CWE-433 happens when a product stores raw content or supporting code under the web document root with an extension that the server is not set up to handle. The server then returns the file as is, instead of running it.
It affects web servers hosting PHP, Perl and similar code, especially older layouts that keep include files next to public pages.
How it happens
MITRE gives the pattern: code saved in a file with an extension such as .inc or .pl, and the web server has no handler for it. The server sends the file contents straight to whoever asks, without the processing the developer expected. If the file holds database credentials, the requester now has them.
A common version is a config include:
<?php
// /var/www/html/includes/db.inc (served as plain text!)
$db_host = "db.internal";
$db_user = "app";
$db_pass = "s3cr3t-password";
Request /includes/db.inc and the browser shows the source. MITRE lists several real cases of .inc files stored under the document root and returned unparsed (CVE-2002-1886, CVE-2002-2065, CVE-2005-2029) and a direct request to a .pl file that left it unparsed (CVE-2001-0330).
What an attacker gains
The record lists confidentiality: reading application data. When the file contains secrets, that can lead to compromise of the application or connected components such as the database.
How to find it
The record lists no detection methods. These checks work:
- List files under the web root and look for extensions the server does not map to a handler:
.inc,.bak,.old,.conf,.sql. - Request a few of them through the running server and see what comes back.
- Scan the web root and repository for secrets. The secrets scanning demo below shows what that looks like.
- Run a dynamic scan against staging to probe common file names.
How to fix it
- Keep code and config outside the document root. Only files meant for the public belong there.
- Use handled extensions for server side code, so the server executes it.
- Deny by extension. Configure the server to refuse requests for include, backup and config types.
- Move secrets out of files into environment variables or a secret store, and rotate any that were exposed.
- Clean up deploys. Do not leave editor backups or old copies in production.
# Block raw include and backup files at the server
location ~* \.(inc|bak|old|sql|conf)$ {
deny all;
}
Try it yourself
Exposed credentials are exactly what a secrets scanner looks for.
Click through it at your own pace, or open it full screen.
Quick check
Why is moving the file outside the web root better than denying its extension?
Then no server rule can fail to cover it. The file is simply not reachable by URL.
If a credential was served once, is changing the file enough?
No. Treat it as exposed and rotate it.