geocar / firewall.js

firewall.js creates an `<iframe>` that blocks networking and downloading

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

firewall.js creates an <iframe> that blocks networking and downloading.

var x = document.createElement("iframe");
document.body.appendChild(x);

var f = FirewallJS(x);
f.onblock = function(e) {
  console.log("Blocked access to:" + e.data);
};
f.load("<script>new Image().src='http://www.google.com/'</script>")

firewall.js is very new and incomplete: There are a lot of ways that JavaScript can be used to perform a network request, a lot of different subtly incompatible web browsers, and there's only about 30 test vectors at the moment, covering:

Ideally, a firewalled script will not be able to detect firewall.js

Suggestions and contributions are welcome.

Whitelist/Blacklist

An alternative to the "block all" default is a whitelist/blacklist mode.

var f = FirewallJS(x);
f.whitelist([ "http://good.example.com" ]);

will permit resources on good.example.com while:

var f = FirewallJS(x);
f.blacklist([ "http://evil.example.com" ]);
f.whitelist([ "http://*.example.com" ]);

will permit resources on good.example.com and whatever.example.com but not evil.example.com.

The blacklist and whitelist (if used) must be supplied before loading the content.

Monitor/Snitch Mode

Another alternative mode is to simply monitor/log all of the URL requests instead of attempting to block them.

var f = FirewallJS(x);
f.monitor(true);

Limitations

Safari can't intercept changes to innerHTML and element attributes, so a MutationObserver is used instead.

This means that network operations might not be blocked, although at least they can be detected and the iframe shutdown.

Building

Pre-flight

Node.JS is required to build the script and its test cases.

npm install

Development

To build firewall.min.js and tests.html run:

npm run build

Contributing

Tests

Tests need to produce network activity; a full-featured test will send a signal to the test system. On Google Chrome, we can reliably detect network activity even if we can't block it, however if your test only works on another browser, you may need to add some instrumentation:

  • parent.postMessage("fail",'*') if you have (or believe you have) performed network activity
  • parent.postMessage("pass",'*') if you are not performing network activity
  • parent.postMessage("block",'*') if you can detect (e.g. with an exception) that network activity has not occurred

If you cannot "detect" network activity, but can manually verify it (by using developer tools or tcpdump), mark as failed after the critical command -- using setTimeout and a small delay if necessary.

Look at sendbeacon.js, image.js and xmlhttpreqest.js for some simple examples, and a3.js for a more complex one.

After every change, rebuild the test system with:

npm run build

then verify the test by loading tests.html in a web browser. Note you can load a specific test by opening tests.html#testname e.g. tests.html#style will load tests/style.js.

Anti-Test

An Anti-Test will make sure that a test isn't blocked. If you have example code that should work but doesn't with firewall.js, you can contribute an Anti-Test to prevent further regressions.

  • parent.postMessage("anti",'*')

This should be done first. Look at anti_a.js for an example.

Firewall

The firewall API is in firewall.js. It's responsible for getting the payload into the iframe, and interpreting errors.

The payload is in firewall/ and are assembled with the firewall API into firewall.min.js using build.js. webpack is used for dependency tracking, and uglifyJS is used to minimise the chunks. Any module that doesn't define module.exports is considered an "entry point" and will be loaded automatically, so to have a module demand-loaded late for its side effects, you must set module.exports to something.

Licensing

firewall.js, and its product firewall.min.js are redistributable under the LGPL v3 or any later version, and for the avoidance of doubt and confusion, are derived from the tests.

The intention is: if you use firewall.js in your own product, you are not required to make available the source code to your product unless you introduce the ability to protect against a new attack vector.

About

firewall.js creates an `<iframe>` that blocks networking and downloading


Languages

Language:JavaScript 94.3%Language:HTML 5.7%