Package Exports
- otiluke/browser/ca/index.js
- otiluke/browser/proxy
- otiluke/node
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (otiluke) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Otiluke 
Toolbox for deploying JavaScript code transformers written in JavaScript themselves on node and browsers.
Virus Interface
In Otiluke, code transformers should adhere to the virus interface. A virus is a function which receives an Antena (isomorphic http client) as well as a mapping of arguments entered by the user and should asynchronously return a code transformation function. A virus module is a commonjs module exporting a virus function. For instance, the virus module below creates a websocket with a path defined by the user; later this websocket is used to communicate the sources of the script being executed.
module.exports = (antena, argm, callback) => {
const websocket = antena.WebSocket(argm["websocket-path"]);
websocket.onerror = () => {
callback(new Error("Connection error"));
};
websocket.onopen = () => {
websocket.onerror = null;
callback(null, (script, source) => {
websocket.send(source);
return script;
});
};
};
Calling context of virus functions:
virus(antena, argm, (error, transform) => { ... });
antena :: antena.Antena
: Isomorphic http client.argm :: {string}
: A mapping of user-defined arguments.error :: Error
script2 = transform(script1, source)
script1 :: string
: The original script.source :: string
Forotiluke/node
it is an absolute path to a node module. Forotiluke/browser
, it is either a url to a javascript file for external scripts or the current location for inline script. In the later case the hash part of the url will be a number indicating the position of the inline script in the original html tree.script2 :: string
: The transformed script
OtilukeBrowser
OtilukeBrowser modifies html pages served over http(s) by performing a man-in-the-middle attack with a forward proxy. Such attack requires the browser to redirect all its request to the forward proxy. For pages securely served over https it also requires the browser to trust the self-signed certificate at browser/ca/cert.pem. Examples: test/browser-hello.sh and test/browser-google.sh.

require("otiluke/browser/ca").initialize(options)
Upon calling this submodule, Otiluke will prepare a directory to serve as a certificate authority.
That the end, this directory will be populated with the subdirectories: req
, key
and cert
and the files: req.pem
, key.pem
and cert.pem
.
To make a browser trust Otiluke, you will need to import cert.pem
which is Otiluke's root certificate.
Warning Making a browser trust a root certificate implies serious security consequences. Everyone having access to the corresponding private key can falsify any identity on that browser (which is exactly what OtilukeBrowser needs to do). To avoid security breach, we recommend to use a dedicated browser and never fill in it any sensitive information.
require("otiluke/browser/ca").initialize({home, subj})
home :: string
, default"node_modules/otiluke/browser/ca-home"
: Path to a certificate authority directory.subj :: string
, default"/CN=otiluke/O=Otiluke"
: The-subj
argument to pass toopenssl -req
.
Alternatively, if Otiluke is installed globally, the otiluke-browser-ca
command can be used:
otiluke-browser-ca --initialize [--home <path>] [--subj arg]
--home
, defaultnode_modules/otiluke/browser/ca-home
: Path to a certificate authority directory.--subj
, default/CN=otiluke/O=Otiluke
: The-subj
argument to pass toopenssl -req
.
proxy = require("otiluke/browser/proxy")(virus_path, options)
Create a man-in-the-middle proxy.
proxy = require("otiluke/browser/proxy")(virus_path, {"ca-home":ca_home, "url-search-prefix":url_search_prefix, "http-splitter":http_splitter, "global-variable":global_variable});
virus_path :: string
: Path to a virus module.ca_home :: string
, default"node_modules/otiluke/browser/ca-home"
Path to a certificate authority directory.url_search_prefix :: string
, default"otiluke-"
: Url search prefix for creating theoptions
object to pass to the virus module. For instance, the urlhttp://example.com/path?otiluke-foo=123&otiluke-bar=456&qux=789
will result into{foo:123, bar:456}
being passed to the virus module.http_splitter :: string
, default random value. Marker for recognizing communication from the virus module.global_variable :: string
, default random value. Global variable name used to store the transformation function asynchronously returned by the virus module.proxy :: object
An imitation of a regularhttp.Server
.- Event:
request
request :: http.IncomingMessage
response :: http.ServerResponse
- Event:
upgrade
request :: http.IncomingMessage
socket :: Net.Socket
head :: buffer
- Event:
listening
- Event:
close
hadError :: boolean
- Event:
error
error :: Error
location :: string
origin :: events.EventEmitter
proxy.listen(port, callback)
proxy.close(callback)
proxy.address()
- Event:
Redirect Firefox requests to the man-in-the-middle proxy
Go to about:preferences
, at the bottom of the General menu, click on Settings....
Tick the checkbox Manual proxy configuration and Use this proxy server for all protocols.
The HTTP Proxy field should be localhost and the Port field should refer to the port to which is the proxy is listening.

Make Firefox trust Otiluke's root certificate
This step is only required if you need to infect html pages securely served over https.
Go to about:preferences
, at the bottom of the Privacy & Security menu, click on View Certificates.
Import Otiluke's root certificate an restart Firefox to avoid sec_error_reused_issuer_and_serial
error.

OtilukeNode
OtilukeNode infects node applications by modifying the require procedure performed by node. See test/node.sh for example.

require("otiluke/node")(virus, options)
require("otiluke/node")(virus, {_:[main, ...argv], host, secure, ...});
virus :: function
: Virus function.main :: string
: Path to main module.argv :: [string]
: Command line arguments.host :: number | string | null
defaultnull
: A local port number orhostname:port
or a Unix domain socket or a Windows pipe. Ifnull
theantena
passed to the virus module will benull
.secure :: boolean
: Indicates whether theantena
argument passed tovirus
should perform remote communication. Non applicable ifhost
isnull
....
: Remaining properties will be used to compute argument mappingargm
passed tovirus
.
Alternatively, if Otiluke is installed globally, the otiluke-node
command can be used:
otiluke-node --virus <path> [--host <number|path|host>] [--secure] ... -- <target-command>`
--virus
: Path to a virus module.--host <number|path|host>
: Defines the host to which theantena
passed to the virus module should be directed.number
: Local port.path
: Unix domain socket or windows pipe.host
:hostname[:port]
.
[--secure]
Tells if theantena
passed to the virus module should perform secure communication....
Additional arguments will be passed asargm
properties to the virus module.--
: The double dash separates Otiluke-related arguments from the target node command.
require("otiluke/node/infect")(transform, command)
This submodule can be used to by-pass the virus interface and directly provide a transformation function.
require("otiluke/node/infect")(transform, [main, ...argv]);
transform:: function
Transformation function.main :: string
: Path to main module.argv :: [string]
: Command line arguments.