Is Your WordPress Debug Log Exposed Right Now?.
WP_DEBUG_LOG writes to a file inside the web root. We requested it as an anonymous visitor and got 200, with server paths and plugin names.
Short answer: if WP_DEBUG_LOG is set to true, WordPress writes errors to wp-content/debug.log, which sits inside the web root and is served like any other file. A wordpress debug log exposed this way needs no exploit to read. You request it, and the server hands it over.
Ten seconds to check:
curl -sI https://example.com/wp-content/debug.log
403 or 404 is fine. 200 is not.
What a WordPress debug log exposed to the internet gives away
I turned debugging on for a site, generated ordinary errors, and requested the file as an anonymous visitor.

install, the names of a theme and a plugin, and a file and line number where the code is already known to misbehave.*
No authentication. No clever request. The file is inside the web root, and the web server has no reason to refuse it.

decided by whatever code happened to fail, which means the worst-behaved plugin on the site decides what ends up public.*
That last point is the one I would push back on if someone told me their debug log was harmless. You do not control what goes in it. An integration that catches an exception and logs the whole request will write an API key into a world-readable file, and nothing warns you.
Why it is on in the first place
Nobody enables debug logging on production out of carelessness. It gets enabled during an incident, when somebody needed to see what was failing, and then the incident ends.
The log is the only artefact of that afternoon nobody thinks to clean up.
It is also worth checking after any performance work, because chasing a slow server response is one of the most common reasons somebody switches debugging on in the first place.
On inherited sites I find it more often than any other single misconfiguration, and it is almost always dated. A file that started in March and has been quietly growing since, on a site that has changed hands twice.
Fixing it

WP_DEBUG_LOG accepts a path, not just true. That single change moves the filesomewhere the web server cannot serve, and it is the fix that survives somebody turning debugging back on next month.*
The detail worth knowing: logging and displaying are separate decisions. WP_DEBUG_DISPLAY controls whether errors are printed into the page for visitors to read. On production it should be false regardless of what the log setting is doing.
And if the file was public for a while, treat whatever it contained as disclosed. Rotate any key an integration might have logged. Changing file permissions today says nothing about who read it in March.
Check the whole portfolio, not one site
The check is a single request, so run it across everything at once:
for d in clientone.com clienttwo.com clientthree.com; do
printf '%-28s ' "$d"
curl -s -o /dev/null -w '%{http_code} %{size_download} bytes\n' \
"https://$d/wp-content/debug.log"
done
Watch the size column as well as the status. Some hosts return a styled 200 error page for missing files, so a 200 with a few hundred bytes of HTML is not the same as a 200 with a log file behind it.
While you are there, the same loop is worth pointing at error_log, and at the wp-config backup files that leak the same way. Both are created by the same habit: somebody needed a file for an afternoon.
Protuno’s free audit checks for an exposed debug log from the domain alone, alongside directory listing and the other files that should never answer. Straight with you as on every post: Rook, the Security agent that would keep re-checking after each incident, is built and named but not live yet.
Run the loop above now. It takes longer to read this paragraph than to check twenty sites, and in my experience roughly one in twenty comes back with a log file. It is the same quiet class of problem as a scheduled job that stopped months ago.
Comments