DOMtegrity is a JavaScript-based framework to ensure web page's integrity. The developer should embed this source code inside ≺script≻ tag and place it the first element of the web page before any other HTML tags.

Detailed description of the protocol here.

Source Code

Attack Scenarios

In orer to show the existing threats of malicious extensions, we have designed two attacks on real-world online banking websites (Barclays and HSBC online banking). You can find more about the attacks here.

Email us


In this project, we address an important real-world problem: how to ensure the integrity of delivering web content in the presence of man-in-the-browser (MITB) attacks by malicious web extensions?

Browser Extensions have powerful privileges to manipulate a user's view of a web page by modifying the underlying Document Object Model (DOM). To demonstrate the threat, we implement two attacks on real-world online banking websites (HSBC and Barclays) and show how a malicious extension can covertly compromise the user's bank accounts.

To address this problem, we propose a cryptographic protocol called DOMtegrity to ensure the end-to-end integrity of a web page's DOM from delivering at a server to the final display in a client's browser. Our solution works by exploiting subtle differences between browser extensions and in-line JavaScript code in terms of their rights to access Websocket channels, as well as leveraging the latest Web Crypto API support added in modern browsers. We show how DOMtegrity prevents the earlier attacks and a whole range of man-in-the-browser attacks that involve maliciously changing the DOM structure of a web page. We conduct extensive experiments on more than 14,000 real-world extensions to evaluate the effectiveness of DOMtegrity and its compatibility with existing extensions. To the best of our knowledge, DOMtegrity is the first solution that protects the integrity of DOM against malicious extensions without needing to modify the existing browser architecture or requiring extra hardware.


In the following demonstration, we assume that a malicious extension is already installed on a client's browser. This can be done through disguising malicious extensions as legitimate browser extensions, using Trojans to install such extensions, missing plug-in attacks, or purchasing popular extensions and then adding malicious code during updates. In both attacks, the web pages that are presented to the victim are from the genuine banking websites via HTTPS.

Attack on Second Factor Authenticatin Scheme - HSBC Attack

The first attack shows how a malicious extension can easily bypass the two-factor authentication that is adopted by major banks, including HSBC. In this attack, the extension intercepts the victim's authentication credentials (i.e., login details), sends them to a remote attacker and redirects the user to a false maintenance page. Depending on the security policy of the banking web site, this authentication could involve a regular password and an additional one-time password (OTP) as a second factor which is either sent to the user's mobile phone as an SMS or locally generated using a dedicated device (i.e., a Chip Authentication Program (CAP) device) provided by the bank.

We developed a proof-of-concept attack that targets the HSBC online banking web pages. To authenticate their clients, HSBC uses a password-based user authentication augmented with an OTP generated by a dedicated device, the HSBC Physical Secure Key.

Our attack works as follows:

Attack on Full Transaction Authorization Scheme - Barclays Attack

The second attack shows how a malicious extension can defeat transaction-specific user authorization, which is added by many banks such as Barclays as an extra layer of security on top of two-factor authentication. Here, when an already authenticated user requests a transaction, she is required to provide a transaction-specific authorization code which is either sent to the user out of band or generated by a dedicated device upon unique transaction-specific input. This transaction authentication is designed to prevent modification of transaction data (e.g., recipient and amount) by man-in-the-browser attackers. Barclays uses the strongest form of transaction authentication (the so-called full transaction authentication in which the unique transaction authorization code (i.e., the transaction-specific OTP) is cryptographically bound to the transaction data. The authorization code is calculated by a dedicated device provided by Barclays called PINsentry. Alternatively, the user can use the functionally equivalent Mobile PINsentry application on her smartphone. When a transaction is requested through Internet banking, the user is required to manually enter the transaction details, including the payee account number and the amount, on PINsentry (or Mobile PINsentry) and then enter the PINsentry produced authorization code on the internet banking web page.

In the following we show how a malicious extension can defeat this security measure by combining social engineering and DOM modifications. The attack works as follows:

In this attack, the attacker's bank account may eventually be discovered by checking the victim's bank transaction records. However, this is not an issue for the attacker since he only needs to prevent the discovery of the fraud for some short timescale in which the funds can be withdrawn from the account.

The key issue that we were able to exploit is that PINsentry prompts the user for two pieces of transaction information: REF and Amount. The only information about what REF means is present on the website, which can be modified by the extension. We have responsibly disclosed our attack to Barclays and since then Mobile PINsentry has been updated and the prompt on the app has been fixed to explicitly ask the user for the payee's account number instead of a REF number.


DOMtegrity is designed to enable the server to detect any unexpected modification of the DOM by extensions when the web page is rendered in the browser. The underlying idea is that DOMtegrity securely records all the modifications made to the web page DOM until the final rendering of the page and then securely communicates the recorded modifications to the server. The server is then in a position to decide whether or not the client's browser has parsed the page as the server expected.

DOMtegrity is implemented as a JavaScript program, called pid.js, which is then embedded as an in-line script (within a ≺script≻ tag) in the web page that the server wishes to protect. This in-line inclusion is necessary since extensions are not able to restrict the execution of in-line web page scripts, whereas they can block loading external script files. For the in-line Javascript to work, we assume that JavaScript execution is not disabled in the browser.

Since DOMtegrity is to record all modifications to the DOM, it is essential that pid.js is placed at the start of the page source code and before all other HTML tags. Since parsing the web page in browser proceeds in the order that tags are placed in the page source code, placing pid.js at the start of the page ensures that recording changes in the DOM starts immediately as the browser starts parsing the page.

The isolated worlds principle guarantees that DOMtegrity's recording of modifications in DOM cannot be tampered with by any extension. When executed, pid.js creates an on-the-fly DOM property (also called a DOM expando) named which implements the DOMtegrity functions within a domain isolated from any extension.

The extension's inability to access Websocket communication established by DOMtegrity provides assurance on the integrity of the communication between pid.js and the server. The in-line script pid.js establishes a Websocket with the server and this Websocket is used as a secure channel to convey a secret key which is later used to authenticate the DOM modifications that records. We should emphasize that although an extension has extensive access to HTTP(S) communications, it can only access the Websockets that are established by the same extension.

DOMtegrity runs in three stages:

  1. Initialization: This stage begins as the browser starts parsing the web page. In this stage, the required setup for DOMtegrity is carried out as: Open Websocket and Request Key from server, Define DOM Mutation Observer, Stop Event Propagation, Define DOM Expando (as shown in the figure below.)
  2. Recording: After initialization, DOMtegrity enters a persistent passive mode and records all DOM mutations through the mutation observer.
  3. Verification: a page identifier (PID) containing the recorded changes in the DOM is generated. The stage starts when the function is called. This is the only public expando function and should be called when the client ``returns'' the form, e.g., by clicking a ``submit'' button. This stage uses Web Crypto API.
We assume the web page is served over HTTPS. The client is identified by the TLS session ID.

How DOMtegrity Prevents Attacks

Full security analysis of DOmtegrity and how it protects DOM from malicious modifications are presented in our  full paper

We argued DOMtegrity is protected against the following attacks: impersonation attacks, malicious attempts to influence its execution, eavesdropping the secure channel by extensions, pollution of JavaScript global variables via monkey patching, and more importently, the new capability added from Chrome v.58 to enable partial access to webSocket channels.