Security headers
Learn security headers like Content-Security-Policy, X-Frame-Options and HSTS.
The header() function
The header() function sends a raw HTTP header. It must be called before any output; otherwise you get a "headers already sent" error. Security headers matter for defense in depth.
Three key headers: Content-Security-Policy (restricts script sources), X-Frame-Options: DENY (blocks the page from being shown in an iframe, prevents clickjacking), Strict-Transport-Security (forces HTTPS).
Content-Security-Policy
Content-Security-Policy (CSP) tells the browser which sources may load scripts, styles and images. The default-src 'self' rule only allows loading from the same origin; inline scripts and external servers are blocked.
CSP limits the impact of XSS even if a vulnerability exists. For example, an attacker's injected external script will not load or run. The header is sent with header().
Exercise Send three security headers
Send three security headers: Content-Security-Policy: default-src 'self', X-Frame-Options: DENY and Strict-Transport-Security: max-age=31536000. Then print the $msg variable with echo.
Show example solution
default-src 'self'");. Add header("X-Frame-Options: DENY"); and header("Strict-Transport-Security: max-age=31536000");. Then print with echo $msg . "\n";.
Example solution:
<?php
header("Content-Security-Policy: default-src 'self'");
header("X-Frame-Options: DENY");
header("Strict-Transport-Security: max-age=31536000");
$msg = "headers sent";
echo $msg . "\n";
Test yourself
-
Match the security headers
- X-Frame-Options
- Prevents clickjacking
- Content-Security-Policy
- Restricts resources
- Strict-Transport-Security
- Forces HTTPS
- header
- Sends an HTTP header
-
Which header prevents clickjacking?
- X-Frame-Options: DENY
- Content-Type: text/html
- Cache-Control: no-store
- Set-Cookie: theme=dark
Show answer
X-Frame-Options: DENY — Correct. X-Frame-Options: DENY blocks the page from being framed.
-
Complete the X-Frame-Options header
header(____);Show answer
header("X-Frame-Options: DENY");