{"id":45076774,"url":"https://github.com/nuprl/augur","last_synced_at":"2026-02-19T13:37:03.749Z","repository":{"id":41287510,"uuid":"286606898","full_name":"nuprl/augur","owner":"nuprl","description":"Performant taint analysis for Node.js","archived":false,"fork":false,"pushed_at":"2024-08-07T00:14:38.000Z","size":22327,"stargazers_count":44,"open_issues_count":1,"forks_count":13,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-08-07T03:02:19.464Z","etag":null,"topics":["graaljs","javascript","nodejs","nodeprof","taint-analysis"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"upl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nuprl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-11T00:27:51.000Z","updated_at":"2024-08-07T00:14:46.000Z","dependencies_parsed_at":"2024-08-07T02:44:24.277Z","dependency_job_id":"2d97780a-36eb-4f9c-a855-ac64cfde408a","html_url":"https://github.com/nuprl/augur","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/nuprl/augur","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuprl%2Faugur","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuprl%2Faugur/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuprl%2Faugur/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuprl%2Faugur/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nuprl","download_url":"https://codeload.github.com/nuprl/augur/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuprl%2Faugur/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29615084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T13:04:20.082Z","status":"ssl_error","status_checked_at":"2026-02-19T13:03:33.775Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graaljs","javascript","nodejs","nodeprof","taint-analysis"],"created_at":"2026-02-19T13:37:02.182Z","updated_at":"2026-02-19T13:37:03.739Z","avatar_url":"https://github.com/nuprl.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Augur Build Status](https://github.com/nuprl/augur/actions/workflows/Augur.yml/badge.svg)](https://github.com/nuprl/augur/actions/workflows/Augur.yml)\n\u003cimg src=\"./augur.png\" align=\"left\" height=\"100\"\u003e\n\n**Augur** is a dynamic taint analysis for Node.js implemented in TypeScript\nusing\n[NodeProf](https://github.com/Haiyang-Sun/nodeprof.js). Check out the [paper](https://dl.acm.org/doi/pdf/10.1145/3551349.3559522)!\n\nAugur builds upon the technique described in [Ichnaea](https://www.franktip.org/pubs/tse2020.pdf). It is more performant, supports the latest version of JavaScript, and is highly configurable to support any type of dynamic data-flow analysis.\n \n---\n\n## What is taint analysis?\n\n**Taint analysis** is a dynamic program analysis technique used to track \n*data flows* through programs. It's useful in many domains, but the most\ncommon application of taint analysis is for detecting injection vulnerabilities.\nRead \n[this paper](https://www.franktip.org/pubs/tse2020.pdf) for more background\non taint analysis.\n\n## Getting started\n\nLet's walk through how to install Augur and use it to analyze a Node.js project.\n\nFirst, install Augur's dependencies if you don't already have them: `node`, `npm`, and `docker`.\n\nClone this project onto your machine, then build Augur:\n```\ngit clone --recurse-submodules https://github.com/nuprl/augur\ncd augur/ts\n\n./docker-nodeprof/docker-pull.sh  # Pull NodeProf Docker image\nnpm install                       # Install Augur deps\nnpm run build                     # Build Augur\n```\n\nTry running a basic test to make sure your installation succeeded:\n```\n./node_modules/.bin/jest -t basic-assignment-tainted\n# tainted value flowed into sink {\"type\":\"variable\",\"name\":\"z\",\"location\":{\"fileName\":\"test.js\"}}!\n```\n\nYour Augur installation is now set up!\n\n#### Instrumenting an application\n\nUsing Augur to analyze your own applications simply requires placing a \nfile, `spec.json`, at the **root** of your Node.js project:\n```\n{\n    \"main\": \"test.js\",\n    \"sources\": [\n        {\n            \"type\": \"functionReturn\",\n            \"name\": \"readFileSync\"\n        }\n    ],\n    \"sinks\": [\n        {\n            \"type\": \"functionInvocation\",\n            \"name\": \"exec\"\n        }\n    ]\n}\n```\nThis file tells Augur the *sources* and *sinks* of the flows you want to\ntrack. The spec above tells Augur to alert you if any value returned from\n`readFileSync` flows into the function `exec`. It also tells Augur how to run\n your project: by executing the file `test.js`.\n[Here](./tests-unit/README.md#specjson) are all the options for `spec.json`.\n\nLet's say we analyze the following program, `test.js`:\n```javascript\nconst fs = require('fs');\nconst child_process = require('child_process');\n\n// read in user's message from a file\nlet input = fs.readFileSync(\"message.txt\");\n\n// echo the user's message\nchild_process.exec(\"echo 'User\\'s message: \" + input + \"'\");\n```\n\nThis exact flow is a classic example of an *injection vulnerability*: `exec` is\na very powerful function, giving the command full control over your machine; and\n`readFileAsync` returns arbitrary *user* input, meaning the user may have full\ncontrol of your machine. This can cause massive security issues, as well as\nbugs with disastrous consequences.\n\nLet's go ahead and use Augur to verify that there is indeed a taint flow\nbetween user input and `exec`.\n\nOur project is structured like this:\n```\nproject/\n|\n+-- test.js\n|\n+-- message.txt\n|\n+-- spec.json\n```\n[This example is also a real test case in Augur.](./tests-unit/input/simple-readFileSync-exec-tainted)\n\nTo analyze this project with Augur, we run:\n```\ncd augur/ts\nnode ./runner/cli.js --projectDir ~/project --projectName project --outputDir .\n         #           ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^\n         #     path to project                        |                 |\n         #                                            |                 |\n         #                                      project name            |\n         #                                                              |\n         #                                        directory to store temp files\n```\n\nAugur will alert us that the application does in fact have the flow we're\nexpecting:\n```\nFlows found into the following sinks: [\n    {\n        \"type\": \"functionInvocation\",\n        \"name\": \"exec\"\n    }\n]\n```\n\nYou've now analyzed your first application using Augur!\n\n## Augur Features\n1. Support for *any* piece of JavaScript code to act as a taint source\n2. Support for *any* piece of JavaScript code to act as a taint sink\n3. Support for taint sanitizers\n4. Support for different forms of taint tracking, from simple boolean tracking \nto full dependency information between variables\n5. Support for tracking taint through native code (see below)\n\n## Tracking Type\nAugur supports *three* methods for tracking taint across your application:\n\n1. `Boolean`: the simplest (and fastest) tracker you can use. During your application's runtime, it simply determines whether a value came from *any* source. It doesn't keep track of which source it came from, or where the flow was introduced. This is not very useful in practice, because you will likely want to use...\n2. `SourcedBoolean`: a more practical tracker. For each value in your program, Augur determines if it came from a *source*, and if so, which source and on what line the taint was introduced.\n3. `Expression`: the most general tracker. In this mode, Augur will save all the information it finds during your application's runtime. For any given expression, its full set of dependent expressions is recorded. In other words, regardless your specified sources and sinks, Augur will save *every* flow between *every* expression. Expect slowdowns and large output files (on the order of MBs).\n\nThe method you choose should be placed in your [`spec.json`](./tests-unit/README.md#specjson).\n\n## Native function models\nModern JavaScript relies on a wide variety of native functions to improve\nits usability and performance. Common operations on data structures and\nutilities are now natively implemented in the VM, including array reduce,\npromises, and regular expressions.\n\nBecause native functions are so pervasive, accurately tracking taint in modern\nJavaScript requires an understanding of these functions. Our taint analysis only\nanalyzes JavaScript code, so we can't instrument the actual implementations of\nthese native functions. Our taint analysis supports two ways of tracking taint\nthrough these native functions:\n\n1. implementing *native models*. A native model is an implementation of a\nnative function that *only* tracks taint. It doesn't have to perform any\nlogical calculations, it just has to inform the\n[abstract machine](./ts/src/README.md)\nwhere taint should flow as a result of the function call. These models are often\nmuch easier to implement than the functions themselves because data flows are\noften more simple than the logic in a function. For examples of native models,\nlook at\n[`src/native/native.ts`](./ts/src/native/native.ts).\n2. using *polyfills*. Polyfills are implementations of native functions written\nin JavaScript itself. While polyfills are traditionally used for providing\nmissing functionality to older web browsers, they can also help the taint\nanalysis understand data-flow. Simply define the polyfill to use it.\nNote that Augur already defines a couple of its own polyfills in\n[`src/native/polyfill.js`](./ts/src/native/polyfill.js).\n\n## Optional: Installing NodeProf locally\nAugur normally runs your Node.js project in Docker. This is because NodeProf\nis difficult to install and configure locally. If you want to avoid using\nDocker, you can install NodeProf locally and point Augur to the installation.\n\nTo install NodeProf locally, follow the \n[advanced installation instructions](https://github.com/Haiyang-Sun/nodeprof.js/tree/master/docs/panathon18#advanced-installation---building-nodeprof-and-graalvm-from-source-linux-and-macos).\n\nWhen using a manual installation, you will have to set environment variables:\n- `NODEPROF_HOME`: pointing to your NodeProf advanced installation\n- `JAVA_HOME`: pointing to your JVM CI directory (not the `bin` subdirectory)\n- `MX_HOME`: pointing to your `mx` installation\n\nExample:\n- `NODEPROF_HOME=/home/mwaldrich/workspace-nodeprof/nodeprof.js/`\n- `MX_HOME=/home/mwaldrich/mx`\n- `JAVA_HOME=/home/mwaldrich/openjdk1.8.0_172-jvmci-0.46`\n\nAugur will automatically use a local NodeProf installation if these environment\nvariables are set; no flags or further configuration is needed.\n\n## Contributing to Augur\nIf you're looking to dive into Augur's code, the structure and implementation of\nthe analysis is documented with `README`s in folders inside [`src`](./ts/src).\n\nIf you want to contribute to Augur, we recommend using JetBrain's WebStorm IDE.\nTo get the project fully up and running, simply:\n1. follow the installation instructions in the *Getting started* section\n2. open the `augur` folder in WebStorm\n3. execute the Run Configuration named `unit tests`\n\n## JavaScript Feature Support\n|                                | Not Yet | In Progress | Done | Notes   |\n|--------------------------------|---------|-------------|------|---------|\n| Variable read                  |         |             | x    |         |\n| Variable write                 |         |             | x    |         |\n| Property read                  |         |             | x    |         |\n| Property write                 |         |             | x    |         |\n| Unary expression               |         |             | x    |         |\n| Binary expression              |         |             | x    |         |\n| Implicit declaration of `this` |         |             | x    | see #19 |\n| Function declaration           |         |             | x    |         |\n| Function arguments             |         |             | x    |         |\n| Variable assignment            |         |             | x    | see #20 |\n| Function call                  |         |             | x    | see #21 |\n| Native functions               |         |             | x    | see #22 |\n| Async/await                    |         |             | X    | see #29 |\n| Function returns               |         |             | x    | see #30 |\n\n## Support for Ichnaea Benchmarks\n[Ichnaea](https://www.franktip.org/pubs/tse2020.pdf) was evaluated against a\nset of 22 benchmarks. Here is a table showing how Augur performs on these\nbenchmarks:\n\n|                             | Correct Output | Incorrect Output | Old/Broken Code |\n|-----------------------------|----------------|------------------|-----------------|\n| `chook-growl-reporter-exec` | x              |                  |                 |\n| `cocos-utils`               | x              |                  |                 |\n| `fish-exec`                 | x              |                  |                 |\n| `git2json-exec`             | x              |                  |                 |\n| `gm-attack`                 | x              |                  |                 |\n| `growl-exec`                | x              |                  |                 |\n| `libnotify-exec`            | x              |                  |                 |\n| `m-log-eval`                |                | x                |                 |\n| `mixin-pro-eval`            | x              |                  |                 |\n| `modulify-eval`             | x              |                  |                 |\n| `mongo-parse-eval`          | x              |                  |                 |\n| `mongoosemask-eval`         | x              |                  |                 |\n| `mongoosify-eval`           | x              |                  |                 |\n| `node-os-utils`             | x              |                  |                 |\n| `node-wos`                  | x              |                  |                 |\n| `office-converter`          | x              |                  |                 |\n| `os-uptime`                 | x              |                  |                 |\n| `osenv`                     | x              |                  |                 |\n| `pidusage-exec`             |                |                  | x               |\n| `pomelo-monitor`            | x              |                  |                 |\n| `system-locale`             | x              |                  |                 |\n| `systeminformation`         | x              |                  |                 |\n\nThe benchmark `pidusage-exec` crashes in modern JavaScript VMs.\n\nThe benchmark `m-log-eval` is not currently compatible with the tool due to a\nmissing native function model.\n\n## Acknowledgments\nAugur was written by [Mark Aldrich](https://github.com/mwaldrich),\n[Emily Shi](https://github.com/aralisza),\n[Alexi Turcotte](https://github.com/reallyTG),\nand [Frank Tip](https://github.com/franktip).\n\nAugur sits on top of [NodeProf](https://github.com/Haiyang-Sun/nodeprof.js),\nthe dynamic analysis framework written by\n[Haiyang Sun](https://github.com/Haiyang-Sun) and others.\n\nAugur also relies on Oracle's [GraalVM](https://www.graalvm.org/)\nand [GraalJS](https://github.com/graalvm/graaljs).\n\nContinuous integration for Augur was designed and implemented by [Adison Trueblood](https://github.com/trueblooda).\n\nThis research was supported by the National Science Foundation under NSF grant \nCCF-1715153 and REU supplement CCF-1930604.\n\nCopyright (c) 2019-2022 [Programming Research Lab](https://prl.ccs.neu.edu/) at \nNortheastern University. Augur is licensed under the UPL. See the `LICENSE` file\nfor more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuprl%2Faugur","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnuprl%2Faugur","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuprl%2Faugur/lists"}