feat: tier 5 — harden twenty-four low-severity gaps#120
Merged
Conversation
Rebased onto merged Tier 1-4: task 020 scoped to empty whereIn -> '1 = 0' (no whereNotIn() method exists); task 023 must preserve Tier 1's JobEnvelope verifyAndUnwrap (only insert resetAttempts before push); task 008 dropped the path() rawurldecode (Tier 3 RouteMatcher already decodes per-param — would double-decode), scoped to the Content-Type/Length header CGI-key fallback; task 004 OpenSslEncryptor stays a plain class (extensibility trap). Corrected stale 'tier3 empty' note and drifted query-builder line numbers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Audit remediation Tier 5 — all 24 tasks, TDD, full-suite green (6677 passing). Built on merged Tier 1-4. No public-contract breakage. - Webhook inbound replay protection: X-Webhook-Timestamp freshness window (webhook.timestamp_tolerance, default 300s) folded into the HMAC. - Session-file: 0600 files / 0700 dir; loud SessionWriteException on short writes. - SSE: reject CR/LF in event/id; subscription heartbeat + idle timeout. - OpenSSL: enforce AEAD cipher at construction; is_string payload checks. - Log: opt-out CR/LF escaping in the line formatter (log.escape_newlines, default on). - Core: container CircularDependencyException; manifest keeps php*-vendor packages. - Routing: Request::header() reads the CGI CONTENT_TYPE/CONTENT_LENGTH keys. - testing: FakeSession::has() null parity with production Session. - Layout: deterministic ambiguous-sort-order detection (out of the comparator). - cache-file: tmp cleanup on rename failure, clear() globs tmp, mkdir race tolerant. - codeindexer: allowed_classes + corrupt-cache rebuild (never silently empty). - docs-fts: malformed FTS5 MATCH → DocsException (no raw PDOException leak). - mcp: reject stacked statements in the read-only DB tool. - lsp: distinguish EOF from a malformed frame (-32700, keep serving). - Translator: single-pass strtr placeholder replacement. - SQL generators: mysql/pgsql type-map parity (uuid/enum/bool/tinyint/blob/decimal). - MySQL connection: explicit PDO param type binding (bool/null/int parity w/ pgsql). - Query builders: empty whereIn([]) → valid `1 = 0` on both. - media-gd: preserve source format + alpha; loud error on encode failure. - admin-api: wildcard-aware section visibility; show() filter parity with index(). - queue: RetryCommand resets attempts (Job/JobInterface::resetAttempts) so retries actually run — preserving Tier 1's JobEnvelope verify/wrap seam. - debugbar: lazy all() (summaries, no full decode); default mask covers password/secret/key/token/dsn at top level and nested. Devil's-advocate-reviewed (rebased the stale cross-tier notes onto merged Tier 1-4), standards-enforced (no src readonly-class promotions), docs updated, phpcs + php-cs-fixer clean. Includes a test-fixture global-function rename and EncryptionException rebased onto MarkoException (public contract preserved). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tier 5 — Low-Severity Hardening
Fifth of six audit-remediation PRs. Hardens twenty-four low-severity gaps across ~20 packages without changing public contracts. 24 TDD tasks, full suite green (6677 passing, 0 failures). Built on Tier 1-4.
Fixes
webhook inbound replay protection (timestamp freshness window) · session-file 0600/0700 perms + checked writes · SSE CRLF rejection + subscription heartbeat · OpenSSL AEAD-cipher enforcement · log line-injection escaping · container circular-dependency detection · request CGI Content-Type header · manifest
php*-vendor filter · FakeSession null parity · deterministic layout ambiguity · cache-file tmp cleanup/mkdir race · codeindexer unserialize allowlist + corrupt-cache rebuild · docs-fts malformed-MATCH → DocsException · mcp stacked-statement guard · lsp malformed-frame resilience · translator single-pass placeholders · mysql/pgsql SQL type-map parity · MySQL explicit PDO param binding · emptywhereIn([])→1 = 0· GD format/alpha preservation · admin-api wildcard section visibility · queue RetryCommand attempt reset · debugbar lazyall()+ default-mask completeness.New config keys
webhook.timestamp_tolerance(default 300s).log.escape_newlines(defaulttrue).debugbardefaultmaskedlist (password/secret/key/token/dsn, top-level + nested).Public-surface additions (non-breaking)
JobInterface::resetAttempts()/Job::resetAttempts().SessionWriteException,CircularDependencyException,SseException::invalidField(),EncryptionException::nonAeadCipher()/invalidCipher().Notes for reviewers
EncryptionExceptionwas re-based ontoMarkoExceptionby the standards pass (public constructor/getters/factories preserved byte-for-byte; verified against its test).docs/src/content/docs/packages/(prior tiers usedpackages/docs-markdown/docs/packages/) — you may want to reconcile the two doc trees.whereInsince nowhereNotIn()exists; task 023 preserves the JobEnvelope seam; task 008 dropped a double-decode). phpcs + php-cs-fixer clean.🤖 Generated with Claude Code