Reduce the DOM XSS attack surface of your application.
Safe and secure
Why should you care?
La secuencia de comandos de sitios cruzados basada en DOM (DOM XSS) es una de las vulnerabilidades de seguridad Web más comunes, y es muy fácil introducirla en su aplicación. Trust types
Brindarle las herramientas para escribir, revisar la seguridad y mantener aplicaciones libres de vulnerabilidades DOM XSS al hacer que las peligrosas funciones de la API web sean seguras de manera predeterminada. Los tipos de confianza son compatibles con Chrome 83 y polyfill está disponible para otros browsers. Watch Browser compatibility for up-to-date information on cross-browser compatibility.
Key term:
Las secuencias de comandos entre sitios basadas en DOM ocurren cuando los datos de un Username controlan
source (como el nombre de usuario o la Url de redireccionamiento tomada del fragmento de URL) alcanza un sink, which is a function like eval ()
or a property creator like
.innerHTML
, que puede ejecutar código JavaScript arbitrario.
Background
For many years DOM XSS
it has been one of the most frequent and dangerous web security vulnerabilities.
Hay dos grupos distintos de secuencias de comandos entre sitios. Algunas vulnerabilidades XSS son causadas por el código del lado del server que crea de manera insegura el código HTML que forma el sitio web. Otros tienen una causa raíz en el client, donde el código JavaScript llama a funciones peligrosas con contents controlado por el usuario.
TO avoid server-side XSSPlease do not generate HTML by string concatenation and use safe template libraries with contextual automatic escape. Use a Nonce-based content security policy for additional mitigation against errors that inevitably occur.
Ahora, un browser también puede ayudar a prevenir los XSS del lado del cliente (también conocidos como basados en DOM) con Trust types.
Introduction to the API
Trust types work by blocking the following risk sink functions. You may already recognize some of them, such as browser providers and web frames is already distancing you from using these features for security reasons.
-
Script manipulation:
and configure the text content of
elements.
-
Generating HTML from a string:
innerHTML
,outerHTML
,insertAdjacentHTML
,
,
document.write
,document.writeln
andDOMParser.parseFromString
-
Compiling JavaScript code at runtime:
eval
,setTimeout
,setInterval
,new Function ()
Trust types require that you process the data before passing it to the above receiver functions. Just using a string will fail, as the browser doesn't know if the data is trustworthy:
No
anElement.innerHTML = location.href;
With Trusted Types enabled, the browser launches a Typing error and avoid using a DOM XSS sink with a string.
To indicate that the data was processed securely, create a special object: a trust type.
Do
anElement.innerHTML = aTrustedHTML;
With trust types enabled, the browser accepts a TrustedHTML
object for listeners that expect HTML snippets. There's also TrustedScript
and TrustedScriptURL
Objects for other sensitive sinks.
Trust types greatly reduce the DOM XSS attack surface
of your application. It simplifies security checks and enables you to enforce type-based security checks that are performed when compiling, linking, or packaging your code at runtime, in the browser.
How to use trust types
Prepare for content security policy violation reports
Puede implementar un recopilador de informes (como el de Open Source go-csp-collector), or use one of the commercial equivalents. You can also debug violations in the browser:
window.addEventListener('securitypolicyviolation',
console.error.bind(console));
Agregue el siguiente encabezado de respuesta HTTP a los documentos que desea migrar a tipos de confianza.
Content-Security-Policy-Report-Only: require-trusted-types-for 'script'; report-uri //my-csp-endpoint.example
Now all violations are reported to //my-csp-endpoint.example
, but the website is still working. The next section explains how //my-csp-endpoint.example
jobs.
Caution:
Trust types are only available in safe context
how HTTPS and localhost
.
Identify trust type breaches
From now on, whenever Trusted Types detects a violation, a report will be sent to a report-uri
. For example, when your application passes a string to innerHTML
, the browser sends the following report:
{
"csp-report": {
"document-uri": "https://my.url.example",
"violated-directive": "require-trusted-types-for",
"disposition": "report",
"blocked-uri": "trusted-types-sink",
"line-number": 39,
"column-number": 12,
"source-file": "https://my.url.example/script.js",
"status-code": 0,
"script-sample": "Element innerHTML <img src=x"
}
}
This says that in https://my.url.example/script.js
on line 39 innerHTML
was called with the string that begins with <img src=x
. This information should help you narrow down which parts of your code may be introducing DOM XSS and should change.
Most violations like this can also be detected by running a code linter or static code checkers
in your code base. This helps to quickly identify a large number of violations.
With that said, you should also look at CSP violations as they are triggered when non-compliant code executes.
Fix the infractions
There are a couple of options to correct a trust type violation. You can remove the offending code, use a library, create a trust type policy, or, as a last resort, create a default policy.
Rewrite the offending code
¿Quizás la funcionalidad no conforme ya no be necesaria o se pueda reescribir de una manera moderna sin usar las funciones propensas a errores?
No
he.innerHTML = '<img src=xyz.jpg>';
Do
he.textContent = '';
const img = document.createElement('img');
img.src = 'xyz.jpg';
he.appendChild(img);
Use a library
Some libraries already generate trust types that you can pass to receiver functions. For example, you can use
DOMPurify to sanitize a snippet of HTML, removing XSS payloads.
import DOMPurify desde 'dompurify';
he.innerHTML = DOMPurify.sanitize(html, {RETURN_TRUSTED_TYPE: true);
DOMPurify supports trust types and it will return sanitized HTML wrapped in a TrustedHTML
object so that the browser does not generate a violation.
Caution:
If the sanitization logic in DOMPurify is buggy, your application may still have a DOM XSS vulnerability. Trust types force you to process a value somehow, but do not define yet what the exact processing rules are and if they are secure.
Create a trust type policy
Sometimes it is not possible to remove the functionality and there is no library to sanitize the value and create a Trust Type for you. In those cases, create a Trusted Type object yourself.
For that, first create a politics. Policies are factories of trust types that impose certain security rules on their entry:
if (window.trustedTypes && trustedTypes.createPolicy) {
const escapeHTMLPolicy = trustedTypes.createPolicy('myEscapePolicy', {
createHTML: string => string.replace(/</g, '<')
});
}
This code creates a policy called myEscapePolicy
what can produce TrustedHTML
objects through their createHTML ()
function. Defined rules will escape HTML <
characters to avoid creating new HTML elements.
Use the policy like this:
const escaped = escapeHTMLPolicy.createHTML('<img src=x onerror=alert(1)>');
console.log(escaped instanceof TrustedHTML);
he.innerHTML = escaped;
While the JavaScript function happened to trustedTypes.createPolicy ()
how
createHTML ()
returns a string, createPolicy ()
returns a policy object that wraps the return value in a correct type, in this case TrustedHTML
.
Use a default policy
Sometimes the offending code cannot be changed. For example, this is the case if you are loading a third-party library from a CDN. In that case, use a
default policy:
if (window.trustedTypes && trustedTypes.createPolicy) {
trustedTypes.createPolicy('default', {
createHTML: (string, sink) => DOMPurify.sanitize(string, {RETURN_TRUSTED_TYPE: true});
});
}
The policy with name default
it is used whenever a string is used in a receiver that only accepts Trusted Type.
Use the default policy sparingly and prefer to refactor your application to use regular policies instead. Doing so encourages designs where security rules are close to the data they process, where you have the most context to properly sanitize the value.
Change to enforce the Content Security Policy
When your application is no longer breaching, you can start enforcing the trust types:
Content-Security-Policy: require-trusted-types-for 'script'; report-uri //my-csp-endpoint.example
Voila! Now, no matter how complex your web application is, the only thing that can introduce a DOM XSS vulnerability is the code in one of your policies, and you can block it even more if limit policy making.
Other readings