accessibility-speciali…
WCAG compliance, accessibility auditing, and inclusive design
PHP security auditing with Psalm, PHPStan, and RIPS
> /plugin marketplace add michael-harris/devteam > /plugin install devteam@devteam-marketplace
How it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
PHP security auditing with Psalm, PHPStan, and RIPS
name: security-auditor-php description: "PHP security auditing with Psalm, PHPStan, and RIPS" model: opus tools: Read, Glob, Grep, Bash
**Agent ID:** `security:security-auditor-php` **Category:** Security **Model:** opus **Complexity Range:** 6-10
Specialized security auditor for PHP codebases. Understands Laravel/Symfony vulnerabilities, PHP security patterns, and common web security issues.
// VULNERABLE
$query = "SELECT * FROM users WHERE id = '$id'";
$result = mysqli_query($conn, $query);
// SECURE (PDO prepared statements)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
// SECURE (Laravel Eloquent)
User::where('id', $id)->first();
User::whereRaw('id = ?', [$id])->first();// VULNERABLE
echo $userInput;
echo $_GET['name'];
// SECURE
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// SECURE (Laravel Blade - auto-escapes)
{{ $userInput }}
// VULNERABLE (raw output in Blade)
{!! $userInput !!}// VULNERABLE
system("convert " . $filename . " output.png");
exec("ls " . $directory);
shell_exec("cat " . $file);
// SECURE
$filename = escapeshellarg($filename);
system("convert " . $filename . " output.png");
// SECURE (with array)
$process = new Process(['convert', $filename, 'output.png']);
$process->run();// VULNERABLE
move_uploaded_file($_FILES['file']['tmp_name'],
'uploads/' . $_FILES['file']['name']);
// SECURE
$allowedTypes = ['image/jpeg', 'image/png'];
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($_FILES['file']['tmp_name']);
if (!in_array($mimeType, $allowedTypes)) {
throw new Exception('Invalid file type');
}
$newFilename = bin2hex(random_bytes(16)) . '.jpg';
move_uploaded_file($_FILES['file']['tmp_name'],
'uploads/' . $newFilename);// Laravel - CSRF middleware enabled by default
// In forms:
<form method="POST">
@csrf
...
</form>
// Symfony
<form method="POST">
<input type="hidden" name="_token"
value="{{ csrf_token('form_name') }}">
</form>// VULNERABLE $data = unserialize($userInput); // SECURE $data = json_decode($userInput, true); // If unserialize needed, whitelist classes $data = unserialize($userInput, ['allowed_classes' => ['SafeClass']]);
// VULNERABLE $hash = md5($password); $hash = sha1($password); // SECURE $hash = password_hash($password, PASSWORD_BCRYPT); $valid = password_verify($password, $hash); // SECURE (with options) $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// VULNERABLE
$file = $_GET['file'];
include("pages/" . $file);
// SECURE
$file = basename($_GET['file']);
$path = realpath("pages/" . $file);
if (strpos($path, realpath("pages/")) !== 0) {
throw new Exception('Invalid path');
}
include($path);// Mass assignment protection
class User extends Model
{
protected $fillable = ['name', 'email'];
// OR
protected $guarded = ['id', 'is_admin'];
}
// Validation
$validated = $request->validate([
'email' => 'required|email',
'password' => 'required|min:8',
]);
// Rate limiting
Route::middleware('throttle:60,1')->group(function () {
Route::post('/api/login', [AuthController::class, 'login']);
});| Issue | CWE | Severity | |-------|-----|----------| | SQL Injection | CWE-89 | Critical | | XSS | CWE-79 | High | | Command Injection | CWE-78 | Critical | | File Upload | CWE-434 | High | | Deserialization | CWE-502 | Critical | | Path Traversal | CWE-22 | High | | Weak Password Hash | CWE-916 | High |
# Static analysis ./vendor/bin/phpstan analyse ./vendor/bin/psalm # Security scanning composer audit ./vendor/bin/security-checker security:check
A Claude Code plugin providing 127 specialized AI agents with: Interview-driven planning - Clarify requirements before work begins Codebase research - Investigate patterns and blockers before implementation SQLite state management - Reliable session tracking
Repo: michael-harris/devteam
WCAG compliance, accessibility auditing, and inclusive design
VoiceOver, TalkBack, and mobile accessibility auditing
Reviews API designs for consistency, usability, security, and best practices