PHP Configuration Analyzer
| Analyzer ID | Category | Severity | Time To Fix |
|---|---|---|---|
php-ini | 🛡️ Security | High | 15 minutes |
What This Checks
Validates that PHP configuration (php.ini) follows security best practices for production and staging environments. This analyzer automatically runs only in production and staging environments, as development environments may have different PHP ini settings for debugging purposes (which is acceptable).
Checks include:
- Dangerous settings disabled:
allow_url_fopen,allow_url_include,expose_php - Error handling:
display_errorsdisabled,log_errorsenabled
Why It Matters
- Information Disclosure:
display_errorsandexpose_phpleak sensitive information about your application - Remote File Inclusion (RFI):
allow_url_includeenables attackers to include malicious remote files - Local File Inclusion (LFI):
allow_url_fopenwith weak code can expose sensitive files
Misconfigured PHP settings are consistently in OWASP Top 10 (A05:2021 – Security Misconfiguration). Common attack vectors include:
- Error disclosure: Stack traces reveal file paths, database credentials, API keys
- RFI attacks:
include($_GET['page'])withallow_url_include=On→ Remote shell - Version fingerprinting:
expose_php=On→X-Powered-By: PHP/8.1.0helps attackers target known vulnerabilities
How to Fix
Quick Fix (5 minutes)
Find your php.ini file location:
php --ini
# Configuration File (php.ini) Path: /etc/php/8.1/fpm/php.iniEdit the php.ini file:
# Disable dangerous URL functions
allow_url_fopen = Off
allow_url_include = Off
# Hide PHP version from HTTP headers
expose_php = Off
# Disable error display in production
display_errors = Off
display_startup_errors = Off
# Enable error logging instead
log_errors = On
error_log = /var/log/php/error.logRestart PHP to apply changes:
# For PHP-FPM
sudo systemctl restart php8.1-fpm
# For Apache with mod_php
sudo systemctl restart apache2
# For nginx with PHP-FPM
sudo systemctl restart nginx
sudo systemctl restart php8.1-fpmProper Fix (15 minutes)
Implement comprehensive PHP security hardening:
1. Production-Grade php.ini Configuration
Create a security-focused php.ini configuration:
;;;;;;;;;;;;;;;;;;;
; Security Settings
;;;;;;;;;;;;;;;;;;;
; Disable dangerous URL functions
allow_url_fopen = Off
allow_url_include = Off
; Hide PHP version from headers
expose_php = Off
; Disable error display (security risk)
display_errors = Off
display_startup_errors = Off
; Enable error logging instead
log_errors = On
error_log = /var/log/php/error.log
; File upload restrictions
file_uploads = On
upload_max_filesize = 2M
max_file_uploads = 5
; Session security
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
session.cookie_samesite = Lax
; Disable deprecated functions
enable_dl = Off2. Environment-Specific Configuration
Use different php.ini files per environment:
# Production server
/etc/php/8.1/fpm/php.ini → Strict security settings (errors off)
# Staging server
/etc/php/8.1/fpm/php.ini → Moderate settings (log errors)
# Development server
/etc/php/8.1/cli/php.ini → Relaxed settings (display errors on)3. Validate Configuration After Changes
Create a validation script:
<?php
// check-php-config.php - Run once then DELETE THIS FILE!
$securityChecks = [
'allow_url_fopen' => ['expected' => 'Off', 'severity' => 'HIGH'],
'allow_url_include' => ['expected' => 'Off', 'severity' => 'CRITICAL'],
'expose_php' => ['expected' => 'Off', 'severity' => 'HIGH'],
'display_errors' => ['expected' => 'Off', 'severity' => 'HIGH'],
'log_errors' => ['expected' => 'On', 'severity' => 'MEDIUM'],
];
echo "PHP Security Configuration Check\n";
echo "=================================\n\n";
foreach ($securityChecks as $setting => $config) {
$value = ini_get($setting);
$status = strtolower($value) === strtolower($config['expected']) ? '✅ PASS' : '❌ FAIL';
echo "{$status} {$setting}: {$value} (expected: {$config['expected']}) [{$config['severity']}]\n";
}Run the validation:
php check-php-config.php
rm check-php-config.php # DELETE after validation!4. Configure ShieldCI Custom Settings (Optional)
By default, the analyzer checks standard security settings (disable allow_url_include, expose_php, display_errors, etc.). To customize which settings are validated or adjust thresholds, publish the config:
php artisan vendor:publish --tag=shieldci-configThen in config/shieldci.php:
'analyzers' => [
'security' => [
'enabled' => true,
'php-ini' => [
// Path to your php.ini file (auto-detected if not set)
'ini_path' => null,
// Custom secure settings to validate
'php_configuration' => [
'allow_url_fopen' => false,
'allow_url_include' => false,
'expose_php' => false,
'display_errors' => false,
'display_startup_errors' => false,
'log_errors' => true,
'ignore_repeated_errors' => false,
// Add your organization's requirements
],
],
],
],TIP
The analyzer auto-detects your php.ini location. You only need to configure ini_path if you have a non-standard setup.
5. Monitor PHP Configuration in CI/CD
Add to your deployment pipeline:
# .github/workflows/deploy.yml
deploy:
steps:
- name: Validate PHP Configuration
run: |
# After deployment, run ShieldCI
php artisan shieldci:analyze --analyzer=php-ini-security
# Fail deployment if PHP config is insecure
if [ $? -ne 0 ]; then
echo "❌ Insecure PHP configuration detected!"
exit 1
fi6. Docker/Container Configuration
For containerized applications:
# Dockerfile
FROM php:8.1-fpm
# Copy secure php.ini
COPY docker/php.ini /usr/local/etc/php/php.ini
# Verify configuration during build
RUN php -r "exit(ini_get('allow_url_include') === 'Off' ? 0 : 1);" \
|| (echo "❌ Insecure PHP configuration!" && exit 1)7. Laravel Vapor / Serverless Deployments
On Laravel Vapor (AWS Lambda), the system php.ini is read-only. ShieldCI automatically detects Vapor and adjusts its recommendations accordingly.
To override PHP settings on Vapor, create a php/conf.d/php.ini file in your project root:
mkdir -p php/conf.d; php/conf.d/php.ini
allow_url_fopen = Off
allow_url_include = Off
expose_php = Off
display_errors = Off
display_startup_errors = Off
log_errors = On
ignore_repeated_errors = OffAfter adding or changing this file, redeploy your application for changes to take effect:
vapor deploy {environment}TIP
ShieldCI auto-detects Vapor via vapor.yml, the laravel/vapor-core package, or Lambda environment variables. No configuration is needed — recommendations will automatically point to php/conf.d/php.ini instead of the system php.ini.
ShieldCI Configuration
This analyzer is automatically skipped in CI environments and only runs in production and staging environments.
Why skip in CI and development?
- PHP ini settings are environment-specific and not applicable in CI
- Local/Development/Testing environments may have permissive settings for debugging (e.g.,
display_errors = On), which is acceptable - Production and staging should have strict security settings
Environment Detection: The analyzer checks your Laravel APP_ENV setting and only runs when it maps to production or staging. Custom environment names can be mapped in config/shieldci.php:
// config/shieldci.php
'environment_mapping' => [
'production-us' => 'production',
'production-blue' => 'production',
'staging-preview' => 'staging',
],Examples:
APP_ENV=production→ Runs (no mapping needed)APP_ENV=production-us→ Maps toproduction→ RunsAPP_ENV=local→ Skipped (not production/staging)
Laravel Vapor / Serverless: On Vapor and other serverless platforms, the log_errors and display_startup_errors checks are additionally skipped — the platform manages PHP error output via stderr/CloudWatch and these settings are not user-controllable there. All other checks (allow_url_fopen, allow_url_include, expose_php, display_errors) still run and point to php/conf.d/php.ini for remediation.
Explicit Off vs empty string: A PHP ini setting explicitly set to Off (or 0, no, false) is treated as intentionally disabled — no issue is raised. An empty value is treated as ambiguous and flagged separately, since ini_get() returns an empty string for both a genuine Off and a setting that may not be applied correctly.
References
- PHP Security Configuration
- PHP ini Settings
- OWASP PHP Configuration Cheat Sheet
- CWE-16: Configuration
- CWE-209: Information Exposure Through Error Messages
Related Analyzers
- Debug Mode Analyzer - Validates APP_DEBUG is disabled in production
- Environment File Analyzer - Checks .env file permissions
- Application Key Analyzer - Validates APP_KEY configuration
- SQL Injection Analyzer - Detects SQL injection vulnerabilities