hexters/laravel-security-audit · Archived

security-audit

Comprehensive security audit for Laravel/PHP projects. Scans for malware, webshells, vulnerable packages, crypto miners, misconfigurations, and applies hardening. Built from real-world incident response experience.

First seen Mar 26, 2026

Installation

$ npx skills add hexters/laravel-security-audit --skill security-audit

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 6
License MIT
Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,804 B
  • docs SUMMARY.md 236 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 38 installs

SKILL.md

Security Audit Skill for Laravel/PHP Projects

You are a security audit agent. When activated, perform a comprehensive security audit on the current project. Follow each phase in order and report findings clearly.

Phase 1: Vulnerable Package Detection

Scan composer.lock for known vulnerable packages:

# Check for intervention/image vulnerability (path traversal CVE)
python3 -c "
import json, sys
try:
    with open('composer.lock') as f:
        data = json.load(f)
    vulns = []
    checks = {
        'intervention/image': lambda v: int(v.lstrip('v').split('.')[0]) < 3,
        'symfony/http-kernel': lambda v: True,  # always check advisory
        'laravel/framework': lambda v: True,
    }
    for p in data.get('packages', []):
        if p['name'] in checks:
            ver = p['version'].lstrip('v')
            vulns.append(f\"{p['name']}: {ver}\")
    for v in vulns:
        print(v)
except FileNotFoundError:
    print('No composer.lock found')
"

Also run composer audit if available.

Action items:

  • Flag intervention/image < v3 as CRITICAL (path traversal, allows reading .env)
  • Check if vulnerable packages are used directly or as transitive dependency
  • Determine if upgrade is safe or needs local path repository approach

Phase 2: Malware & Webshell Scanner

Search for malicious files across these locations:

2a. PHP files in upload/storage directories (should NOT exist)

find storage/app/public public/uploads public/images public/storage -name "*.php" -type f 2>/dev/null

2b. Suspicious file patterns

Search for files with:

  • Random 5-character names: [a-z0-9]{5}.php
  • Known malware names: stmept, guard.sh, wp-admin.php, wp-cron.php, cache.php, test.php, unzip.php, bootstrap.cache.php, themes.php, menu.php, php8.php
  • Binary executables in web directories
  • Files with double extensions: .php.jpg, .jpg.php
  • Temporary PHP files: tmp_*.php

2c. Dangerous code patterns in PHP files

Search app/ and public/ directories for:

eval(
base64_decode(
exec(
system(
passthru(
shell_exec(
gzinflate(
str_rot13(
assert(
preg_replace with /e modifier
$_GET/$_POST/$_REQUEST used with eval/exec
create_function(

2d. Crypto miner detection

# Check for known miner processes
pgrep -f "xmrig\|stmept\|minerd\|cpuminer" 2>/dev/null

# Check for miner binaries
find . -name "stmept" -o -name "xmrig" -o -name "minerd" 2>/dev/null

# Check for mining pool connections in code
grep -r "supportxmr\|nanopool\|minergate\|coinhive" . --include="*.php" --include="*.sh" --include="*.conf" 2>/dev/null

2e. Injected .htaccess files

# Check all .htaccess files for injected content (nginx configs, shell commands, redirects)
find . -name ".htaccess" -exec grep -l "sudo\|nginx\|server_name\|proxy_pass\|RewriteRule.*http" {} \;

Phase 3: Configuration Security Check

3a. Storage directory protection

Check if storage/app/public/.htaccess exists with PHP execution blocking:

<FilesMatch "\.(?:php|phtml|phar|php[0-9]|inc)$">
    Order Deny,Allow
    Deny from all
</FilesMatch>

If missing, CREATE IT - this is the #1 defense against uploaded webshells.

3b. Public .htaccess hardening

Check public/.htaccess for:

  • Block PHP execution in storage/uploads dirs: RewriteRule ^storage/.*\.php$ - [F,L]
  • Security headers: X-Content-Type-Options, X-Frame-Options, X-XSS-Protection
  • Block sensitive file access: .env, .log, .sql, .bak

3c. File upload security

Search for these risky patterns in Filament/Controller code:

  • editableSvgs(true) - SVG can contain JavaScript (XSS) and XXE attacks
  • preserveFilenames() - Original filenames can be manipulated for path traversal
  • Missing mime type validation on upload fields
  • Missing file extension validation

3d. Credential exposure

Check .env file types present (DO NOT output actual values):

grep -E "^[A-Z_]+=." .env | sed 's/=.*/=***/' | grep -iE "key|secret|password|token|mail|sendgrid|aws|stripe|paypal"

Phase 4: Server-Level Checks (if accessible)

4a. Web server user

ps aux | grep -E "nginx|php-fpm|apache" | head -5

CRITICAL if running as root - web server must run as unprivileged user (www-data/nginx).

4b. Sudoers audit

grep -i "NOPASSWD" /etc/sudoers /etc/sudoers.d/* 2>/dev/null

Flag any NOPASSWD: ALL entries - especially for www-data, nginx, or CI users like gitlab-runner.

4c. Crontab persistence check

crontab -l 2>/dev/null
crontab -u www-data -l 2>/dev/null
ls -la /etc/cron.d/ /etc/cron.daily/ 2>/dev/null

4d. Active miner/backdoor processes

pgrep -a -f "xmrig\|stmept\|minerd\|cryptonight"
netstat -tlnp 2>/dev/null | grep -E ":3333|:4444|:5555|:8888"

Phase 5: Auto-Fix (Apply Hardening)

When confirmed by user, apply these fixes:

Fix 1: Create storage/.htaccess (SAFE - zero breaking changes)

<IfModule mod_php.c>
    php_flag engine off
</IfModule>
<IfModule mod_php7.c>
    php_flag engine off
</IfModule>
<IfModule mod_php8.c>
    php_flag engine off
</IfModule>
<FilesMatch "\.(?:php|phtml|phar|php[0-9]|inc)$">
    Order Deny,Allow
    Deny from all
</FilesMatch>

Fix 2: Harden public/.htaccess (SAFE - zero breaking changes)

Add before existing rewrite rules:

# Block PHP execution in storage/upload directories
RewriteRule ^storage/.*\.php$ - [F,L]
RewriteRule ^uploads/.*\.php$ - [F,L]
RewriteRule ^images/.*\.php$ - [F,L]

Add after </IfModule>:

# Security Headers
<IfModule mod_headers.c>
    Header set X-Content-Type-Options "nosniff"
    Header set X-Frame-Options "SAMEORIGIN"
    Header set X-XSS-Protection "1; mode=block"
</IfModule>

# Block access to sensitive files
<FilesMatch "\.(env|log|sql|bak|conf|ini)$">
    Order Deny,Allow
    Deny from all
</FilesMatch>

Fix 3: Generate nginx security config (SAFE - needs manual include)

Create nginx-security.conf:

location ~ ^/storage/.*\.php$ { deny all; return 403; }
location ~ /\.(env|git|htaccess|htpasswd) { deny all; return 404; }
location ~* \.(sql|bak|log|conf|ini)$ { deny all; return 404; }
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;

Fix 4: Vulnerable package mitigation (CHECK for breaking changes)

For packages with breaking changes (e.g., intervention/image v2 → v3):

  1. Copy package from vendor/ to packages/<vendor>/<package>/
  2. Add path repository to composer.json:
{
    "repositories": [{
        "type": "path",
        "url": "packages/<vendor>/<package>",
        "options": { "symlink": true }
    }]
}
  1. This allows patching the vulnerability locally without breaking API changes

Report Format

Present findings as:

## Security Audit Report - [Project Name]

### CRITICAL
- [Findings that need immediate action]

### HIGH
- [Findings that should be fixed soon]

### MEDIUM
- [Findings to address in next sprint]

### LOW
- [Recommendations for improvement]

### AUTO-FIXED
- [List of hardening applied]

### ACTION ITEMS
1. [ ] Rotate all credentials in .env
2. [ ] Kill any running miner processes
3. [ ] Review sudoers configuration
4. [ ] Deploy .htaccess changes to production
5. [ ] Monitor access logs for 48 hours

Common Attack Chain Reference

Based on real incidents, this is the typical attack flow:

1. ENTRY: Path traversal via vulnerable package (e.g., intervention/image v2)
   → Upload PHP webshell to storage/public directory

2. EXECUTION: Web server executes uploaded .php file
   → Because no .htaccess blocks PHP in storage dirs

3. DATA THEFT: Webshell reads .env file
   → Gets DB credentials, API keys (SendGrid, AWS, Stripe, etc.)

4. LATERAL MOVEMENT: Read .env from other projects on same server
   → Shared server = all projects compromised

5. PERSISTENCE: Install crypto miner + cron job
   → guard.sh / wp-admin.php pattern: download xmrig, auto-restart

6. ABUSE: Use stolen API keys
   → Send phishing emails via SendGrid
   → Access cloud resources via AWS keys

Important Notes

  • NEVER output actual credential values - only indicate what types exist
  • Always ask before applying fixes that could have breaking changes
  • Storage .htaccess and public .htaccess hardening are ALWAYS safe to apply
  • When in doubt, report and let the user decide
  • This skill is designed for defensive security only