security-audit について
security-auditは、Laravel/PHPプロジェクトの保守担当者向けセキュリティ監査スキルです。依存関係、ファイル、コード、サーバー設定のリスクを調べ、互換性に影響する可能性のある修正は事前確認を求めます。
主な機能
- 01composer.lockの既知の脆弱性を確認
- 02不正ファイル、危険なコード、マイナーの痕跡を検索
- 03アップロード、ストレージ、機密ファイルの保護を点検
- 04認証情報の露出とサーバー上のリスクを確認
- 05重大度別に監査結果を整理
- 06確認後にセキュリティ強化を適用
活用シーン
- 01Laravel/PHPプロジェクトの依存関係の脆弱性監査
- 02アップロード領域のWebシェルや不正ファイルの調査
- 03.htaccessとセキュリティヘッダー設定の確認
- 04サーバープロセス、sudoers、定期タスクのリスク評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hexters/ laravel-security-audit --skill security-auditインストール後、Claude Code で/security-auditを入力して読み込まれたか確認します。
詳細
Laravel/PHP プロジェクト向けセキュリティ監査スキル
あなたはセキュリティ監査エージェントです。有効化されたら、現在のプロジェクトに対して包括的なセキュリティ監査を実施してください。各フェーズを順番に実行し、調査結果を明確に報告してください。
フェーズ 1:脆弱なパッケージの検出
既知の脆弱なパッケージがないか、composer.lock をスキャンします。
# 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')
"
利用可能な場合は、composer audit も実行してください。
対応項目:
intervention/image< v3 は重大(パストラバーサルにより.envの読み取りが可能)として報告します- 脆弱なパッケージが直接依存か、推移的依存かを確認します
- アップグレードが安全か、ローカルパスリポジトリを使う必要があるかを判断します
フェーズ 2:マルウェアとウェブシェルのスキャン
以下の場所に悪意のあるファイルがないか検索します。
2a. アップロード/ストレージディレクトリ内の PHP ファイル(存在してはいけません)
find storage/app/public public/uploads public/images public/storage -name "*.php" -type f 2>/dev/null
2b. 不審なファイルパターン
次のファイルを検索します。
- ランダムな 5 文字の名前:
[a-z0-9]{5}.php - 既知のマルウェア名:
stmept、guard.sh、wp-admin.php、wp-cron.php、cache.php、test.php、unzip.php、bootstrap.cache.php、themes.php、menu.php、php8.php - Web ディレクトリ内のバイナリ実行ファイル
- 二重拡張子のファイル:
.php.jpg、.jpg.php - 一時 PHP ファイル:
tmp_*.php
2c. PHP ファイル内の危険なコードパターン
app/ および public/ ディレクトリを検索します。
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. 暗号資産マイナーの検出
# 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. 挿入された .htaccess ファイル
# 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" {} \;
フェーズ 3:設定のセキュリティチェック
3a. ストレージディレクトリの保護
storage/app/public/.htaccess が存在し、PHP の実行をブロックしているか確認します。
<FilesMatch "\.(?:php|phtml|phar|php[0-9]|inc)$">
Order Deny,Allow
Deny from all
</FilesMatch>
存在しない場合は作成してください。これはアップロードされたウェブシェルに対する最も重要な防御策です。
3b. public .htaccess の強化
public/.htaccess について、以下を確認します。
- ストレージ/アップロードディレクトリ内の PHP 実行をブロック:
RewriteRule ^storage/.*\.php$ - [F,L] - セキュリティヘッダー:
X-Content-Type-Options、X-Frame-Options、X-XSS-Protection - 機密ファイルへのアクセスをブロック:
.env、.log、.sql、.bak
3c. ファイルアップロードのセキュリティ
Filament/Controller コード内で、次のリスクのあるパターンを検索します。
editableSvgs(true)— SVG には JavaScript が含まれる可能性があり、XSS および XXE 攻撃の危険がありますpreserveFilenames()— 元のファイル名がパストラバーサルに悪用される可能性があります- アップロードフィールドで MIME タイプの検証がない
- ファイル拡張子の検証がない
3d. 認証情報の露出
存在する .env ファイルの種類を確認します(実際の値は出力しないでください)。
grep -E "^[A-Z_]+=." .env | sed 's/=.*/=***/' | grep -iE "key|secret|password|token|mail|sendgrid|aws|stripe|paypal"
フェーズ 4:サーバーレベルのチェック(アクセス可能な場合)
4a. Web サーバーのユーザー
ps aux | grep -E "nginx|php-fpm|apache" | head -5
root で実行されている場合は重大です。Web サーバーは非特権ユーザー(www-data/nginx)で実行する必要があります。
4b. sudoers の監査
grep -i "NOPASSWD" /etc/sudoers /etc/sudoers.d/* 2>/dev/null
NOPASSWD: ALL のエントリがあれば報告します。特に www-data、nginx、または gitlab-runner などの CI ユーザーに注意してください。
4c. crontab による永続化のチェック
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. 実行中のマイナー/バックドアプロセス
pgrep -a -f "xmrig\|stmept\|minerd\|cryptonight"
netstat -tlnp 2>/dev/null | grep -E ":3333|:4444|:5555|:8888"
フェーズ 5:自動修正(セキュリティ強化の適用)
ユーザーの確認後、次の修正を適用します。
修正 1:storage/.htaccess の作成(安全 — 互換性への影響なし)
<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>
修正 2:public/.htaccess の強化(安全 — 互換性への影響なし)
既存の rewrite ルールより前に追加します。
# Block PHP execution in storage/upload directories
RewriteRule ^storage/.*\.php$ - [F,L]
RewriteRule ^uploads/.*\.php$ - [F,L]
RewriteRule ^images/.*\.php$ - [F,L]
</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>
修正 3:nginx セキュリティ設定の生成(安全 — 手動での include が必要)
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;
修正 4:脆弱なパッケージの緩和(互換性への影響を確認)
互換性を損なう変更があるパッケージ(例:intervention/image v2 → v3)については、次の手順を実行します。
vendor/からパッケージをpackages/<vendor>/<package>/にコピーしますcomposer.jsonにパスリポジトリを追加します。
{
"repositories": [{
"type": "path",
"url": "packages/<vendor>/<package>",
"options": { "symlink": true }
}]
}
- これにより、API の変更を伴わずに脆弱性をローカルで修正できます
報告形式
次の形式で調査結果を提示します。
## 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
典型的な攻撃チェーンの参考情報
実際のインシデントに基づく、典型的な攻撃の流れは次のとおりです。
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
重要な注意事項
- 実際の認証情報の値は絶対に出力せず、存在する種類のみを示してください
- 破壊的変更を伴う可能性がある修正を適用する前に、必ず確認してください
- ストレージの
.htaccessと公開用の.htaccessの強化は、常に安全に適用できます - 判断に迷う場合は報告し、ユーザーの判断に委ねてください
- このスキルは防御的なセキュリティのみを目的としています