7 evolutionary tasks implemented: 1. PHP web development: php-developer agent + 6 skills (Laravel, Symfony, WordPress, security, testing, modular architecture) + 2 pipeline commands (/laravel, /wordpress) 2. Atomic task decomposition: 1 action = 1 task rule, task sizing guide, decomposition protocol for orchestrator, token budgets per complexity 3. Modular code rules: max 100 lines/file, max 30 lines/function, service/repository patterns, cross-module communication via events only 4. Gitea-centric workflow: mandatory issue creation before work, research with links, progress checkboxes, screenshots on test, git history as knowledge base 5. Fix: target project auto-detection — removed all hardcoded UniqueSoft/APAW from API calls, added get_target_repo() via git remote, GITEA_TARGET_REPO env override 6. Agent execution monitoring: agent-executions.jsonl logging, agent-stats.ts statistics script, required fields per invocation, Gitea comment includes duration/tokens 7. Token optimization: 1 action = 1 task principle, token budgets by task type, routing matrix, no scope creep, skip unnecessary pipeline steps
3.8 KiB
3.8 KiB
name, description
| name | description |
|---|---|
| php-security | PHP security patterns - OWASP Top 10, CSRF, XSS, SQL injection, authentication, input validation |
PHP Security Checklist
Input Validation & Sanitization
// Always validate and sanitize input
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$price = filter_input(INPUT_POST, 'price', FILTER_VALIDATE_FLOAT);
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
// Laravel: Form Request validation
// Symfony: Form Types with Constraints
// WordPress: sanitize_text_field(), absint()
SQL Injection Prevention
// NEVER: Direct string interpolation
$sql = "SELECT * FROM users WHERE email = '$email'"; // VULNERABLE!
// ALWAYS: Parameterized queries
// PDO
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
// Laravel Eloquent (safe by default)
User::where('email', $email)->first();
// WordPress $wpdb
$wpdb->get_results($wpdb->prepare(
'SELECT * FROM %i WHERE email = %s',
$wpdb->users,
$email
));
XSS Prevention
// Output encoding
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// Laravel: Blade auto-escapes {{ $variable }}
// Symfony: Twig auto-escapes {{ variable }}
// NEVER output raw user data
echo $userInput; // VULNERABLE!
// Content Security Policy header
header("Content-Security-Policy: default-src 'self'; script-src 'self'");
CSRF Protection
// Laravel: @csrf in forms
<form method="POST">
@csrf
...
</form>
// Symfony: $form->handleRequest($request) handles CSRF
// WordPress: wp_nonce_field() + wp_verify_nonce()
// API: Use Sanctum tokens instead of CSRF
Authentication
// Laravel Sanctum (API)
$token = $user->createToken('api-token')->plainTextToken;
// Password hashing (NEVER md5/sha1)
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
if (password_verify($input, $hash)) { /* authenticated */ }
// Rate limiting
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->ip());
});
File Upload Security
// Validate file type, size, and content
$allowedMimes = ['image/jpeg', 'image/png', 'image/webp'];
$maxSize = 2 * 1024 * 1024; // 2MB
if (!in_array($file->getMimeType(), $allowedMimes)) {
throw new ValidationException('Invalid file type');
}
if ($file->getSize() > $maxSize) {
throw new ValidationException('File too large');
}
// Store outside web root
$path = $file->store('uploads', 'private');
// NEVER use user-provided filenames
Session Security
ini_set('session.cookie_httponly', '1');
ini_set('session.cookie_secure', '1');
ini_set('session.cookie_samesite', 'Strict');
ini_set('session.use_strict_mode', '1');
// Regenerate ID on login
session_regenerate_id(true);
Security Headers
// Add security headers
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Permissions-Policy: camera=(), microphone=(), geolocation=()');
OWASP Top 10 Checklist
| # | Risk | Mitigation |
|---|---|---|
| A01 | Broken Access Control | Authorization checks, RBAC, deny by default |
| A02 | Crypto Failures | TLS, bcrypt, no weak algorithms |
| A03 | Injection | Parameterized queries, validation |
| A04 | Insecure Design | Threat modeling, secure defaults |
| A05 | Security Misconfig | No debug in prod, no defaults, headers |
| A06 | Vulnerable Components | composer audit, update regularly |
| A07 | Auth Failures | MFA, rate limit, strong passwords |
| A08 | Data Integrity | Signature verification, CI security |
| A09 | Logging | Log auth failures, no sensitive data in logs |
| A10 | SSRF | URL allowlist, no internal requests |