Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Latest commit

 

History

History
160 lines (110 loc) · 15.7 KB

File metadata and controls

160 lines (110 loc) · 15.7 KB

HTML5 Security Cheat Sheet

Introduction

The following cheat sheet serves as a guide for implementing HTML 5 in a secure fashion.

Communication APIs

Web Messaging

Web Messaging (also known as Cross Domain Messaging) provides a means of messaging between documents from different origins in a way that is generally safer than the multiple hacks used in the past to accomplish this task. However, there are still some recommendations to keep in mind:

  • When posting a message, explicitly state the expected origin as the second argument to postMessage rather than * in order to prevent sending the message to an unknown origin after a redirect or some other means of the target window's origin changing.
  • The receiving page should always:
    • Check the origin attribute of the sender to verify the data is originating from the expected location.
    • Perform input validation on the data attribute of the event to ensure that it's in the desired format.
  • Don't assume you have control over the data attribute. A single Cross Site Scripting flaw in the sending page allows an attacker to send messages of any given format.
  • Both pages should only interpret the exchanged messages as data. Never evaluate passed messages as code (e.g. via eval()) or insert it to a page DOM (e.g. via innerHTML), as that would create a DOM-based XSS vulnerability. For more information see DOM based XSS Prevention Cheat Sheet.
  • To assign the data value to an element, instead of using a insecure method like element.innerHTML=data;, use the safer option: element.textContent=data;
  • Check the origin properly exactly to match the FQDN(s) you expect. Note that the following code: if(message.origin.indexOf(".owasp.org")!=-1) { /* ... */ } is very insecure and will not have the desired behavior as owasp.org.attacker.com will match.
  • If you need to embed external content/untrusted gadgets and allow user-controlled scripts (which is highly discouraged), please check the information on sandboxed frames.

Cross Origin Resource Sharing

  • Validate URLs passed to XMLHttpRequest.open. Current browsers allow these URLs to be cross domain; this behavior can lead to code injection by a remote attacker. Pay extra attention to absolute URLs.
  • Ensure that URLs responding with Access-Control-Allow-Origin: * do not include any sensitive content or information that might aid attacker in further attacks. Use the Access-Control-Allow-Origin header only on chosen URLs that need to be accessed cross-domain. Don't use the header for the whole domain.
  • Allow only selected, trusted domains in the Access-Control-Allow-Origin header. Prefer allowing specific domains over blocking or allowing any domain (do not use * wildcard nor blindly return the Origin header content without any checks).
  • Keep in mind that CORS does not prevent the requested data from going to an unauthorized location. It's still important for the server to perform usual CSRF prevention.
  • While the Fetch Standard recommends a pre-flight request with the OPTIONS verb, current implementations might not perform this request, so it's important that "ordinary" (GET and POST) requests perform any access control necessary.
  • Discard requests received over plain HTTP with HTTPS origins to prevent mixed content bugs.
  • Don't rely only on the Origin header for Access Control checks. Browser always sends this header in CORS requests, but may be spoofed outside the browser. Application-level protocols should be used to protect sensitive data.

WebSockets

Server-Sent Events

  • Validate URLs passed to the EventSource constructor, even though only same-origin URLs are allowed.
  • As mentioned before, process the messages (event.data) as data and never evaluate the content as HTML or script code.
  • Always check the origin attribute of the message (event.origin) to ensure the message is coming from a trusted domain. Use an allow-list approach.

Storage APIs

