Dev.to · 4 min read

PHP .user.ini can make auto_prepend_file a persistence path

PHP .user.ini can make auto_prepend_file a persistence path

PHP .user.ini can make auto_prepend_file a persistence path PHP's per-directory .user.ini files are configuration, but they can influence which code runs before a requested script. The auto_prepend_file directive names a file that PHP parses before the main file, as if it had been loaded with require. If an application permits an attacker to create or modify a .user.ini file in the document tree, a temporary upload or template-write flaw can become a persistent execution path. The manual says .user.ini processing is available for the CGI/FastCGI SAPI. PHP scans from the requested script's directory upward to the document root, and only settings in the allowed modes are recognized. auto_prepend_file is a per-directory setting. The file is resolved with include_path, which adds another configuration value to the review. How the path is formed An uploaded file is usually not executed directly. The problem begins when a user can place content in a directory that PHP scans for .user.ini, or when a deployment process writes generated files beside application code. The next request in that directory can inherit settings that the application did not intend. The cache matters. user_ini.cache_ttl controls how often the per-directory configuration is reread. A response to an incident may remove a malicious file while a running FastCGI worker retains the previous setting for some period. Treat the cache as part of containment, not as a reason to assume the file is harmless. The risk is not limited to a file named shell.php. A prepended file can contain initialization logic, logging hooks, or code that changes the application's runtime. Reviewers need to look at who can write any path that may be treated as configuration and at what code that configuration can include. Where to search Inventory all document roots and every writable directory below them. Include uploads, cache, generated thumbnails, plugin directories, and deployment release folders that are web-accessible. Search for .user.ini files and for auto_prepend_file or auto_append_file references in deployment templates. Check for symlinks and path normalization differences between the web server and PHP. Inspect the effective PHP-FPM configuration for user_ini.filename, user_ini.cache_ttl, open_basedir, include_path, and allow_url_include. Confirm whether web-server location rules deny requests to dot files and whether the denial covers every virtual host and alias. An application-level 404 is not a filesystem restriction if PHP still scans the directory. Review the deployment user's write permissions. A release process that can replace application code is highly privileged; it should not also accept untrusted filenames or extract archives into the live document root. Separate writable data from executable code, and keep the web process unable to create PHP files where it can also write configuration. Defensive controls If per-directory configuration is not required, set user_ini.filename to an empty value and deploy the decision through the PHP-FPM pool configuration. Where it is required, deny direct access to .user.ini, set a short cache lifetime appropriate to the deployment, and make the file immutable by the web user. Use open_basedir to bound file access, and do not allow remote inclusion unless the application has a documented and reviewed need. Set a trusted include_path and disable URL wrappers for application files. Protect the FastCGI socket and pool configuration from unprivileged users. A user who can change the pool configuration can bypass many application-level controls. Verification In a staging copy, create a harmless .user.ini that points auto_prepend_file at a test file, then request a script in that directory. Confirm that the test file is included and record the cache delay. Remove the file and repeat the request after the cache expires. Try the same path through the public web server, an alias, and any alternate hostname. Review application logs for changes to .user.ini, unexpected include failures, and requests for dot files. Correlate those events with upload and deployment activity. The useful control is a path boundary: untrusted data must not be able to change which code PHP loads before the application starts. References PHP: .user.ini files PHP: Description of core php.ini directives PHP: Where a configuration setting may be set

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

Related stories