Skip to content

Cross Boundary Dataflows

jackfromeast edited this page Jun 9, 2024 · 2 revisions

In this document, we answer the following questions:

  1. What kinds of cross-boundary dataflows can TheHulk handle?
  2. How do we handle the cross-boundary dataflows?

What are the Cross-Boundary Dataflows?

In client-side JavaScript execution, we have identified that JavaScript values may be passed to other components, such as the DOM, which are no longer processed by V8 or stored on the V8 heap. When cross-bounary dataflow occurs, usually through API calls, our wrapped value need to be stripped before passing it to the APIs. However, to maintain its stored taint or symbolic information, we needs special handling of them.

There are two types of cross-boundary dataflows based on whether the data will be stored outside the V8 heap.

For example, in the following code snippet (Case One), the function exported from wasmInstance is seen as an external party since Jalangi2 cannot instrument functions written in WebAssembly. To handle this, we can create a specific rule for the processToken function and apply it during the function call. Most of the methods installed on built-in objects fall into this category, as the methods themselves are written in C++ or Assembly language. However, these methods return immediately to the JavaScript world as the return value of the method call. Therefore, to handle these kinds of cross-boundary dataflows, we create rules for them. (TODO: Replace this case one as the processToken function looks like a user-written function.)

// Case One
let wasmBinary = new Uint8Array([...]);
let wasmModule = new WebAssembly.Module(wasmBinary);
let wasmInstance = new WebAssembly.Instance(wasmModule, {});

let userToken = "abc123";
let result = wasmInstance.exports.processToken(userToken);
let processedToken = result;

However, in the following code snippet case two, in the JavaScript string HelloWorld will be saved in the DOM nodes. Before setting it to the .innerText property of a DOM node, any wrapped value (e.g., the userInput variable) should be stripped, and the passed variable should be of type String. If not handled properly, when the value is retrieved back from the DOM nodes, we will lose its taint propagation from userInput to fromUserInput.

// Case Two
let userInput = "HelloWorld";
document.getElementById("greeting").innerText = userInput;
let fromUserInput = document.getElementById("greeting").innerText;

Clone this wiki locally