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:
'php_configuration' => [
// Path to your php.ini file (auto-detected if not set)
'ini_path' => null,
// Custom secure settings to validate
'secure_settings' => [
'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)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)
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