Files
APAW/.kilo/skills/php-security/SKILL.md
¨NW¨ b46a1a20a8 feat: add PHP development stack, atomic tasks, modular code rules, agent monitoring, fix target project detection
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
2026-04-18 23:43:04 +01:00

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