Local Storage

  • Also known as Offline Storage, Web Storage. Underlying storage mechanism may vary from one user agent to the next. In other words, any authentication your application requires can be bypassed by a user with local privileges to the machine on which the data is stored. Therefore, it's recommended to avoid storing any sensitive information in local storage where authentication would be assumed.
  • Due to the browser's security guarantees it is appropriate to use local storage where access to the data is not assuming authentication or authorization.
  • Use the object sessionStorage instead of localStorage if persistent storage is not needed. sessionStorage object is available only to that window/tab until the window is closed.
  • A single Cross Site Scripting can be used to steal all the data in these objects, so again it's recommended not to store sensitive information in local storage.
  • A single Cross Site Scripting can be used to load malicious data into these objects too, so don't consider objects in these to be trusted.
  • Pay extra attention to "localStorage.getItem" and "setItem" calls implemented in HTML5 page. It helps in detecting when developers build solutions that put sensitive information in local storage, which can be a severe risk if authentication or authorization to that data is incorrectly assumed.
  • Do not store session identifiers in local storage as the data is always accessible by JavaScript. Cookies can mitigate this risk using the httpOnly flag.
  • There is no way to restrict the visibility of an object to a specific path like with the attribute path of HTTP Cookies, every object is shared within an origin and protected with the Same Origin Policy. Avoid hosting multiple applications on the same origin, all of them would share the same localStorage object, use different subdomains instead.

