Back to Articles

PCC: The Two-Day Self-Destructing PHP Security Audit

[ View on GitHub ]

PCC: The Two-Day Self-Destructing PHP Security Audit

Hook

Most security tools try to stay alive forever. PCC deliberately kills itself after 48 hours. That's not paranoia—it's genius.

Context

PHP configuration is notoriously treacherous. A single misconfigured directive in php.ini can expose your entire application: allow_url_fopen opens the door to remote file inclusion attacks, display_errors leaks stack traces to attackers, and register_globals (mercifully deprecated) was responsible for countless breaches. Yet auditing these settings is tedious—PHP has hundreds of configuration directives spread across core, extensions, and SAPI-specific settings.

Traditional approaches to configuration auditing fall into two camps: heavyweight security scanners that require agents, databases, and ongoing maintenance, or manual checklists that grow stale the moment PHP releases a new version. SektionEins GmbH, a German security firm that has conducted PHP security audits since the early 2000s, built PCC to solve a specific problem: their consultants needed a drop-in tool that could assess a PHP installation's security posture in minutes, not hours, without leaving behind a permanent attack surface. The result is a single PHP file that runs its audit and then deliberately makes itself unusable.

Technical Insight

CLI

Web

No

No

Yes

Yes

Match

Mismatch

Yes

No

CLI

Web

PCC Script Execution

Execution Mode?

Skip Safety Checks

Safety Validation

IP Whitelisted?

Modified < 48hrs?

Refuse Execution

Load Check Definitions

Security Checks Array

Iterate Each Check

ini_get directive

Current vs Expected?

Mark as Pass

Report Issue with Risk Level

More Checks?

Generate Security Report

Output Mode?

Print to stdout

Render HTML Report

System architecture — auto-generated

PCC's architecture is refreshingly straightforward: it's 800 lines of procedural PHP with zero external dependencies, no classes, and no frameworks. This isn't laziness—it's a security decision. When you're auditing a potentially hostile environment, introducing complex dependencies creates new attack vectors. The entire tool can be code-reviewed in under an hour.

The core mechanism is deceptively simple. PCC maintains an array of security checks, each defining a configuration directive, the expected value, and a risk assessment. Here's how a typical check works:

$checks = array(
    array(
        'name' => 'expose_php',
        'expected' => 'Off',
        'current' => ini_get('expose_php'),
        'risk' => 'MEDIUM',
        'description' => 'Removes PHP signature from HTTP headers'
    ),
    array(
        'name' => 'allow_url_fopen',
        'expected' => 'Off',
        'current' => ini_get('allow_url_fopen'),
        'risk' => 'HIGH',
        'description' => 'Prevents remote file inclusion vulnerabilities'
    )
);

foreach ($checks as $check) {
    if ($check['current'] !== $check['expected']) {
        report_issue($check['name'], $check['risk'], $check['description']);
    }
}

What makes PCC clever is its built-in safeguards against accidental public exposure. When running in web mode, it checks its own modification time using stat() and refuses to execute if the file is older than 48 hours. This prevents the classic mistake: a developer uploads PCC to audit a production server, forgets to remove it, and leaves a publicly accessible security report online. The self-destruct mechanism is implemented at the very top of the file:

$file_age = time() - filemtime(__FILE__);
if ($file_age > 172800) { // 48 hours in seconds
    die("This security checker has expired. Re-upload a fresh copy.");
}

Additionally, PCC includes IP-based access control that defaults to localhost-only in web mode. You can override this by modifying the ALLOWED_IPS array, but the default behavior prevents drive-by security information disclosure. This is security tooling that assumes you'll make operational mistakes and protects you anyway.

The multi-format output system is another thoughtful touch. PCC detects whether it's running via CLI or web and adjusts formatting accordingly, but it also supports explicit format selection via query parameters. This means you can integrate PCC into CI/CD pipelines using the JSON output:

curl http://localhost/pcc.php?format=json | jq '.failed_checks[] | select(.risk=="HIGH")'

This outputs only high-risk configuration failures in a machine-parseable format, making it trivial to fail builds when critical security settings are misconfigured. The tool understands its role in automation workflows without requiring complex plugins or adapters.

The check catalog itself reflects real-world PHP security knowledge. Beyond obvious settings like display_errors and expose_php, PCC audits subtle configurations that even experienced developers miss: session.cookie_httponly to prevent XSS-based session theft, session.use_strict_mode to prevent session fixation attacks, and disable_functions to verify that dangerous functions like exec() and system() are actually disabled. Each check includes context about why the setting matters, turning PCC into both an audit tool and an educational resource.

Gotcha

PCC's laser focus on configuration is both its strength and its limitation. It will tell you that allow_url_fopen is enabled, but it won't detect whether your application actually uses remote file operations safely. A perfectly configured PHP installation can still run catastrophically insecure code—PCC only validates the foundation, not the building.

The self-destruct mechanism, while brilliant for preventing accidental exposure, makes PCC unsuitable for long-running monitoring scenarios. If you need continuous configuration drift detection, you'll need to either automate re-uploading fresh copies or choose a different tool. The 48-hour timeout is hardcoded, so extending it requires modifying the source. Similarly, the check catalog is frozen at the moment you download PCC. New PHP versions introduce new security-relevant directives, and PCC won't automatically update its checks. You're responsible for periodically grabbing the latest version from GitHub. The single-file architecture means updates are all-or-nothing—you can't patch individual checks or add custom rules without forking the entire file.

Verdict

Use if: You're performing ad-hoc security audits of PHP installations, hardening new servers, or validating configuration in deployment pipelines. PCC excels at giving you a fast, authoritative answer to "is this PHP install configured securely?" without requiring agent installation, database setup, or ongoing maintenance. It's perfect for consultants, DevOps engineers doing initial server provisioning, or security teams conducting rapid assessments across multiple environments. The JSON output makes it straightforward to integrate into existing automation. Skip if: You need continuous configuration monitoring, runtime security analysis, or code-level vulnerability scanning. PCC is a point-in-time configuration validator, not a persistent security monitor. If you're looking for dependency vulnerability scanning, static code analysis, or runtime application security, you need complementary tools like PHPStan, Snyk, or OWASP Dependency-Check. Also skip it if your security policy prohibits uploading executable scripts to production servers—even with the 48-hour timeout, some compliance frameworks won't allow this approach.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/sektioneins-pcc.svg)](https://starlog.is/api/badge-click/cybersecurity/sektioneins-pcc)