## # Security audit — peptide-news-plugin # # Standalone workflow kept separate from the estate CI caller so it can evolve # independently and run on every PR without being bundled into the reusable pipeline. # Checks for: unescaped SQL, eval(), base64_decode(), file_get_contents with user input. ## name: Security Audit on: pull_request: {} push: branches: [main] permissions: contents: read jobs: security-audit: name: Security Audit runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Check for common PHP security issues run: | echo ":: Checking for direct SQL queries without prepare..." # Exclude uninstall.php (DROP TABLE is standard WP pattern), activator (table DDL), # and logger (TRUNCATE) — these use $wpdb->prefix which is safe internal state. if grep -r "query\s*(\s*['\"].*\$" --include="*.php" --exclude-dir=vendor . 2>/dev/null \ | grep -v "\$wpdb->prepare" \ | grep -v "uninstall\.php" \ | grep -v "class-peptide-news-activator\.php" \ | grep -v "class-peptide-news-logger\.php" \ | grep -v "DROP TABLE" \ | grep -v "TRUNCATE" \ && [ ${PIPESTATUS[0]} -eq 0 ]; then echo "WARNING: Found potential unescaped SQL queries. Use wpdb->prepare() for all dynamic SQL." exit 1 fi echo ":: Checking for eval() usage..." if grep -r "eval\s*(" --include="*.php" --exclude-dir=vendor . 2>/dev/null; then echo "ERROR: eval() found. This is a critical security risk." exit 1 fi echo ":: Checking for base64_decode without validation..." if grep -r "base64_decode\s*(" --include="*.php" --exclude-dir=vendor . 2>/dev/null; then echo "WARNING: Found base64_decode(). Ensure the input is properly validated." fi echo ":: Checking for file_get_contents with user input..." if grep -r "file_get_contents\s*(\s*\$" --include="*.php" --exclude-dir=vendor . 2>/dev/null; then echo "WARNING: Found file_get_contents with variable. Ensure input is validated and restricted." fi echo "All security checks passed."