PCC 0.3.0 — PHP Secure Configuration Checker - Big 2026 Update

Release 0.3.0 of the PHP Secure Configuration Checker (pcc) is out: a 2026 update for PHP 8.x with new security checks, bug fixes, and cleanup.

Bug fixes

  • str_replace arguments reversed — The "GET overrides POST" detection was broken (subject was an empty string). Fixed.

  • Hardcoded path separator — Replaced : with PATH_SEPARATOR for correct behavior on Windows.

  • Redundant ini_atol() call — Removed duplicate conversion.

  • constant() without defined() guard — Prevents ValueError on PHP 8+ in two places (including ANSI colors).

  • curl.cainfo Windows path check — Restructured to correctly detect absolute paths on both Unix and Windows.

Version gate and lifecycle

  • Minimum PHP version is now 8.1 (version gate and documentation updated).

  • test_old_php_version() reflects the 2026 lifecycle: PHP 8.1 = EOL, 8.2 = security-only, 8.3+ = supported.

Dead code removal

Removed handling and helptext for long-gone directives: magic_quotes_gpc, magic_quotes_runtime, magic_quotes_sybase, register_globals, always_populate_raw_post_data, asp_tags. Dropped assert.quiet_eval and track_errors from the known-safe list. Simplified iconv.*_encoding logic and the update/Snuffleupagus checks.

New security checks

From the 2026 PHP 8.x update:

  • session.sid_length — Flags short session IDs.

  • session.sid_bits_per_character — Flags low entropy density.

  • serialize_precision — Flags non-default values that can cause float serialization issues.

Additional checks added in the follow-up commit (12 directives):

  • session.serialize_handler — MEDIUM if php (legacy, pipe-injection risk).

  • session.gc_maxlifetime — COMMENT if > 86400 (24 h sessions).

  • zend.exception_ignore_args — MAYBE if off (stack traces may leak function arguments).

  • zend.exception_string_param_max_len — COMMENT if > 0 (stack traces may leak string parameters).

  • sqlite3.defensive — MEDIUM if off (writable schema enabled).

  • sqlite3.extension_dir — MEDIUM if set and writable.

  • unserialize_max_depth — MEDIUM if 0 (depth check disabled, deserialization bombs).

  • max_multipart_body_parts — MEDIUM if -1 (unlimited, DoS risk per CVE-2023-0662).

  • openssl.cafile / openssl.capath — MEDIUM if set but file/dir does not exist (MITM risk).

  • pcre.backtrack_limit / pcre.recursion_limit — COMMENT if 0 (unlimited; ReDoS / stack exhaustion risk).

  • error_log_mode — LOW if world-writable, COMMENT if world-readable.

  • register_argc_argv — COMMENT if on in web mode.

Roughly 50 directives were added to the known-safe list (e.g. fiber.stack_size, session.upload_progress.*, zend.enable_gc, zlib.output_compression, and many others), so they are no longer reported as unknown.

Verification

Syntax check, text output, and zero-unknown-directives were confirmed on PHP 8.1.34, 8.2.30, 8.3.30, 8.4.18, and 8.5.3.

Modernization

  • Replaced strstr()/strpos() !== FALSE with str_contains().

  • Added explicit parentheses for operator precedence where useful and // fall through comments in the ini_atol() switch.

Download

Source and releases: https://github.com/sektioneins/pcc

Issues and ideas: https://github.com/sektioneins/pcc/issues

bf