You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提升HTML联系表单的安全性?附现有表单代码

How to Secure Your HTML Contact Form

Great question! You’re already off to a strong start by including a CSRF token with HMAC—let’s build on that to lock down your form against common web security threats. Here’s a step-by-step breakdown:

1. Harden Your CSRF Protection

Your current token uses hash_hmac('sha256', 'some_string', $_SESSION['token'])—let’s make this more robust:

  • Use a unique, random session secret: Replace the static 'some_string' with a cryptographically secure random value generated once per user session. For example:
    // Generate a secure secret when the session starts
    if (!isset($_SESSION['csrf_secret'])) {
        $_SESSION['csrf_secret'] = bin2hex(random_bytes(32));
    }
    // Create a token tied to the user's session and timestamp
    $csrf_token = hash_hmac('sha256', session_id() . time(), $_SESSION['csrf_secret']);
    
  • Validate tokens securely on the backend: When processing the form, recalculate the HMAC and compare it with the submitted token using hash_equals() to prevent timing attacks:
    if (!isset($_POST['token']) || !hash_equals(
        hash_hmac('sha256', session_id() . time(), $_SESSION['csrf_secret']),
        $_POST['token']
    )) {
        die("Invalid request. Please try again.");
    }
    
  • Secure your session cookie: Configure session cookies to block XSS and cross-site misuse:
    session_set_cookie_params([
        'httponly' => true, // Prevent JS access to session cookie
        'secure' => true, // Only send over HTTPS
        'samesite' => 'Strict', // Block cross-site requests
        'lifetime' => 3600 // Expire after 1 hour
    ]);
    session_start();
    

2. Enforce Strict Input Validation

Never trust user input—frontend validation is just for UX; backend validation is non-negotiable:

  • Email validation: Use PHP’s built-in filter to ensure valid format:
    $email = filter_var(trim($_POST['email']), FILTER_VALIDATE_EMAIL);
    if (!$email) {
        // Handle invalid email (e.g., show error message)
    }
    
  • Name validation: Restrict allowed characters to letters, spaces, and common accents (avoid special characters that could enable injection):
    $nome = trim($_POST['nome']);
    if (!preg_match('/^[a-zA-ZÀ-ÿ\s]{1,50}$/', $nome)) {
        // Handle invalid name
    }
    
  • Add HTML constraints: Guide users and reduce invalid submissions with attributes like required, maxlength, and type="email":
    <input type="email" class="form-control" placeholder="Email" id="email" name="email" required maxlength="255">
    <input type="text" class="form-control" placeholder="Nome" id="nome" name="nome" required maxlength="50">
    

3. Prevent Email Injection (If Sending Emails)

If your form sends emails via PHP’s mail() function, attackers can inject malicious headers. Fix this by:

  • Stripping newline characters: Remove \r, \n, and URL-encoded equivalents from inputs:
    $nome = str_replace(["\r", "\n", "%0A", "%0D"], "", $_POST['nome']);
    $email = str_replace(["\r", "\n", "%0A", "%0D"], "", $_POST['email']);
    
  • Using a library like PHPMailer: It automatically handles header injection and is more secure than raw mail():
    use PHPMailer\PHPMailer\PHPMailer;
    $mail = new PHPMailer();
    $mail->addAddress('your-contact-email@example.com');
    $mail->setFrom($email, $nome);
    $mail->Subject = 'New Contact Form Submission';
    $mail->Body = "Name: $nome\nEmail: $email";
    $mail->send();
    

4. Use HTTPS Exclusively

Always serve your form over HTTPS to encrypt data in transit—this prevents attackers from intercepting form inputs (including your CSRF token). Configure your server to redirect all HTTP traffic to HTTPS.

5. Block XSS Attacks

If you ever display user input back to the browser (e.g., a "thank you" page), escape it with htmlspecialchars() to prevent cross-site scripting:

echo "Thank you, " . htmlspecialchars($nome, ENT_QUOTES, 'UTF-8') . "! We'll get back to you soon.";

6. Add Rate Limiting

Prevent spam or brute-force attacks by limiting how often a user can submit the form:

// Track submission frequency in the session
if (!isset($_SESSION['submission_count'])) {
    $_SESSION['submission_count'] = 0;
    $_SESSION['last_submission'] = time();
}
// Block if more than 5 submissions in an hour
if ($_SESSION['submission_count'] >= 5 && time() - $_SESSION['last_submission'] < 3600) {
    die("Too many submissions. Please try again in an hour.");
}
// Reset count after an hour
if (time() - $_SESSION['last_submission'] >= 3600) {
    $_SESSION['submission_count'] = 0;
}
// Update submission tracking
$_SESSION['submission_count']++;
$_SESSION['last_submission'] = time();

7. Avoid Information Disclosure in Errors

Never reveal specific failure reasons to users. Instead of saying "CSRF token invalid", use generic messages like "Invalid request. Please try again." to avoid giving attackers clues.

内容的提问来源于stack exchange,提问作者eskimopest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:11:48