PHP - Content Security Policy (CSP) with PHP
Content Security Policy, commonly referred to as CSP, is a security mechanism used to prevent various types of attacks such as cross-site scripting (XSS) and data injection attacks. It works by defining a set of rules that control which resources a browser is allowed to load and execute on a web page. When implemented correctly, CSP acts as an additional layer of defense even if vulnerabilities exist in the application.
Concept and Purpose
CSP is implemented through HTTP headers sent by the server to the browser. These headers instruct the browser about trusted sources for content such as scripts, styles, images, fonts, and other resources. Instead of trusting all content by default, CSP enforces a whitelist-based approach where only explicitly allowed sources are permitted.
In a PHP application, CSP is typically configured by sending appropriate headers using PHP’s header() function. This allows developers to dynamically control policies depending on the application’s requirements.
Basic CSP Implementation in PHP
A simple CSP header can be set like this:
header("Content-Security-Policy: default-src 'self';");
This policy tells the browser to only load resources from the same origin as the application. It blocks all external scripts, styles, and other resources unless explicitly allowed.
Understanding CSP Directives
CSP policies are composed of directives. Each directive controls a specific type of resource. Some commonly used directives include:
-
default-src: Defines the default policy for all resource types
-
script-src: Controls from where JavaScript can be loaded
-
style-src: Controls CSS sources
-
img-src: Specifies allowed image sources
-
font-src: Defines allowed font sources
-
connect-src: Controls AJAX, WebSocket, and API requests
-
frame-src: Controls embedded content like iframes
Example:
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;");
This allows scripts only from the same domain and a trusted CDN.
Inline Scripts and CSP
By default, CSP blocks inline JavaScript because it is a common source of XSS attacks. However, some applications rely on inline scripts. There are safer alternatives to allow them:
-
Using a nonce (number used once):
$nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: script-src 'self' 'nonce-$nonce';");
The same nonce must be added to the script tag:
<script nonce="generated_nonce_here">
// script content
</script>
-
Using hashes:
A hash of the script content is included in the CSP header, allowing only that exact script to run.
These approaches ensure that only trusted inline scripts are executed.
CSP for External Resources
Modern applications often use third-party resources like CDNs, APIs, and analytics tools. CSP must explicitly allow these sources.
Example:
header("Content-Security-Policy:
default-src 'self';
script-src 'self' https://apis.google.com;
style-src 'self' https://fonts.googleapis.com;
font-src https://fonts.gstatic.com;
");
This configuration allows specific external services while still blocking unknown sources.
Report-Only Mode
During development, enforcing CSP strictly may break functionality. To test policies without blocking resources, CSP provides a report-only mode.
header("Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report.php;");
In this mode, violations are reported but not blocked. Developers can analyze these reports and refine the policy before enforcing it.
Handling CSP Violation Reports
When a violation occurs, the browser sends a report to the specified endpoint. A PHP script can capture and log these reports:
$data = file_get_contents("php://input");
file_put_contents("csp-violations.log", $data, FILE_APPEND);
This helps identify unauthorized resource usage and potential vulnerabilities.
Best Practices for CSP in PHP
A strong CSP implementation should follow these principles:
-
Start with a strict default policy such as default-src 'self'
-
Avoid using unsafe-inline and unsafe-eval whenever possible
-
Use nonces or hashes instead of allowing inline scripts globally
-
Allow only trusted external domains
-
Regularly monitor violation reports
-
Test policies in report-only mode before enforcing
Advantages of CSP
CSP significantly improves application security by:
-
Reducing the risk of XSS attacks
-
Preventing unauthorized script execution
-
Controlling third-party resource loading
-
Adding a defense layer beyond input validation
It does not replace secure coding practices but strengthens them.
Limitations
CSP can be complex to configure, especially for large applications with many dependencies. Incorrect policies may break functionality. Additionally, older browsers may not fully support CSP, although modern browsers provide strong support.
Conclusion
Content Security Policy is a powerful security feature that helps protect PHP applications from common web vulnerabilities. By carefully defining which resources are allowed and enforcing strict rules, developers can greatly reduce the attack surface of their applications. Proper implementation, combined with monitoring and testing, ensures both security and functionality are maintained.