Skip to content

Commit

Permalink
Adding Mochitests for Taint Propagation
Browse files Browse the repository at this point in the history
  • Loading branch information
tmbrbr committed Oct 6, 2023
2 parents fc0b51f + 340d549 commit ba4420f
Show file tree
Hide file tree
Showing 52 changed files with 2,710 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ jobs:
if: success() || failure() # run this step even if previous step failed
with:
name: test-results
path: build/jstest_output.xml
path: build/jstest_output.xml
2 changes: 1 addition & 1 deletion dom/base/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3878,7 +3878,7 @@ void Element::SetInnerHTML(const nsAString& aInnerHTML,

void Element::GetOuterHTML(nsAString& aOuterHTML) {
GetMarkup(true, aOuterHTML);
MarkTaintOperation(aOuterHTML, "element.outerHTML");
MarkTaintOperation(aOuterHTML, "element.outerHTML");
}

void Element::SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError) {
Expand Down
6 changes: 3 additions & 3 deletions dom/base/Location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ void Location::SetProtocol(const nsAString& aProtocol,
return;
}

// TaintFox: location.protocol sink.
ReportTaintSink(aProtocol, "location.protocol");

nsAString::const_iterator start, end;
aProtocol.BeginReading(start);
aProtocol.EndReading(end);
Expand Down Expand Up @@ -527,9 +530,6 @@ void Location::SetProtocol(const nsAString& aProtocol,
return;
}

// TaintFox: location.protocol sink.
ReportTaintSink(aProtocol, "location.protocol");

SetURI(uri, aSubjectPrincipal, aRv);
}

Expand Down
4 changes: 4 additions & 0 deletions taint/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ SOURCES += [
'md5_utils.c',
'Taint.cpp'
]

TEST_DIRS += [
'test'
]
7 changes: 7 additions & 0 deletions taint/test/browser/browser.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[test_document.html]
[test_form_sources.html]
[test_location.html]
[test_location_sinks.html]
[test_sinks.html]
[test_taint.html]
[test_local_storage.html]
Empty file added taint/test/chrome/chrome.ini
Empty file.
9 changes: 9 additions & 0 deletions taint/test/mochitest/error_worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
this.onpush = function(event) {
var request = event.data.json();
if (request.type == "exception") {
throw new Error("Uncaught exception");
}
if (request.type == "rejection") {
event.waitUntil(Promise.reject(new Error("Unhandled rejection")));
}
};
8 changes: 8 additions & 0 deletions taint/test/mochitest/file_websocket_wsh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from mod_pywebsocket import msgutil

def web_socket_do_extra_handshake(request):
pass

def web_socket_transfer_data(request):
resp = "Test"
msgutil.send_message(request, resp)
24 changes: 24 additions & 0 deletions taint/test/mochitest/frame.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<script>

function waitOnWorkerMessage(type) {
return new Promise(function(res, rej) {
function onMessage(e) {
if (e.data.type == type) {
navigator.serviceWorker.removeEventListener("message", onMessage);
(e.data.okay == "yes" ? res : rej)(e.data);
}
}
navigator.serviceWorker.addEventListener("message", onMessage);
});
}

</script>
</head>
<body>

</body>
</html>
90 changes: 90 additions & 0 deletions taint/test/mochitest/lifetime_worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
var state = "from_scope";
var resolvePromiseCallback;

self.onfetch = function(event) {
if (event.request.url.includes("lifetime_frame.html")) {
event.respondWith(new Response("iframe_lifetime"));
return;
}

var currentState = state;
event.waitUntil(
self.clients.matchAll().then(clients => {
clients.forEach(client => {
client.postMessage({ type: "fetch", state: currentState });
});
})
);

if (event.request.url.includes("update")) {
state = "update";
} else if (event.request.url.includes("wait")) {
event.respondWith(
new Promise(function(res, rej) {
if (resolvePromiseCallback) {
dump("ERROR: service worker was already waiting on a promise.\n");
}
resolvePromiseCallback = function() {
res(new Response("resolve_respondWithPromise"));
};
})
);
state = "wait";
} else if (event.request.url.includes("release")) {
state = "release";
resolvePromise();
}
};

function resolvePromise() {
if (resolvePromiseCallback === undefined || resolvePromiseCallback == null) {
dump("ERROR: wait promise was not set.\n");
return;
}
resolvePromiseCallback();
resolvePromiseCallback = null;
}

self.onmessage = function(event) {
var lastState = state;
state = event.data;
if (state === "wait") {
event.waitUntil(
new Promise(function(res, rej) {
if (resolvePromiseCallback) {
dump("ERROR: service worker was already waiting on a promise.\n");
}
resolvePromiseCallback = res;
})
);
} else if (state === "release") {
resolvePromise();
}
event.source.postMessage({ type: "message", state: lastState });
};

self.onpush = function(event) {
var pushResolve;
event.waitUntil(
new Promise(function(resolve) {
pushResolve = resolve;
})
);

// FIXME(catalinb): push message carry no data. So we assume the only
// push message we get is "wait"
self.clients.matchAll().then(function(client) {
if (!client.length) {
dump("ERROR: no clients to send the response to.\n");
}

client[0].postMessage({ type: "push", state });

state = "wait";
if (resolvePromiseCallback) {
dump("ERROR: service worker was already waiting on a promise.\n");
} else {
resolvePromiseCallback = pushResolve;
}
});
};
46 changes: 46 additions & 0 deletions taint/test/mochitest/mochitest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[DEFAULT]
support-files =
file_websocket_wsh.py
mockpushserviceparent.js
webpush.js
worker.js
frame.html
test_utils.js
error_worker.js
lifetime_worker.js
mock_worker.js
[test_document.html]
[test_form_sources.html]
[test_location.html]
[test_location_sinks.html]
[test_sinks.html]
[test_taint.html]
[test_local_storage.html]
[test_local_storage_sinks.html]
[test_session_storage.html]
[test_session_storage_sinks.html]
[test_cookie.html]
[test_cookie_sinks.html]
[test_javascript_sinks.html]
[test_url_search_params.html]
[test_window.html]
[test_xml_http_request_response.html]
[test_xml_http_request.html]
[test_window_message_event.html]
[test_navigator.html]
[test_inner_html.html]
[test_href_sinks.html]
[test_script_sinks.html]
[test_json_conversion.html]
[test_object.html]
[test_dom_parser.html]
[test_element.html]
[test_iframe_sinks.html]
[test_fetch.html]
[test_websocket_sinks.html]
[test_function_ctor.html]
[test_websocket.html]
[test_push.html]
scheme = https
[test_url_object.html]
[test_message_event.html]
11 changes: 11 additions & 0 deletions taint/test/mochitest/mock_worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
onconnect = function (event) {

const port = event.ports[0];

port.onmessage = function (event) {
const result = event.data;
port.postMessage(result);
};

port.start();
}
Loading

0 comments on commit ba4420f

Please sign in to comment.