Make WordPress Core

Opened 3 weeks ago

#65908 new defect (bug)

WP_DEBUG_LOG=true should fail closed instead of creating a publicly accessible debug log

Reported by: codebridge Owned by:
Priority: normal Milestone: Awaiting Review
Component: Bootstrap/Load Version:
Severity: normal Keywords: needs-patch needs-unit-tests needs-privacy-review
Cc: Focuses: privacy

Description

Summary

When WP_DEBUG_LOG is set to true, WordPress defaults to writing errors to wp-content/debug.log. On installations where the web server or CDN permits static .log files, that predictable file can be retrieved without authentication.

This is an insecure default. WP_DEBUG_DISPLAY=false does not protect the log file because it only suppresses error output in rendered responses.

Sanitized production incident

In August 2026, we confirmed this behavior on a production WordPress installation. The public debug log reached 74,273,044 bytes, approximately 74.3 MB decimal or 70.8 MiB, and was still growing. It contained personally identifiable information and diagnostic data that should never have been publicly retrievable.

An unauthenticated request to the standard /wp-content/debug.log URL returned HTTP 200 through the public website and CDN. No log contents or personal information are included in this ticket.

Emergency mitigation required moving the existing log intact to a private directory above the webroot, changing WP_DEBUG_LOG to that absolute path, adding origin-level denial rules, and deploying an edge rule returning HTTP 403.

Steps to reproduce

  1. Install WordPress behind a web server that serves static .log files.
  2. Configure:
    define( 'WP_DEBUG', true );
    define( 'WP_DEBUG_DISPLAY', false );
    define( 'WP_DEBUG_LOG', true );
    
  3. Trigger a PHP warning or notice.
  4. Request /wp-content/debug.log without authentication.

Actual result

WordPress creates a predictable log inside the public content directory. Depending on server configuration, the file is returned over HTTP without authentication.

Expected result

Enabling the boolean WP_DEBUG_LOG=true default must not create a debug log that is publicly retrievable. If Core cannot establish a protected destination, it should fail closed instead of silently writing sensitive diagnostics to a known public path, and provide a critical Site Health notice with remediation guidance.

Proposed security invariant

The default debug-log destination must not be publicly retrievable without authentication.

Possible implementation approaches may include:

  • Prefer a writable location outside the detected public webroot.
  • Use a dedicated protected log directory and generate supported Apache/LiteSpeed and IIS denial rules.
  • Require an explicitly configured absolute path when Core cannot confirm a safe default, including Nginx environments.
  • Add a critical Site Health result when the effective path is inside a potentially public directory or protection cannot be confirmed.
  • Preserve explicitly configured custom log paths.
  • Treat filename randomization only as defense in depth, not as access control.

Related but distinct tickets

#60611 proposes relocating and randomizing the debug-log filename. This ticket instead defines a fail-closed access-control requirement; an unpredictable URL alone does not prevent access.

#64071 concerns a Site Health false positive when an explicitly configured log is already outside the public content directory. This ticket concerns the unsafe boolean default and automatic prevention of public exposure.

Attachments (1)

65908.patch (3.1 KB ) - added by sachinrajcp123 3 weeks ago.

Download all attachments as: .zip

Change History (1)

Note: See TracTickets for help on using tickets.