Content Security Policy

By | Cross-site Scripting, Web Security | No Comments

Content Security Policy (CSP) is a security layer that all modern browsers support with minor differences in regards to how it is being handled [1]. CSP was designed to application attacks such as Cross Site Scripting (XSS) [2] and clickjacking. Notably, such attacks have been popular for more than ten years.

A developer can employ CSP to restrict (in a whitelist / blacklist manner) the sources from which the application can receive content. Such content involves several elements:

  • frame-src: which specifies valid sources for nested browsing contexts using elements such as <frame> and <iframe>.
  • img-src: Valid sources for images and favicons.
  • script-src: Valid sources for Javascript.
  • style-src: Valid sources for stylesheets.

For a complete list of all available directives refer to the following citation: [3].

If the source of the element (e.g. script or image) is not trusted the policy will reject it on the browser’s side. Also alongside the whitelisted domains, a developer can define the protocols (or schemes as they are called) that are allowed for pulling content from the whitelisted domains.

Using CSP

Browsers that implement the CSP, expect to find an HTTP header in the response. That header is called Content-Security-Policy. Policies provided with this header are semicolon separated as we’ll see later on. Most reverse proxies provide the ability to add headers at will and this is how CSP is implemented by these web servers.

For example, for NGINX, one should add the following:

 add_header Content-Security-Policy "script-src 'self'"

Some Examples

Example 1

Content-Security-Policy: default-src 'self'

The above indicates to the browser that all content coming from the current domain is allowed, for all types of content. NOTE: This excludes subdomains.

Example 2

Content-Security-Policy: default-src 'self' *.trusted.com

Expanding on the previous example, here we allow trusted.com and all of its subdomains

Example 3

Content-Security-Policy: script-src 'self' https://cdnjs.cloudflare.com

A more real-world example, allows javascript from the current domain and a known CDN for pulling your angular / react js from.

Example 5

content-security-policy: 
script-src https://apis.google.com/_/streamwidgets/ 
...
report-uri https://mail.google.com/mail/cspreport;
object-src https://mail-attachment.googleusercontent.com/attachment/ script-src 'report-sample' 'unsafe-eval' 'nonce-gTWEiUr6jJYUSdaZ17xO8Q' 'unsafe-inline' 'strict-dynamic'; 
object-src 'none';
base-uri 'self';
...


The above is a CSP for gmail.com. The policy is quite loose for browsers that implement CSP2 and more strict for modern browsers that support CSP3.
For more information, read up on citation [3].

Before Production

CSP is meant to break things if not implemented correctly, for example, by default inline javascript in traditional <script> tags is not allowed. For this method to work, one has to provide:

script-src: 'unsafe-inline'

Additionally, custom event handlers and JavaScript: URLs are also banned by default. On another scenario, let’s say a developer adds another javascript dependency from another CDN that is not whitelisted but forgot to update the CSP. The script will be allowed in a local/development environment where CSP might be disabled, but fail to load on the production deployment.

Since CSP is hard to get right and we do not want to deploy such policies on production without testing them, CSP provides another header that allows such testing to occur. The header is called Content-Security-Policy-Report-Only and allows us to load all content without blocking anything, but instead report on CSP violations. This is harmless for any environment that deploys a CSP policy and allows us to debug on production.

Using the above header you can either see the errors in your browser’s console, or enable reporting.

Report-uri

On both Content-Security-Policy and Content-Security-Policy-Report-Only a directive can be used to tell the browser what to do on CSP violation. The directive contains a URL where the browser will send a POST request, containing all information about the violation that occurred [4].

Caveats and hurdles

Nowadays development is rapid, and most people deploy many times during the day, putting aside whether this is the right way of doing things, some times developers need to allow unsafe-inline scripts. If that is the case, we recommend going for the nonce-based route. All that is needed for this is to provide an unguessable nonce with the script tag as shown below:

Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='

This way, even if an adversary injects a script tag, they would have to guess the hash provided by the backend. Note that, the nonce gets generated in a per-request manner, otherwise it would be trivial for the adversary to make a request, find out what the nonce is and use it later on to attack the application.

