Content Security Policy (CSP) 
CSP provides additional layer of protection by enforcing loading of resources (scripts, images, etc.) from trusted locations
- It's very effective against XSS, Clickjacking etc.
- Visibility on attacks on app using CSP reporting directive
- Options to deliver CSP: - Content-Security-Policyheader is preferred technique
- <meta>HTML element with- http-equivwith attribute set to- Content-Security-Policy
- Content-Security-Policy-Report-Onlyheader used only for monitoring and not enforcing
 
Headers that can be used:
- Content-Security-Policy: yes
- Content-Security-Policy-Report-Only: !
- X-Content-Security-Policy: no
- X-WebKit-CSP: no
Example:
<meta
  http-equiv="Content-Security-Policy"
  content="
        default-src 'self';
        font-src 'self' https://fonts.gstatic.com/;
        style-src-elem 'self' googleapis.com;
        "
/>CSP Directives 
CSP - fine grain control set
- Fetch: Informs browser of locations to trust and load resources from Eg.: - script-src,- object-src
- Document: Informs properties of documents to which policies will apply. Eg.: - base-url,- sandbox
- Navigation: Informs about the location that the document can navigate to. Eg.: - frame-ancestors
- Reporting: Delivers violations to specified location. Eg.: - report-to,- report-uri
Special directives:
| Name | Purpose | 
|---|---|
| none | Strict. No resources allowed. | 
| self | Strict. Only resources from same origin. | 
| unsafe-inline | Weak. Allows scripts in HTML. | 
| unsafe-eval | Weak. Allows eval()functions in scripts. | 
| strict-dynamic | Strong (if used correctly). Allows trust propagation scripts. | 
Basic CSP Policy 
Basic policy with good security has the following requirements:
- All resources are hosted by the same domain of the document 
- There are no inlines or evals for scripts and style resources: http- Content-Security-Policy: default-src 'self';
- Stricter: Only allow images, scripts, AJAX and CSS from same origin. (No frame, object, media, etc.) http- Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';
Order of priority: default-src --> script-src --> script-src-elem | script-src-attr
Locking Down JavaScript 
- Hash Method: - Calculate the hash of the script or script file 
- Following changes to application is required: 
- Refactor any markup with inline event handlers (e.g. - onclick) and JavaScript: URIs
- Move all scripts (movable) from inline to external JS files 
- Add input validation for any user inputs and encoding before writing into DOM 
 html- script-src 'sha2-d24982a62c99c55d38cf05efe943324c95a342b019b6a5bc136dc865' <!-- chrome calculates for us --> <script> console.log("this will work"); </script> <script src="https://...">
- Nonce: - Nonce is arbitrary number that can be used just once 
- Nonce is composed of - base64values
- Nonce attributes are added to script tags 
- Nonce is verified against the nonce sent in the CSP header 
- Following changes to application is required: - Add nonce attribute to all trusted <script>elements
- For every page load, generate a new nonce and use that in CSP header
 
- Add nonce attribute to all trusted 
 html- script-src 'nonce-SecureRandomValue' <script nonce="SecureRandomValue"> console.log("this will work"); </script> <script nonce="SecureRandomValue" src="https://...">
For dynamic JS:
- Some JS/Framework might add/create scripts dynamically and append to DOM
- If scripts are appended by trusted (nonce) scripts, then allow them
script-src 'nonce-SecureRandomValue' 'strict-dynamic'
<!-- this is allowed -->
<script nonce="SecureRandomValue">
  let s = document.createElement("script");
  s.src = "some.com/some.js";
  document.body.appendChild(s);
</script>
<!-- this is blocked -->
<script src="some.com/some.js">Preventing Clickjacking 
A companion to X-Frame-Options:
- Protect page from being framed by other sites 
- Prevent all framing of your content: http- Content-Security-Policy: frame-ancestors 'none';
- Allow framing for site itself: http- Content-Security-Policy: frame-ancestors 'self';
- Allow framing for trusted domains: http- Content-Security-Policy: frame-ancestors 'trusted.com';
Versions 
CSP3
Policy Injection 
- New directive - script-src-elemallows you to control just script blocks
- This allows event handlers but blocks script elements: http- Content-Security-Policy: script-src-elem 'none'; script-src-attr 'unsafe-inline';
- CSP bypass is possible provided you have policy injection flaw 
- This directive will overwrite existing - script-srcdirectives
JSONP problem:
- Allowlist an origin/path hosting a JSONP
- JS execution is allowed. Depends on JSONP endpoint
- CDN typically have numerous exposed JSONP endpoint
Conclusion 
- CSP is very effective with Nonce and/or SHA
- Beware of using strict-dynamic. Only on trusted scripts/frameworks
- Start with report only CSP header
- Beware of Unvalidated redirects, JSONP endpoints or Header injection
- Not a substitute for XSS protection
