Content-Security-Policy (CSP)
Content Security Policy (CSP) is a security mechanism that helps prevent cross-site scripting (XSS), clickjacking, and other code injection attacks by allowing websites to specify which sources of content are trusted. It is an HTTP header that defines a whitelist of content sources, such as scripts, stylesheets, and images, that a website is allowed to load and execute.
When a web page with a CSP is loaded, the browser will only load resources from the allowed sources specified in the policy. If a resource is not from an allowed source, the browser will block it from loading. This helps to protect against malicious code injection attacks that try to load unauthorized scripts or other resources on the page.
CSP can be customized to meet the needs of different websites by allowing or blocking specific sources of content, such as third-party scripts, inline scripts, or eval functions. It can also be used to report violations to a designated endpoint, which can help developers identify and fix security issues.
Overall, CSP is a powerful tool for improving the security of web applications by reducing the attack surface and mitigating the impact of code injection attacks.
It is a feature of modern browsers, allows to helps protect the application.
An added layer of protection that helps mitigate some client-side attacks. Works similar to a firewall, for client-side source code.
Lets developers whitelist client-side code to run on their website.
Limitations
opt-in model; does nothing by default. Developers have to explicitly specify.
only an exposure control; CSP cannot patch vulnerabilities or remediate defects. Not a substitute for output encoding and other primary controls. Does not fix anything and is used like a blocker to block contents. CSP is not a fix for vulnerabilities in code. It’s a mechanism that limits content sources and helps to mitigate the impact of code injection attacks. It’s important to use CSP alongside other primary security controls like input validation and output encoding for a more comprehensive security solution.
only partially effective; does not stop HTML code injection, although it can limit the effectiveness of HTML injection by blocking images, actions, etc.
only helps with client-side attacks; useless for server-side vulnerabilities. It is basically a browser-based control.
Challenges
It requires developers with best-practice code. CSP is basically a policy that blocks the injection.
Developers are allowed to disable CSP. Might implement CSP technically but in unsafe (disabled when CSP is not wanted) mode. CSP forces to write best-practice code. Code cannot be embedded in HTML. All code including JS and styles must be placed in “include” files. CSP restricts inline (CSS) and inline (JS). Events must migrate to registered events. Any remaining scripts must be tagged using “nonce” or “digest”. Lets the browser know that this code is a part of the source code. The developer team understands that it was not injected at runtime by some untrusted sources.
Requires developers to write best-practice code
Developers can disable CSP or use it in unsafe mode
Forces developers to place code in separate files rather than embedding in HTML
Restricts the use of inline CSS and JS
Events must be migrated to registered events
Any remaining scripts must be tagged using “nonce” or “digest”
Developers must ensure that the code is part of the source code and not injected at runtime by untrusted sources.
Example
This code is implementing Content Security Policy (CSP) on a web page by using a nonce to allow only specific scripts to be executed. Here’s what’s happening in the code:
The first line generates a random 32-byte nonce using the
openssl_random_pseudo_bytes()
function and converts it to a hexadecimal string usingbin2hex()
.The second line constructs a CSP header with a policy that allows scripts to be loaded only from the current domain (
'self'
) and from the domainmutillidae.local
. Thenonce
attribute is included with the nonce value from the previous step to allow specific scripts to bypass the CSP policy.The third section of the code includes a script tag with the
nonce
attribute set to the nonce value. This allows the script to bypass the CSP policy and be executed because it has a matching nonce.The
addEventListener
function sets up a listener for theDOMContentLoaded
event, which fires when the page has finished loading. When this event is triggered, the function passed to it will execute. In this case, the function is searching for an element with the IDidCSPForm
and performing some action on it.
Overall, this code is using CSP to limit the sources of scripts that can be loaded on the page, which can help to mitigate the risk of code injection attacks. The use of a nonce allows specific scripts to bypass the CSP policy, while still ensuring that they are not injected at runtime by untrusted sources.
Implementation
Implemented as HTTP Response Header, dictating the site’s security policy.
Like all HTTP Headers, CSP header is a colon-delimited name and value. Content-Security-Policy (CSP) is the standard header used to specify a content security policy for a web page. X-Content-Security-Policy is an older, deprecated version of the CSP header that lacks some of its advanced features. CSP is more robust and flexible, and recommended for modern browsers, while X-Content-Security-Policy may still be needed for backward compatibility.
The policy can be broken down into multiple directives. Values are basically a set of one/more directives separated by semi-colons.
Directives
Directives are the one who blocks. They are of multiple types –
Blockers
resource ‘fetch’ policies
specifies trusted locations for source code and other resources. From where data is allowed to fetch.
script-src ‘self’ (allowing scripts to only be loaded from the same domain as the page itself)
Blockers
document policies
allow further control over the behavior of a document, including the application of CSP rules, beyond what is specified in the HTTP response headers.
allow-top-navigation ‘self’ (allowing the page to be navigated to other pages on the same domain)
Blockers
navigation policies
from/to where users can navigate
frame-ancestors ‘none’ (preventing the page from being loaded inside an iframe on another domain)
Reports
reporting policies
allows violations to be reported to the development teams.
report-uri /csp-violation-report-endpoint (specifying a URL where violation reports should be sent)
The composition of CSP is in name:value pairs. Directives have a name and a list of sources, which are space delimited.
This policy defines that, scripts can be downloaded from ‘self’ (same origin) and the URL.
There are different types of sources –
none – Disables any resources for the policy
self – content from the same domain or the origin
URL – another domain
nonce – a random number assigned to the script by the server [dynamic]
digest – a digest (hash) of the code included in the page [static]
nonce and digests are used to tag legacy code so the code won’t be blocked.
CSP has brought formerly independent features under the same umbrella. It has introduced directives related to HTML Injection. It does not directly block; but blocks activities that typically go along with HTML Injection.
form-action: defines valid sources that can be used as an HTML <form> action.
font-src: restricts source (URLs) from which fonts may be loaded.
img-src: restricts URLs from which images may be loaded.
style-src: restricts locations from which style may be applied to a document.
frame-src: defines valid sources for loading frames.
media-src: restricts URLs from which media resources may be loaded.
object-src: restricts URLs from which objects may be loaded.
sandbox: enables a set of extra restrictions on any content hosted by the frame and iframe.
CSP does not block any HTML Injection but rather blocks different actions.
Important Directives
Directives Related to XSS
connect-src
Restrict URLs loaded using script interfaces like XHR and web sockets. Where this domain is allowed to connect to.
script-src
Restricts the locations from which scripts may be executed
These directives may mitigate code injection. Some sample console.logs for CSP Blocking –
In addition to a console message, a securitypolicyviolation
event is fired on the window. Further: https://www.w3.org/TR/CSP2/#firing-securitypolicyviolationevent-events.
In general, all the blocking directives work similarly.
CSPs’ XSS directives obsolete X-XSS-Protection. This is replaced by script-src policy.
Directives Related to Phishing
frame-ancestors
defines valid sources to embed resources. using <object>, <embed>, <applet>. setting this directive to ‘none’ is equivalent to X-Frame-Options: DENY. Blocks potential clickjacking.
navigate-to
Restricts where document may send the user. Checks the link, if it is the designated one or not. example: link clicked → form submitted (on) window.location. form-action takes precedence over form submission.
form-action
valid sources that can be used as an HTML
action. Similar to navigate-to, decides where the form submission can be sent to.
Obsoletes X-Frame-Options. frame-options is replaced by frame-ancestors policy.
frame-ancestors extend the capability of frame-options. Systems that want to allow others (example: business partners) to frame the site, might include the following HTTP Header where is a fully qualified domain without wild cards.
Special Directives
default-src: Serves as a fallback for other fetch directives. Sets the policy for any directives that are not specified.
Reporting Features
Reporting directives basically report back whenever there is a problem.
report-uri
instructs the user-agent to report violations to the given URL
report-to
will replace report-uri. declares report policy in ‘report-to’ HTTP Header. Indicates which reporting endpoint from the report-to to use.
Report-to VS report-to
The Report-to
HTTP header allows website owners to specify an endpoint URL to which the user agent can report violations of the CSP policy. This header is sent along with the CSP policy in the HTTP response. Here’s an example of how it can be used:
The report-to
CSP directive is used to specify a JSON object that defines the endpoint(s) to which the user agent should report CSP violations. This directive is included in the CSP policy itself. Here’s an example:
In both cases, the JSON object specifies the endpoint URL to which the user agent should report the violations. However, with the Report-to
HTTP header, the report-to
directive is not necessary in the CSP policy itself. Additionally, the Report-to
HTTP header allows for the specification of multiple endpoints, while the report-to
directive only allows for one endpoint to be specified.
Overall, the Report-to
HTTP header and report-to
CSP directive provides similar functionality for reporting CSP violations, but the Report-to
HTTP header provides more flexibility in specifying multiple endpoints and allows for reporting on policies that do not include a report-to
directive.
Additional Resources
Conclusion
Content-Security-Policy is a security mechanism that helps defend web applications from a variety of attacks, such as cross-site scripting (XSS), clickjacking, and other code injection attacks. It enables developers to whitelist specific content sources and restrict others, thereby reducing the attack surface for malicious actors. However, CSP has certain limitations and must be implemented with caution in order to be effective.
Last updated