As mentioned above, deploying CSP is hard [6], it needs maintenance and can be a headache for both developers and operators. Hence, a question arises, who is responsible to maintain the CSP? Developers? Operators? Security engineers? There is no clear answer as it concerns all three actors. Developers will have to decide what policy is needed for an application, as they will add and / or remove dependencies. Security engineers have to provide developers with the right information in order to help them make an educated decision and also review the CSP. Finally, operators might assist in monitoring CSP violation reports when deployed on production.

Relatively recent research has shown that CSP is nearly impossible to get right [5] and also proved that 94.72% of real-world CSP deployments could be bypassed. CSP 3 that is currently a working draft, contains new methods to implement CSP based on cryptographic nonces and not whitelisted domains. Some of the new directives are currently implemented by most browsers. One of them is strict-dynamic that says to the browser, trust only the following nonce (cryptographically secure hash) whether it is an inline or an external source.

One thing is for certain, CSP is another layer of security, and should only be considered as one. We shouldn’t rely only on CSP and deploy other measures to detect and fix the vulnerabilities although CSP can in some cases limit exploitation. So audit your codebase, fix issues and use CSP with caution.

[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#Browser_compatibility.
[2] https://cert.grnet.gr/el/cross-site-scripting-xss/
[3] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
[4] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only#Violation_report_syntax
[5] https://ai.google/research/pubs/pub45542.pdf
[6] https://uselesscsp.com/

Password policies

By | Policies | No Comments

Responsibilities of systems processing passwords

– Passwords must be prohibited from being displayed when entered.
– Passwords must never be stored in clear, readable format (encryption must always be used).
– Encrypted password hashes must never be accessible to unauthorized individuals.
– Where possible, salted hashes should be used for password encryption.

Password requirements

– At least eight (8) characters; using a combination of at least one character from each of the following four listed character types:
— uppercase letters (A-Z)
— lowercase letters (a-z)
— base 10 digits (0-9)
— non-alphanumeric (such as ` ~ ! @ # $ % ^ & * ( ) _ + – = { } | \ : ” ; ‘ < > ? , . / and space)
– Passwords should not match the username, or parts of the user’s full name, such as their first name.

Password Aging

– Passwords must be changed every ‘X’ months, where ‘X’ can be 6 months.
– At least four (4) characters must be changed when new passwords are created.
– New passwords must comply with the password requirements defined in the previous section.

** For admin users enforce a more strict password policy.

Read more: Password policies and guidelines, Password policies and best practices , Configuring Password Policies

Cross-Site Request Forgery (CSRF)

By | Terminology | No Comments

CSRF is an attack that tricks the victim into submitting a malicious request. It inherits the identity and privileges of the victim to perform an undesired function on the victim’s behalf. For most sites, browser requests automatically include any credentials associated with the site, such as the user’s session cookie, IP address, Windows domain credentials, and so forth. Therefore, if the user is currently authenticated to the site, the site will have no way to distinguish between the forged request sent by the victim and a legitimate request sent by the victim.

Read more: OWASP – CSRF, CSRF CWE

Same origin policy

By | Terminology | No Comments

An origin is defined as a combination of URI scheme, host name, and port number. Same Origin Policy prevents a web site’s scripts from accessing and interacting with scripts used on other sites. In other words, this policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page’s Document Object Model.

Cross-Origin Resource Sharing

The second technique for relaxing the same-origin policy is standardized under the name Cross-Origin Resource Sharing. This standard extends HTTP with a new Origin request header and a new Access-Control-Allow-Origin response header. It allows servers to use a header to explicitly list origins that may request a file or to use a wildcard and allow a file to be requested by any site.

Read more: Why is the same origin policy important?

Cross-site Scripting (XSS)

By | Terminology | No Comments

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.
Non-persistent XSS: These are usually the most common types. Typically these are within HTTP query parameters and are used by server-side scripts to parse and display a page of results for the user.
Persistent XSS: These are when the data from the attacker is actually saved on the server and then displayed to the user, mimicking a normal page.

Read more: OWASP – XSS, X-XSS-Protection