您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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.