Content Security Policy (CSP) is a browser security mechanism against content injection. Using the CSP header, browsers can restrict content from just the domains whitelisted in the policy. This session shares lessons learned with deploying CSP at Yahoo.
2. https://cwe.mitre.org/data/definitions/79.html
http://bit.ly/1ZK9COc
Cross-site Scripting
● Execution of malicious code injected by an attacker
on victim’s web page
● Leads to credentials and data theft, malware
distribution, site defacement etc.
● Primary reason: Improper neutralization of user input
when it gets rendered on a web page
● Remained as a top threat on OWASP top ten list
since its first publication in 2004
3. Common Remedies
● Input validation and output encoding
● Whitelist trusted contents and tags
● Isolation - e.g. safe iframes
http://bit.ly/1VRI1Gb
6. So what is CSP?
● Content Security Policy is a browser based mechanism that allow you to
whitelist locations from which your web application can load resources.
You can specify a policy on a web page with a CSP HTTP header like
below:
will allow resources to be only loaded from example.com
● Policy Delivery
○ content-security-policy
○ content-security-policy-report-only - for experimenting & monitoring
○ HTML meta tag
content-security-policy: default-src https://example.com
11. <html>
<head>
<base href="https://example.com/" target="_blank">
</head>
<body>
<form action='https://form-sub-example.com' id='theform'
method='post'>
<input type='text' name='fieldname' value='fieldvalue'>
<input type='submit' id='submit' value='submit'>
</form>
</body>
</html>
frame-ancestors - controls who is allowed to frame your page (iframe,
object, embed tags)
plugin-types - whitelist MIME types for object and embed tags. e.g.
application/pdf
sandbox - similar to iframe sandbox attribute. supports allow-forms allow-
same-origin allow-top-navigation
report-uri - specifies a URL to which the user agent sends reports
about policy violation
base-uri
form-action
More directives
12. Directive keywords
● ‘none’ - content-security-policy: default-src ‘none’;
○ Disallows any urls
○ Helpful when you are building a CSP policy
● ‘self’ - content-security-policy: default-src ‘self’;
○ Restricts access to application’s own origin
○ Protocol and port must match as well
● ‘unsafe-inline’ - content-security-policy: script-src ‘unsafe-
inline’;
○ allows inline scripts/style
● ‘unsafe-eval’ - content-security-policy: script-src ‘unsafe-
eval’;
○ allows eval(untrusted_input), setTimeout(untrusted_string) and setInterval
(untrusted_string) and Function constructor
● ‘*’ - wildcard to allow all - content-security-policy: default-src *;
13. CSP versions & browser support
CSP 1.0 http://www.w3.org/TR/CSP1/
○ Available since 2012
○ Directives: connect-src, default-src, font-src, frame-src, img-src, media-
src, objects-src, report-uri, script-src, and style-src
CSP 2.0 http://www.w3.org/TR/CSP2/ (CSP 1.1)
○ Mid 2015
○ New directives: base-uri, child-src, form-action, frame-ancestors, plugin-
types.
○ Deprecates frame-src
Browser support status
○ CSP 1.0 is supported by all modern browsers
○ CSP 2.0 is supported by latest Chrome (v.40+), FireFox (v.35+) and Opera (v27+)
14. Let’s look at some examples….
On https://csp.example.com
content-security-policy: default-src ‘self’;
● https://csp.example.com/campaign.js
● https://csp.example.com/reporting/report.js
● http://csp.example.com/campaign.js
● https://test.csp.com/campaign.js
● https://csp.example.com:8443/campaign.js
15. Why inline Javascript is bad?
Content-Type: text/html; charset=utf-8
<script>console.log("Legitimate javascript code as part of the page");</script>
<div> Welcome, <script>alert("Attack!");</script></div>
https://trusted.example.com/welcome.php?username=<script>alert("Attack!");</script>
<?php
echo '<script>console.log("This is a legitimate javascript code as part of the
page");</script>'
echo '<div class="header"> Welcome, ' . $_GET['username']; . '</div>';
?>
It is hard for the browser to distinguish trusted javascript with a malicious script
16. Mitigation for inline scripts
● Solution 1: Externalizing inline javascript and CSS
○ May involve significant effort for existing applications
○ In addition, there are cases that require inline Javascript, notably for performance.
● Solution 2: use unsafe-inline
○ Reduce the effectiveness of CSP
● Solution 3: CSP 2.0 script whitelisting features - nonce-source and hash-source:
○ nonce whitelisting: nonce-$random - Requires modification to CSP header for every req
○ hash whitelisting - hashAlgorithm-base64hash
○ Hash computation:
% echo -n "alert('Hello, world');" | openssl dgst -sha1 -binary | openssl enc -base64
content-security-policy: script-src 'nonce-random01'
<script nonce="random01"> alert('Hello, world'); </script>
content-security-policy: script-src 'sha1-RgO/D2C8PM9lERhYHMbiSllxM4g='
<script> alert('Hello, world'); </script>
17. Cross-site Scripting
○ CSP prevents XSS from being exploited. How ever it does NOT fix XSS
Unapproved third party beacons, tags and contents
○ Using CSP, restrict the resources to just the whitelisted domains
Packet Sniffing
○ Using CSP, servers can enforce all content be loaded using HTTPS
○ e.g. Content-Security-Policy: default-src https://
Clickjacking - “Look before you click”
○ Use frame-ancestors to specify valid parents
○ Alternate to x-frame-options
Block unwanted plugins
○ Use plugin-types to allow only valid plugins
What are some of the most common attacks and how
can CSP help mitigate?
19. CSP deployment
● Identify domains you trust and start with with a restrictive policy
● Initial policy sample:
● Use HTTPS and enable reporting
● Test this policy using a browser based CSP testing tool (e.g. caspr)
● Rinse and repeat!
content-security-policy-report-only: default-src 'none';
script-src 'self';
connect-src 'self';
img-src 'self';
style-src 'self';
font-src 'self';
report-uri https://csp.example.com
22. Post deployment
● In theory, fully compliant CSP
implementation can leverage reports to
detect injection attacks; however..
● Reports are noisy due to browser
extension violations
● Detect malicious extensions in user
browser
27. Browser extensions - To sum-up
● Extensions are considered as part of Trusted
Computing Base
● They can
○ Interfere with our web pages
○ Alter and inject javascripts to our page
■ Ad injection
■ Malware, exfiltrate user information
■ Alter CSP header itself!
● May contain security vulnerabilities
● Generate large volume of CSP reports
● Make injection attack detection extremely hard
http://bit.ly/1kbsLbp
28.
29. ● Not a solution for all content injection problems
○ E.g. SQL, Shell and other server side injections
● Loose policies
○ Render CSP less effective
● Browser extensions can override CSP policies,
○ Less effective against malicious extensions
● Whitelisted locations are fully trusted
○ CDN scenario
Not so good side of CSP
30. ● Maintain code hygiene
○ Keep HTML, CSS and Javascript separate
○ Use Javascript event handlers
● Automation
○ csp-validator.js protects against CSP misconfigurations and HTTPS
enforcement
● Use stricter policies
○ Always use https:
○ Avoid the use of unsafe-inline and unsafe-eval
○ Use paths https://cdn.example.com/asset/path/ (CSP 2.0 feature)
○ Avoid wildcards if possible - *.example.com
● Enable reporting even on enforce mode
○ Help in detecting content injection in near real time
CSP best practices
31. CSP - What else?
● Scan violation URLs for malwares
● Detect injection attacks in near real time by
analyzing CSP violation reports
● Threat intelligence - IP and URL reputation
based on blocked links
https://www.flickr.com/photos/drp/34988312
32. CSP testing tools
● csptester.io - Open source tool
● csp-validator.js for CICD - PhantomJS headless script to audit CSP policy
for the given URL
● GitHub: https://github.com/yahoo/csptester
● Chrome browser plugin - caspr