Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

5.3KB

Security Skill

Purpose

Use this skill for input validation, output escaping, passwords, authentication, authorization, sessions, CSRF, secrets, error disclosure, dangerous functions, serialization, and file/path safety.


Security Baseline

Treat all external data as untrusted.

Untrusted data includes:

  • $_GET
  • $_POST
  • $_REQUEST
  • $_COOKIE
  • $_SERVER
  • uploaded files
  • request bodies
  • session values
  • database values originally supplied by users
  • third-party API responses

Input Validation

Validate on input.

Example:

$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);

if ($email === false || $email === null) {
    throw new InvalidArgumentException('A valid email address is required.');
}

Rules:

  • Validate type, range, length, format, and allowed values.
  • Validate server-side even when client-side validation exists.
  • Reject unexpected fields when appropriate.
  • Normalize data intentionally, not accidentally.

Output Escaping

Escape on output based on context.

For HTML output:

function e(string $value): string
{
    return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

Usage:

<p><?= e($user->name()) ?></p>

Rules:

  • Escape based on context: HTML, attribute, JavaScript, CSS, URL, SQL, shell.
  • Do not use the same escaping function for every context.
  • Prefer template engines with automatic escaping only when appropriate for the project.
  • Avoid allowing raw HTML from users. If required, sanitize with a proven whitelist sanitizer.
  • Use escapeshellarg() when passing controlled values to shell commands, and avoid shell execution when possible.
  • Never trust file paths supplied by users.
  • Reject path traversal values such as ../, /, \, and null bytes when user-provided paths are not allowed.

Passwords and Authentication

Never store plain-text passwords.

Use PHP’s password API:

$hash = password_hash($plainPassword, PASSWORD_DEFAULT);

if (! password_verify($plainPassword, $hash)) {
    throw new RuntimeException('Invalid credentials.');
}

Rules:

  • Use password_hash() for new password hashes.
  • Use password_verify() for login checks.
  • Use password_needs_rehash() when algorithm/cost settings change.
  • Do not create your own password hashing algorithm.
  • Do not use general-purpose hashes like md5, sha1, or raw sha256 for passwords.
  • Rate-limit login attempts.
  • Regenerate session IDs after login.
  • Use secure, HTTP-only, SameSite cookies for sessions.

Authorization

  • Check authorization separately from authentication.
  • Do not assume logged-in means allowed.
  • Enforce permissions server-side.
  • Avoid hiding buttons as the only authorization control.
  • Prefer explicit permission checks near protected actions or service boundaries.

CSRF

Use CSRF protection for state-changing forms and unsafe HTTP methods.

State-changing actions include:

  • Create
  • Update
  • Delete
  • Login/logout state changes
  • Password changes
  • Email changes
  • Permission changes

Serialization and Data Exchange

Do not call unserialize() on untrusted data.

Prefer JSON for data exchange:

$data = json_decode($json, true, flags: JSON_THROW_ON_ERROR);
$json = json_encode($data, JSON_THROW_ON_ERROR);

Rules:

  • Use JSON_THROW_ON_ERROR for new code.
  • Validate decoded data before using it.
  • Avoid PHP serialization for data that crosses trust boundaries.

Configuration and Secrets

Rules:

  • Keep secrets out of source control.
  • Do not commit passwords, API keys, private keys, tokens, or production DSNs.
  • Store configuration outside the public web root.
  • Use environment variables or ignored local config files for secrets.
  • Provide a safe example file such as .env.example.

Example .gitignore entries:

.env
.env.local
/config/local.php
/var/cache/
/var/log/
/vendor/

Error Handling and Logging

Development:

  • Show errors locally.
  • Log errors.
  • Use Xdebug when debugging complex issues.

Production:

  • Do not display errors to users.
  • Log errors to a secure log destination.
  • Return safe, generic error messages.
  • Preserve enough context in logs for troubleshooting.

Do not leak:

  • stack traces to users
  • SQL statements with secrets
  • environment variables
  • full filesystem paths
  • tokens or passwords

Example:

try {
    $service->handle($request);
} catch (Throwable $e) {
    $logger->error('Order processing failed.', [
        'exception' => $e,
        'requestId' => $requestId,
    ]);

    http_response_code(500);
    echo 'An unexpected error occurred.';
}

Security Checklist

Before completing any feature, verify:

  • All external input is validated.
  • All output is escaped for the correct context.
  • SQL uses prepared statements or safe query builders.
  • Authentication and authorization are checked server-side.
  • Secrets are not committed.
  • Errors are not exposed in production responses.
  • File uploads validate size, extension, MIME type, and storage path.
  • Passwords use password_hash() and password_verify().
  • CSRF protection exists for state-changing requests.
  • Dangerous functions are avoided or justified: eval, exec, shell_exec, system, passthru, unserialize.
  • Dependencies have no known vulnerabilities according to composer audit.

Powered by TurnKey Linux.