From ffb7da644cba0e5bbdbeb771d9da712c3a596bcf Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Dec 2025 19:49:59 +0000 Subject: [PATCH] fix(security): harden CI/CD workflows and add roadmap Security improvements: - Pin editorconfig-checker action to SHA (v2.1.0) - Add Haskell (.hs) file extensions to security policy checks - Update setup-haskell to haskell-actions/setup v2.9.0 (archived action) - Upgrade GHC from 8.10.3 to 9.6, Cabal from 3.2 to 3.10 - Expand base version constraint for GHC 9.4-9.10 compatibility Project updates: - Add comprehensive ROADMAP.scm with 6-phase development plan - Update STATE.scm to 30% completion with component tracking - Add CI/CD security and SCM files as completed components --- .github/workflows/haskell.yml | 6 +- .github/workflows/quality.yml | 4 +- .github/workflows/security-policy.yml | 6 +- ROADMAP.scm | 261 ++++++++++++++++++++++++++ STATE.scm | 28 ++- sanctify-php.cabal | 6 +- 6 files changed, 294 insertions(+), 17 deletions(-) create mode 100644 ROADMAP.scm diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 620ff1d..2413f34 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -17,10 +17,10 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: actions/setup-haskell@28c8ff1d6cbeaed15ce310b1952dc19352a0a07d # v1.1.5 + - uses: haskell-actions/setup@0a703b53e0ecfe04a312712af19699c3d8a17c7a # v2.9.0 with: - ghc-version: '8.10.3' - cabal-version: '3.2' + ghc-version: '9.6' + cabal-version: '3.10' - name: Cache uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 7456828..0cd6576 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -28,14 +28,14 @@ jobs: - name: Check TODO/FIXME run: | echo "=== TODOs ===" - grep -rn "TODO\|FIXME\|HACK\|XXX" --include="*.rs" --include="*.res" --include="*.py" --include="*.ex" . | head -20 || echo "None found" + grep -rn "TODO\|FIXME\|HACK\|XXX" --include="*.rs" --include="*.res" --include="*.py" --include="*.ex" --include="*.hs" . | head -20 || echo "None found" - name: Check for large files run: | find . -type f -size +1M -not -path "./.git/*" | head -10 || echo "No large files" - name: EditorConfig check - uses: editorconfig-checker/action-editorconfig-checker@main + uses: editorconfig-checker/action-editorconfig-checker@4b6cd6190d435e7e084fb35e36a096e98506f7b9 # v2.1.0 continue-on-error: true docs: diff --git a/.github/workflows/security-policy.yml b/.github/workflows/security-policy.yml index ca53cf8..509df18 100644 --- a/.github/workflows/security-policy.yml +++ b/.github/workflows/security-policy.yml @@ -17,21 +17,21 @@ jobs: FAILED=false # Block MD5/SHA1 for security (allow for checksums/caching) - WEAK_CRYPTO=$(grep -rE 'md5\(|sha1\(' --include="*.py" --include="*.rb" --include="*.js" --include="*.ts" --include="*.go" --include="*.rs" . 2>/dev/null | grep -v 'checksum\|cache\|test\|spec' | head -5 || true) + WEAK_CRYPTO=$(grep -rE 'md5\(|sha1\(|MD5\.|SHA1\.' --include="*.py" --include="*.rb" --include="*.js" --include="*.ts" --include="*.go" --include="*.rs" --include="*.hs" . 2>/dev/null | grep -v 'checksum\|cache\|test\|spec' | head -5 || true) if [ -n "$WEAK_CRYPTO" ]; then echo "⚠️ Weak crypto (MD5/SHA1) detected. Use SHA256+ for security:" echo "$WEAK_CRYPTO" fi # Block HTTP URLs (except localhost) - HTTP_URLS=$(grep -rE 'http://[^l][^o][^c]' --include="*.py" --include="*.js" --include="*.ts" --include="*.go" --include="*.rs" --include="*.yaml" --include="*.yml" . 2>/dev/null | grep -v 'localhost\|127.0.0.1\|example\|test\|spec' | head -5 || true) + HTTP_URLS=$(grep -rE 'http://[^l][^o][^c]' --include="*.py" --include="*.js" --include="*.ts" --include="*.go" --include="*.rs" --include="*.hs" --include="*.yaml" --include="*.yml" . 2>/dev/null | grep -v 'localhost\|127.0.0.1\|example\|test\|spec' | head -5 || true) if [ -n "$HTTP_URLS" ]; then echo "⚠️ HTTP URLs found. Use HTTPS:" echo "$HTTP_URLS" fi # Block hardcoded secrets patterns - SECRETS=$(grep -rEi '(api_key|apikey|secret_key|password)\s*[=:]\s*["\x27][A-Za-z0-9+/=]{20,}' --include="*.py" --include="*.js" --include="*.ts" --include="*.go" --include="*.rs" --include="*.env" . 2>/dev/null | grep -v 'example\|sample\|test\|mock\|placeholder' | head -3 || true) + SECRETS=$(grep -rEi '(api_key|apikey|secret_key|password)\s*[=:]\s*["\x27][A-Za-z0-9+/=]{20,}' --include="*.py" --include="*.js" --include="*.ts" --include="*.go" --include="*.rs" --include="*.hs" --include="*.env" . 2>/dev/null | grep -v 'example\|sample\|test\|mock\|placeholder' | head -3 || true) if [ -n "$SECRETS" ]; then echo "❌ Potential hardcoded secrets detected!" FAILED=true diff --git a/ROADMAP.scm b/ROADMAP.scm new file mode 100644 index 0000000..cb9925b --- /dev/null +++ b/ROADMAP.scm @@ -0,0 +1,261 @@ +;;; ROADMAP.scm — sanctify-php Development Roadmap +;; SPDX-License-Identifier: AGPL-3.0-or-later +;; SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell +;; +;; This roadmap outlines the development phases for sanctify-php. +;; Updated: 2025-12-17 + +(define-module (sanctify-php roadmap) + #:export (roadmap current-milestone next-steps)) + +;;; ============================================================================ +;;; PHASE 1: Foundation (v0.1.x) — Current Phase +;;; ============================================================================ + +(define phase-1 + '((name . "Foundation") + (version . "0.1.x") + (status . "in-progress") + (completion . 30) + (milestones + (;; COMPLETED + (milestone "RSR Compliance" + (status . complete) + (items + ("SPDX headers on all files" . done) + ("SHA-pinned GitHub Actions" . done) + ("Security workflows configured" . done) + ("Guix SCM files" . done) + ("Dual licensing (MIT/AGPL)" . done))) + + (milestone "CI/CD Security" + (status . complete) + (items + ("CodeQL analysis" . done) + ("PHP security scanning" . done) + ("Secret detection (TruffleHog)" . done) + ("OpenSSF Scorecard" . done) + ("Haskell extensions in security checks" . done) + ("Upgraded to GHC 9.6" . done))) + + ;; IN PROGRESS + (milestone "PHP Parser" + (status . pending) + (priority . high) + (items + ("Megaparsec-based lexer" . pending) + ("PHP 7.4+ syntax support" . pending) + ("PHP 8.x syntax support" . pending) + ("AST representation" . pending) + ("Source location tracking" . pending) + ("Error recovery" . pending))) + + (milestone "Test Infrastructure" + (status . pending) + (priority . medium) + (items + ("HSpec test suite setup" . pending) + ("Parser unit tests" . pending) + ("Golden tests with PHP fixtures" . pending) + ("Property-based tests (QuickCheck)" . pending) + ("CI test coverage reporting" . pending))))))) + +;;; ============================================================================ +;;; PHASE 2: Core Analysis (v0.2.x) +;;; ============================================================================ + +(define phase-2 + '((name . "Core Analysis") + (version . "0.2.x") + (status . "planned") + (milestones + ((milestone "Security Analysis Engine" + (priority . critical) + (items + ("SQL injection detection" . planned) + ("XSS vulnerability detection" . planned) + ("CSRF pattern identification" . planned) + ("Command injection detection" . planned) + ("Path traversal detection" . planned) + ("Unsafe deserialization detection" . planned))) + + (milestone "Taint Tracking" + (priority . high) + (items + ("Source identification ($_GET, $_POST, etc.)" . planned) + ("Sink identification (echo, query, etc.)" . planned) + ("Data flow analysis" . planned) + ("Sanitizer recognition" . planned) + ("Cross-function taint propagation" . planned))) + + (milestone "Type Inference" + (priority . medium) + (items + ("Return type inference" . planned) + ("Parameter type inference" . planned) + ("Property type inference" . planned) + ("PHPDoc annotation parsing" . planned) + ("Type hint suggestions" . planned))))))) + +;;; ============================================================================ +;;; PHASE 3: Transformations (v0.3.x) +;;; ============================================================================ + +(define phase-3 + '((name . "Transformations") + (version . "0.3.x") + (status . "planned") + (milestones + ((milestone "Strict Types Transformation" + (priority . high) + (risk . "zero") + (items + ("Add declare(strict_types=1)" . planned) + ("Preserve existing declarations" . planned) + ("Handle multiple files" . planned))) + + (milestone "Type Hint Addition" + (priority . high) + (risk . "low-review-required") + (items + ("Add inferred parameter types" . planned) + ("Add inferred return types" . planned) + ("Generate PHPStan annotations" . planned) + ("Preserve formatting" . planned))) + + (milestone "Sanitization Transforms" + (priority . critical) + (risk . "medium-review-required") + (items + ("Auto-escape echo statements" . planned) + ("wpdb::query to prepare conversion" . planned) + ("Superglobal sanitization" . planned) + ("rand() to random_int() upgrade" . planned) + ("Nonce verification insertion" . planned))) + + (milestone "Code Emission" + (priority . high) + (items + ("Pretty-print transformed AST" . planned) + ("Preserve comments" . planned) + ("Maintain original formatting where possible" . planned) + ("Diff-friendly output" . planned))))))) + +;;; ============================================================================ +;;; PHASE 4: WordPress Support (v0.4.x) +;;; ============================================================================ + +(define phase-4 + '((name . "WordPress Support") + (version . "0.4.x") + (status . "planned") + (milestones + ((milestone "WordPress Constraints" + (priority . high) + (items + ("ABSPATH check enforcement" . planned) + ("Capability escalation detection" . planned) + ("Direct database access warnings" . planned) + ("Proper escaping function usage" . planned) + ("Text domain consistency" . planned))) + + (milestone "WordPress Hooks Analysis" + (priority . medium) + (items + ("Action hook analysis" . planned) + ("Filter hook analysis" . planned) + ("Priority conflict detection" . planned) + ("Deprecated hook warnings" . planned))) + + (milestone "WordPress Security Patterns" + (priority . critical) + (items + ("Admin-ajax.php security" . planned) + ("REST API endpoint security" . planned) + ("File upload handling" . planned) + ("Options API security" . planned) + ("User meta security" . planned))))))) + +;;; ============================================================================ +;;; PHASE 5: Reporting & Integration (v0.5.x) +;;; ============================================================================ + +(define phase-5 + '((name . "Reporting & Integration") + (version . "0.5.x") + (status . "planned") + (milestones + ((milestone "Report Generation" + (priority . high) + (items + ("JSON report format" . planned) + ("SARIF format for IDE integration" . planned) + ("HTML report with navigation" . planned) + ("Markdown summary" . planned) + ("Severity classification" . planned))) + + (milestone "Infrastructure Export" + (priority . medium) + (items + ("php.ini recommendations export" . planned) + ("nginx security rules export" . planned) + ("Guix container overrides export" . planned) + ("Docker security configs" . planned))) + + (milestone "IDE Integration" + (priority . medium) + (items + ("VSCode extension" . planned) + ("Language Server Protocol (LSP)" . planned) + ("Real-time analysis" . planned) + ("Quick-fix suggestions" . planned))))))) + +;;; ============================================================================ +;;; PHASE 6: Production Ready (v1.0.0) +;;; ============================================================================ + +(define phase-6 + '((name . "Production Ready") + (version . "1.0.0") + (status . "planned") + (milestones + ((milestone "Performance Optimization" + (items + ("Parallel file processing" . planned) + ("Incremental analysis" . planned) + ("Memory optimization" . planned) + ("Large codebase support" . planned))) + + (milestone "Documentation" + (items + ("User guide" . planned) + ("API documentation" . planned) + ("Integration examples" . planned) + ("WordPress plugin guidelines" . planned))) + + (milestone "Release" + (items + ("Binary releases (Linux/macOS/Windows)" . planned) + ("Guix package submission" . planned) + ("Homebrew formula" . planned) + ("Docker image" . planned))))))) + +;;; ============================================================================ +;;; Summary & Export +;;; ============================================================================ + +(define roadmap + (list phase-1 phase-2 phase-3 phase-4 phase-5 phase-6)) + +(define current-milestone + '((phase . 1) + (name . "Foundation") + (next-task . "Implement PHP parser with Megaparsec") + (blockers . ()))) + +(define next-steps + '(("Implement PHP lexer" . immediate) + ("Add parser tests" . immediate) + ("Implement AST pretty-printer" . this-week) + ("Add strict_types transformation" . this-week) + ("Implement basic SQL injection detection" . next-sprint))) diff --git a/STATE.scm b/STATE.scm index cdd0d0d..61297a7 100644 --- a/STATE.scm +++ b/STATE.scm @@ -3,20 +3,36 @@ ;; SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell (define metadata - '((version . "0.1.0") (updated . "2025-12-15") (project . "sanctify-php"))) + '((version . "0.1.0") (updated . "2025-12-17") (project . "sanctify-php"))) (define current-position '((phase . "v0.1 - Initial Setup") - (overall-completion . 25) - (components ((rsr-compliance ((status . "complete") (completion . 100))))))) + (overall-completion . 30) + (components + ((rsr-compliance ((status . "complete") (completion . 100))) + (ci-cd-security ((status . "complete") (completion . 100))) + (scm-files ((status . "complete") (completion . 100))) + (parser ((status . "pending") (completion . 0))) + (security-analysis ((status . "pending") (completion . 0))) + (transformations ((status . "pending") (completion . 0))) + (wordpress-support ((status . "pending") (completion . 0))) + (reporting ((status . "pending") (completion . 0))))))) (define blockers-and-issues '((critical ()) (high-priority ()))) (define critical-next-actions - '((immediate (("Verify CI/CD" . high))) (this-week (("Expand tests" . medium))))) + '((immediate + (("Implement PHP parser" . high) + ("Add test fixtures" . medium))) + (this-week + (("Implement strict_types transformation" . high) + ("Implement basic security analysis" . medium))))) (define session-history - '((snapshots ((date . "2025-12-15") (session . "initial") (notes . "SCM files added"))))) + '((snapshots + ((date . "2025-12-15") (session . "initial") (notes . "SCM files added")) + ((date . "2025-12-17") (session . "security-audit") + (notes . "CI/CD security fixes: SHA-pinned actions, added Haskell extensions to security checks, upgraded GHC to 9.6"))))) (define state-summary - '((project . "sanctify-php") (completion . 25) (blockers . 0) (updated . "2025-12-15"))) + '((project . "sanctify-php") (completion . 30) (blockers . 0) (updated . "2025-12-17"))) diff --git a/sanctify-php.cabal b/sanctify-php.cabal index 6d3f373..7193e60 100644 --- a/sanctify-php.cabal +++ b/sanctify-php.cabal @@ -44,7 +44,7 @@ library Sanctify.Parser.Lexer Sanctify.Parser.Token build-depends: - base ^>=4.17, + base >=4.17 && <4.21, text >=2.0, containers >=0.6, mtl >=2.3, @@ -73,7 +73,7 @@ executable sanctify import: warnings main-is: Main.hs build-depends: - base ^>=4.17, + base >=4.17 && <4.21, sanctify-php, text, optparse-applicative, @@ -91,7 +91,7 @@ test-suite sanctify-php-test hs-source-dirs: test main-is: Main.hs build-depends: - base ^>=4.17, + base >=4.17 && <4.21, sanctify-php, hspec >=2.10, hspec-megaparsec >=2.2,