CSRF and XSS Protection in PHP
Introduction
When developing secure web applications in PHP, two of the most critical vulnerabilities you must defend against are CSRF (Cross-Site Request Forgery) and XSS (Cross-Site Scripting). These attack vectors are widely used by hackers to steal user data, perform unauthorized actions, or inject malicious scripts.
In this guide, we'll explore:
- What is CSRF and XSS in PHP?
- Real-world examples of CSRF and XSS attacks
- How to prevent CSRF attacks using tokens
- How to protect against XSS using output encoding
- Secure coding practices to reduce risks
- Tools and libraries to enhance PHP security
What is CSRF in PHP?
CSRF (Cross-Site Request Forgery) Definition
CSRF is a type of session-riding attack where an attacker tricks an authenticated user into submitting a malicious request to your application.
Example CSRF Attack
Suppose a user is logged into their online banking account and clicks on a malicious link:
<img src="https://bank.com/transfer.php?to=attacker&amount=1000">
If the application doesn't verify the request's authenticity, the money will be transferred without user consent.
How CSRF Works in PHP
- The attacker sends a request on behalf of a logged-in user.
- The user's session cookie is automatically included.
- The server accepts the forged request.
How to Prevent CSRF in PHP
The most effective way to prevent CSRF attacks in PHP is to use CSRF tokens.
What is a CSRF Token?
A CSRF token is a unique, random string generated for each session/form and verified on form submission.
Step-by-Step CSRF Token Implementation in PHP
1. Generate CSRF Token
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
2. Add Token to HTML Form
<form action="process.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="text" name="username">
<input type="submit" value="Submit">
</form>
3. Validate Token in PHP Script
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("CSRF token validation failed");
}
This ensures that only genuine form submissions are processed.
XSS (Cross-Site Scripting) in PHP
What is XSS?
XSS occurs when an attacker injects malicious scripts into content that is viewed by other users.
Types of XSS Attacks
- Stored XSS: Malicious code stored in a database
- Reflected XSS: Code is included in URL and reflected back to the user
- DOM-Based XSS: Injected into the page through the DOM (JavaScript)
Example Reflected XSS
echo "Welcome " . $_GET['name'];
If the URL is: ?name=<script>alert(1)</script>, the script will execute.
How to Prevent XSS in PHP
The key to preventing XSS is output encoding. Always escape special characters in user input before rendering.
1. Use htmlspecialchars()
$name = htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
echo "Welcome " . $name;
This converts:
- < to <
- > to >
- " to "
- ' to '
2. Encode All Output from User Input
Whenever you display data from users—via forms, database, or URLs—use htmlspecialchars().
3. Avoid echo $_POST or $_GET Directly
Instead, always sanitize like this:
echo htmlspecialchars($_POST['message']);
PHP XSS and CSRF Vulnerabilities in Forms
Insecure Example
<form method="post">
<input type="text" name="comment">
<input type="submit">
</form>
<?php echo $_POST['comment']; ?>
Secure Example
<form method="post">
<input type="text" name="comment">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="submit">
</form>
<?php echo htmlspecialchars($_POST['comment']); ?>
Combines CSRF and XSS protection.
Secure Coding Practices for PHP
1. Sanitize User Input
Use filter_input() or filter_var() for validation:
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
2. Set Content-Type Headers
header("Content-Type: text/html; charset=UTF-8");
This reduces risk of character-set-based XSS attacks.
3. Disable register_globals
Ensure your php.ini has:
register_globals = Off
This prevents automatic variable creation from $_GET and $_POST.
4. Use Content-Security-Policy (CSP)
In HTML headers:
header("Content-Security-Policy: default-src 'self'; script-src 'self';");
Helps mitigate XSS by controlling where scripts can be loaded from.
Tools and Libraries for CSRF/XSS Protection in PHP
1. Symfony Security CSRF Component
composer require symfony/security-csrf
Automatically handles token generation and validation.
2. Laravel Built-in CSRF Protection
Laravel includes CSRF tokens in all forms by default using Blade:
@csrf
3. OWASP PHP Security Cheat Sheet
Regularly updated guidelines: OWASP PHP Security
Comparison Table: CSRF vs XSS
Feature | CSRF | XSS |
---|---|---|
Attack Vector | Forged requests | Injected scripts |
Targets | Authenticated users | End users |
Type of Threat | Unauthorized actions | Data theft, session hijack |
Prevention Method | Tokens, SameSite cookies | Output encoding, content validation |
Typical Entry Point | Forms, links | URL, comment, input field |