Client-side databases

  • Web SQL Database was deprecated by the W3C in 2010 and is removed from all major browsers: Chromium dropped support in version 119 (October 2023) and Safari/Firefox never shipped it for third-party origins. Do not use Web SQL. If you specifically need an SQL interface in the browser, prefer running an embedded engine such as the official SQLite WebAssembly build (sqlite-wasm), backed by IndexedDB or the Origin Private File System (OPFS) for persistence.
  • The current standard for client-side structured storage is IndexedDB, a transactional key-value store that has been a W3C Recommendation since 2015 and is supported in all evergreen browsers.
  • Underlying storage mechanisms vary across user agents and operating systems. A user (or any process running with that user's privileges, including malware) with read access to the browser profile directory on disk can read or modify the stored data, so do not assume client-side storage provides confidentiality. Do not store session tokens, credentials, or other secrets in IndexedDB unless they are encrypted with a key that is not itself recoverable from the browser (for example, derived from a user-supplied passphrase that is never persisted, or wrapped by a non-extractable Web Crypto CryptoKey).
  • A single Cross-Site Scripting vulnerability can read or write any data in IndexedDB; treat its contents as untrusted input on read.
  • Apply the same input validation and output encoding rules to data coming from IndexedDB as you would to data coming from the network.

Geolocation

  • The Geolocation API requires that user agents ask for the user's permission before calculating location. Whether or how this decision is remembered varies from browser to browser. Some user agents require the user to visit the page again in order to turn off the ability to get the user's location without asking, so for privacy reasons, it's recommended to require user input before calling getCurrentPosition or watchPosition.

Web Workers

  • Web Workers are allowed to use XMLHttpRequest object to perform in-domain and Cross Origin Resource Sharing requests. See relevant section of this Cheat Sheet to ensure CORS security.
  • While Web Workers don't have access to DOM of the calling page, malicious Web Workers can use excessive CPU for computation, leading to Denial of Service condition or abuse Cross Origin Resource Sharing for further exploitation. Ensure code in all Web Workers scripts is not malevolent. Don't allow creating Web Worker scripts from user supplied input.
  • Validate messages exchanged with a Web Worker. Do not try to exchange snippets of JavaScript for evaluation e.g. via eval() as that could introduce a DOM Based XSS vulnerability.

Tabnabbing

Attack is described in detail in this article.

To summarize, it's the capacity to act on parent page's content or location from a newly opened page via the back link exposed by the opener JavaScript object instance.

It applies to an HTML link or a JavaScript window.open function using the attribute/instruction target to specify a target loading location that does not replace the current location and then makes the current window/tab available.

To prevent this issue, the following actions are available:

Cut the back link between the parent and the child pages:

  • For HTML links:
    • To cut this back link, add the attribute rel="noopener" on the tag used to create the link from the parent page to the child page. This attribute value cuts the link, but depending on the browser, lets referrer information be present in the request to the child page.
    • To also remove the referrer information use this attribute value: rel="noopener noreferrer".
  • For the JavaScript window.open function, add the values noopener,noreferrer in the windowFeatures parameter of the window.open function.

As the behavior using the elements above is different between the browsers, either use an HTML link or JavaScript to open a window (or tab), then use this configuration to maximize the cross supports:

  • For HTML links, add the attribute rel="noopener noreferrer" to every link.
  • For JavaScript, use this function to open a window (or tab):
function openPopup(url, name, windowFeatures){
  //Open the popup and set the opener and referrer policy instruction
  var newWindow = window.open(url, name, 'noopener,noreferrer,' + windowFeatures);
  //Reset the opener link
  newWindow.opener = null;
}
  • Add the HTTP response header Referrer-Policy: no-referrer to every HTTP response sent by the application (Header Referrer-Policy information. This configuration will ensure that no referrer information is sent along with requests from the page.

Compatibility matrix:

Sandboxed frames

  • Use the sandbox attribute of an iframe for untrusted content.
  • The sandbox attribute of an iframe enables restrictions on content within an iframe. The following restrictions are active when the sandbox attribute is set:
    1. All markup is treated as being from a unique origin.
    2. All forms and scripts are disabled.
    3. All links are prevented from targeting other browsing contexts.
    4. All features that trigger automatically are blocked.
    5. All plugins are disabled.

It is possible to have a fine-grained control over iframe capabilities using the value of the sandbox attribute.

  • In old versions of user agents where this feature is not supported, this attribute will be ignored. Use this feature as an additional layer of protection or check if the browser supports sandboxed frames and only show the untrusted content if supported.
  • Apart from this attribute, to prevent Clickjacking attacks and unsolicited framing it is encouraged to use the header X-Frame-Options which supports the deny and same-origin values. Other solutions like framebusting if(window!==window.top) { window.top.location=location;} are not recommended.

Credential and Personally Identifiable Information (PII) Input hints

  • Protect the input values from being cached by the browser.

Access a financial account from a public computer. Even though one is logged-off, the next person who uses the machine can log-in because the browser autocomplete functionality. To mitigate this, we tell the input fields not to assist in any way.

<input type="text" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off"></input>

Text areas and input fields for PII (name, email, address, phone number) and login credentials (username, password) should be prevented from being stored in the browser. Use these HTML5 attributes to prevent the browser from storing PII from your form:

  • spellcheck="false"
  • autocomplete="off"
  • autocorrect="off"
  • autocapitalize="off"

Offline Applications

  • The HTML5 Application Cache (<html manifest="..."> and .appcache files) has been removed from all major browsers (Firefox 85, Chrome 93). Do not use it for new applications and migrate any remaining usage to Service Workers with the Cache API.
  • Service Workers run on a separate, scriptable thread and intercept network requests for the registered scope. Because they can transparently serve cached responses, they have a significant security impact:
    • Only register Service Workers from your own origin and only serve the worker script over HTTPS with a long-cache-busting filename (e.g. sw.<hash>.js).
    • Validate that the scope of the Service Worker is restricted (use the scope option or the Service-Worker-Allowed response header) so a compromised worker cannot intercept unrelated paths.
    • A malicious or compromised Service Worker can intercept every request from its scope until it is unregistered or the cache TTL expires; have a documented kill-switch (e.g. an unregister flow you can ship in a hotfix).
    • Do not cache responses that contain sensitive data. Send Cache-Control: no-store on those responses so the Cache API will not retain them.

Progressive Enhancements and Graceful Degradation Risks

  • The best practice now is to determine the capabilities that a browser supports and augment with substitutes only for capabilities that are not directly supported. Do not fall back to obsolete browser plugins — Adobe Flash Player reached end-of-life on 31 December 2020 and is removed from all browsers; Java applets, Silverlight, and ActiveX are likewise unsupported. Native HTML5 (<video>, <audio>, <canvas>, WebAssembly) covers these legacy use cases.

HTTP Headers to enhance security

Consult the project OWASP Secure Headers in order to obtains the list of HTTP security headers that an application should use to enable defenses at browser level.