htmlspecialchars() is a function used to prevent XSS (Cross-Site Scripting) attacks. It works by converting special characters in HTML (such as <, >, ", &) into HTML entities, preventing malicious scripts submitted by users from executing on the page. For example:
<?php
$user_input = '<script>alert("XSS")</script>';
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
?>
The output will be:
<script>alert("XSS")</script>
This code effectively prevents the injection of malicious JavaScript into HTML, but it has little to no direct relation to preventing CSRF attacks.
CSRF exploits the "logged-in state" of a user. An attacker tricks the user into clicking a link or visiting an image/iframe, using the user's current login status on a website to make a request. For example:
<img src="https://m66.net/delete_account.php" />
If the user is logged in to m66.net and the server doesn't perform any validation, this request could potentially delete the user's account.
The key to this attack is that the user unknowingly initiates a state-changing request, and the server trusts the request.
htmlspecialchars() operates at the "output phase," mainly preventing the browser from interpreting malicious scripts. CSRF attacks, however, involve requests automatically or deliberately initiated by the user's browser, which may be triggered even without any page output.
In other words, CSRF is a "request that impersonates the user," and it doesn't matter whether the output content is escaped. Therefore, htmlspecialchars() cannot prevent CSRF attacks.
Use CSRF Tokens
The most effective method is to include a randomly generated CSRF token in forms and validate it when processing requests. For example:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
?>
<form method="POST" action="https://m66.net/update_profile.php">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>" />
<!-- Other form fields -->
<button type="submit">Submit</button>
</form>
<?php
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die("Illegal request!");
}
// Execute update operation
}
?>
Verify Referer or Origin Headers
Although not entirely reliable, in some cases, this can help determine whether a request is legitimate. For example:
<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';
if (parse_url($referer, PHP_URL_HOST) !== 'm66.net') {
die("Invalid source");
}
?>
Use SameSite Cookie Attribute
Modern browsers support preventing third-party requests from sending cookies by setting the SameSite=Strict or SameSite=Lax cookie attributes:
setcookie('session_id', $value, [
'samesite' => 'Strict',
'secure' => true,
'httponly' => true
]);