├── custom_sink.txt
├── custom_source.txt
├── custom_userinput.txt
├── .gitignore
├── client
├── js
│ ├── go.js
│ ├── coderoadservice.js
│ ├── locationctrl.js
│ ├── lib
│ │ ├── utils.js
│ │ ├── angular-route-1.2.13.min.js
│ │ ├── localforage.min.js
│ │ └── walk.js
│ ├── main.js~
│ ├── main.js
│ ├── scanworker.js
│ ├── rulesctrl.js
│ ├── build
│ │ ├── test
│ │ │ ├── dumper.coffee
│ │ │ ├── controller.coffee
│ │ │ └── traverse.coffee
│ │ ├── execute.js
│ │ └── graph
│ │ │ └── dndTree.js
│ ├── experimentctrl.js
│ ├── scanservice.js
│ └── coderoadctrl.js~
├── img
│ ├── Gear.png
│ ├── glyphicons-halflings.png
│ └── glyphicons-halflings-white.png
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.ttf
│ └── fontawesome-webfont.woff
├── partials
│ ├── coderoad.html~
│ ├── rules.html
│ ├── experiment.html
│ ├── experiment.html~
│ └── scan.html
├── rules.readme.md
├── css
│ ├── angular-csp.css
│ ├── prettify.css
│ ├── dashboard.css
│ ├── app.css~
│ ├── c3.css
│ ├── codemirror-mdn.css
│ ├── codemirror.css
│ └── app.css
├── index.html
└── vectors
│ ├── v1.txt
│ ├── v4.txt
│ └── v2.txt
├── App
├── reload.js
└── a
│ └── ajdsoijdgv
│ └── time.js
├── LICENSE-scanjs
├── Copyright
├── scanjs_LICENSE
├── package.json
├── jsprime_LICENSE
├── jsprime_README.md
└── scanjs_README.md
├── Examples Test Files
└── time.js
├── server.js
├── package.json
├── LICENSE
├── LICENSE-jsprime
├── README.md
├── common
├── template_rules.json
└── scan.js
└── jspwn.js
/custom_sink.txt:
--------------------------------------------------------------------------------
1 | test_sink
--------------------------------------------------------------------------------
/custom_source.txt:
--------------------------------------------------------------------------------
1 | test_source
--------------------------------------------------------------------------------
/custom_userinput.txt:
--------------------------------------------------------------------------------
1 | test_user_input
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | /nbproject/
3 | *~
4 |
--------------------------------------------------------------------------------
/client/js/go.js:
--------------------------------------------------------------------------------
1 | document.write('');
2 |
--------------------------------------------------------------------------------
/client/img/Gear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dvolvox/JSpwn/HEAD/client/img/Gear.png
--------------------------------------------------------------------------------
/client/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dvolvox/JSpwn/HEAD/client/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/client/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dvolvox/JSpwn/HEAD/client/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/client/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dvolvox/JSpwn/HEAD/client/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/client/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dvolvox/JSpwn/HEAD/client/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/client/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dvolvox/JSpwn/HEAD/client/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/client/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dvolvox/JSpwn/HEAD/client/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/client/js/coderoadservice.js:
--------------------------------------------------------------------------------
1 | scanjsModule.factory('Data', ['$rootScope', '$http', function($rootScope, $http) {
2 |
3 |
4 |
5 |
6 |
7 | }]);
--------------------------------------------------------------------------------
/client/partials/coderoad.html~:
--------------------------------------------------------------------------------
1 |
2 |
Hello {{getname()}}
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/App/reload.js:
--------------------------------------------------------------------------------
1 | function reload() {
2 | var redir = location.hash.split("#")[1];
3 | if (redir){
4 | x = document.getElementsByTagName('iframe');
5 | x[0].setAttribute('src',redir);
6 | }}
--------------------------------------------------------------------------------
/LICENSE-scanjs:
--------------------------------------------------------------------------------
1 | This Source Code Form is subject to the terms of the Mozilla Public
2 | License, v. 2.0. If a copy of the MPL was not distributed with this
3 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
--------------------------------------------------------------------------------
/App/a/ajdsoijdgv/time.js:
--------------------------------------------------------------------------------
1 | function timedMsg(callback){
2 | if(callback){
3 | var t=setTimeout(eval('callback'),3000);
4 | return 0;
5 | }}
6 | function fire(){
7 | var call = location.hash.split("#")[1];
8 | timedMsg(call);
9 | }
--------------------------------------------------------------------------------
/Copyright/scanjs_LICENSE:
--------------------------------------------------------------------------------
1 | This Source Code Form is subject to the terms of the Mozilla Public
2 | License, v. 2.0. If a copy of the MPL was not distributed with this
3 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
--------------------------------------------------------------------------------
/Examples Test Files/time.js:
--------------------------------------------------------------------------------
1 | function timedMsg(callback){
2 | if(callback){
3 | var t=setTimeout(eval('callback'),3000);
4 | return 0;
5 | }}
6 | function fire(){
7 | var call = location.hash.split("#")[1];
8 | timedMsg(call);
9 | }
--------------------------------------------------------------------------------
/client/rules.readme.md:
--------------------------------------------------------------------------------
1 | Rules maintained here:
2 | https://docs.google.com/a/mozilla.com/spreadsheets/d/1T14mvMMAspnvhKXxPNRBiV0x6QKZsXr8_b7eXJvEf_A/edit?alt=json#gid=0
3 |
4 | Converted to JSON with http://shancarter.github.io/mr-data-converter/
5 |
6 |
--------------------------------------------------------------------------------
/client/js/locationctrl.js:
--------------------------------------------------------------------------------
1 | scanjsModule.controller('LocationCtrl', ['$scope', '$location', function LocationCtrl($scope, $location) {
2 | $scope.tabBtnClass = function (page) {
3 | var current = $location.path().substring(1) || 'scan';
4 | //console.log("l", $location.hash(), "ls", $location.hash().substring(2))
5 | return page === current ? 'active' : '';
6 | }
7 | }]);
--------------------------------------------------------------------------------
/client/css/angular-csp.css:
--------------------------------------------------------------------------------
1 | /* Include this file in your html if you are using the CSP mode. */
2 |
3 | @charset "UTF-8";
4 |
5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
6 | .ng-cloak, .x-ng-cloak,
7 | .ng-hide {
8 | display: none !important;
9 | }
10 |
11 | ng\:form {
12 | display: block;
13 | }
14 |
15 | .ng-animate-block-transitions {
16 | transition:0s all!important;
17 | -webkit-transition:0s all!important;
18 | }
19 |
--------------------------------------------------------------------------------
/client/js/lib/utils.js:
--------------------------------------------------------------------------------
1 |
2 | //Array.find polyfill
3 | if (!Array.prototype.find) {
4 | Object.defineProperty(Array.prototype, 'find', {
5 | enumerable: false,
6 | configurable: false,
7 | writable: false,
8 | value: function(predicate) {
9 | for (var i=0; i < this.length; i++) {
10 | if (predicate(this[i], i, this)) {
11 | return this[i];
12 | }
13 | }
14 | return void 0;
15 | }
16 | });
17 | }
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | var static = require("node-static");
3 | var file = new static.Server('.', {
4 | headers: {
5 | "Content-Security-Policy": "default-src 'self'; object-src 'none'; img-src 'self' data:; script-src 'self' 'unsafe-eval'",
6 | }
7 | });
8 |
9 | const PORT = process.env.PORT || 4000;
10 | require ('http').createServer(function (req, res) {
11 | req.addListener('end', function () {
12 | file.serve(req, res);
13 | }).resume();
14 | }).listen(PORT);
15 |
16 | console.log("> node-static is listening on http://127.0.0.1:"+PORT+"/client/#/scan");
17 |
--------------------------------------------------------------------------------
/client/js/main.js~:
--------------------------------------------------------------------------------
1 | var scanjsModule = angular.module('scanjs', ['ui.bootstrap', 'ngRoute']);
2 |
3 | scanjsModule.config(['$routeProvider',
4 | function($routeProvider) {
5 | $routeProvider.
6 | when('/scan', {
7 | templateUrl: 'partials/scan.html',
8 | controller: 'ScanCtrl'
9 | }).
10 | when('/rules', {
11 | templateUrl: 'partials/rules.html',
12 | controller: 'RuleListCtrl'
13 | }).
14 | when('/experiment', {
15 | templateUrl: 'partials/experiment.html',
16 | controller: 'ExperimentCtrl'
17 | }).
18 | otherwise({
19 | redirectTo: '/scan'
20 | });
21 | }]);
--------------------------------------------------------------------------------
/client/css/prettify.css:
--------------------------------------------------------------------------------
1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
--------------------------------------------------------------------------------
/client/js/main.js:
--------------------------------------------------------------------------------
1 | var scanjsModule = angular.module('scanjs', ['ui.bootstrap', 'ngRoute']);
2 |
3 | scanjsModule.config(['$routeProvider',
4 | function($routeProvider) {
5 | $routeProvider.
6 | when('/scan', {
7 | templateUrl: 'partials/scan.html',
8 | controller: 'ScanCtrl'
9 | }).
10 | when('/rules', {
11 | templateUrl: 'partials/rules.html',
12 | controller: 'RuleListCtrl'
13 | }).
14 | when('/experiment', {
15 | templateUrl: 'partials/experiment.html',
16 | controller: 'ExperimentCtrl'
17 | }).
18 | otherwise({
19 | redirectTo: '/scan/client'
20 | });
21 | }]);
22 |
--------------------------------------------------------------------------------
/Copyright/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "scanjs",
3 | "version": "0.0.2",
4 | "description": "Static analysis tool for javascript codebases",
5 | "main": "scanner.js",
6 | "bin": {
7 | "scanjs": "./scanner.js",
8 | "scanjs-server": "./server.js"
9 | },
10 | "preferGlobal": true,
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/mozilla/scanjs.git"
14 | },
15 | "keywords": [
16 | "scanjs",
17 | "code-analysis",
18 | "javascript",
19 | "static-analysis"
20 | ],
21 | "author": "Paul Theriault, Frederik Braun, Rob Fletcher",
22 | "license": "MPL",
23 | "dependencies": {
24 | "acorn": "~0.3.0",
25 | "tern": "~0.5.0",
26 | "optimist": "~0.5.2",
27 | "jszip": "~2.2.0",
28 | "node-static": "~0.7.3",
29 | "js-beautify":"~1.4.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "JSpwn",
3 | "version": "0.0.1",
4 | "description": "Static analysis tool for javascript codebases",
5 | "main": "scanner.js",
6 | "bin": {
7 | "scanjs": "./scanner.js",
8 | "scanjs-server": "./server.js"
9 | },
10 | "preferGlobal": true,
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/Etraud123/JSpwn"
14 | },
15 | "keywords": [
16 | "scanjs",
17 | "code-analysis",
18 | "javascript",
19 | "static-analysis"
20 | ],
21 | "author": "Duarte Monteiro",
22 | "license": "MIT",
23 | "dependencies": {
24 | "acorn": "~0.3.0",
25 | "tern": "~0.5.0",
26 | "optimist": "~0.5.2",
27 | "jszip": "~2.2.0",
28 | "node-static": "~0.7.3",
29 | "js-beautify": "~1.4.2"
30 | },
31 | "scripts": {
32 | "start": "node server.js"
33 | },
34 | "bugs": {
35 | "url": "https://github.com/Etraud123/JSpwn/issues"
36 | },
37 | "homepage": "https://github.com/Etraud123/JSpwn",
38 | "devDependencies": {}
39 | }
40 |
--------------------------------------------------------------------------------
/client/js/scanworker.js:
--------------------------------------------------------------------------------
1 | /* this makes sure that console.log can be used, even if it is undefined.
2 | We won't see the message though, since this kind of postMessage isn't handled in scanservice.js */
3 | if (typeof console === "undefined") {
4 | console = {};
5 | console.log = function consoleShim(mesg) {
6 | postMessage({'type':'log', 'message': mesg});
7 | }
8 | }
9 |
10 | importScripts('lib/acorn.js',
11 | 'lib/walk.js',
12 | 'lib/acorn_loose.js',
13 | '../../common/scan.js');
14 |
15 | //load default rules
16 | //ScanJS.loadRulesFile("../../common/rules.json")
17 |
18 | onmessage = function (evt) {
19 | if (evt.data.call === 'scan') {
20 | var args = evt.data.arguments;
21 | var source = args[0];
22 | var rules;
23 |
24 | var file = args[1];
25 | var findings = ScanJS.scan(source,file);
26 | postMessage({"filename": file, "findings": findings});
27 | }
28 | else if(evt.data.call === 'updateRules'){
29 | console.log('scanworker.js: Loaded '+evt.data.rules.length+" rules.")
30 | ScanJS.loadRules(evt.data.rules)
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2014 Duarte Monteiro (duarteetraud@gmail.com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
--------------------------------------------------------------------------------
/LICENSE-jsprime:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Nishant Das Patnaik (nishant.dp@gmail.com)
5 | Copyright (c) 2013 Sarathi Sabyasachi Sahoo (sarathisahoo@gmail.com)
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | this software and associated documentation files (the "Software"), to deal in
9 | the Software without restriction, including without limitation the rights to
10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 | the Software, and to permit persons to whom the Software is furnished to do so,
12 | subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 | */
24 |
--------------------------------------------------------------------------------
/Copyright/jsprime_LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Nishant Das Patnaik (nishant.dp@gmail.com)
5 | Copyright (c) 2013 Sarathi Sabyasachi Sahoo (sarathisahoo@gmail.com)
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | this software and associated documentation files (the "Software"), to deal in
9 | the Software without restriction, including without limitation the rights to
10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 | the Software, and to permit persons to whom the Software is furnished to do so,
12 | subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 | */
24 |
--------------------------------------------------------------------------------
/client/js/rulesctrl.js:
--------------------------------------------------------------------------------
1 | scanjsModule.controller('RuleListCtrl', ['$scope', 'ScanSvc', function RuleListCtrl($scope, ScanSvc) {
2 | $scope.rulesFile = "../common/rules.json";
3 | $scope.rules = []; //JSON rules object
4 |
5 | document.getElementById("rule-file-input").addEventListener("change", function (evt) {
6 | $scope.handleFileUpload(this.files);
7 | });
8 |
9 | function loadRulesFile(rulesFile) {
10 | //TODO rewrite with $http()
11 | var request = new XMLHttpRequest();
12 | request.open('GET', rulesFile);
13 |
14 | request.onload = function () {
15 | if (request.status >= 200 && request.status < 400) {
16 | $scope.rules = JSON.parse(request.responseText);
17 |
18 | ScanSvc.loadRules($scope.rules);
19 | } else {
20 | console.log('Error loading ' + rules)
21 | }
22 | $scope.$apply();
23 | };
24 |
25 | request.onerror = function () {
26 | console.log('Connection error while loading ' + rulesFile)
27 | };
28 | request.send();
29 | }
30 |
31 | $scope.handleFileUpload = function handleFileUpload(fileList) {
32 |
33 | $scope.rulesFile = fileList[0].name;
34 |
35 | var reader = new FileReader();
36 | reader.onload = function () {
37 | $scope.rules = JSON.parse(this.result);
38 | ScanSvc.loadRules($scope.rules);
39 | $scope.$apply();
40 | }
41 |
42 | reader.readAsText(fileList[0])
43 | };
44 |
45 | loadRulesFile($scope.rulesFile);
46 | }]);
47 |
--------------------------------------------------------------------------------
/client/partials/rules.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Load new rules
8 | Load a JSON rules file to change rules:
9 |
10 |
Current rules
11 |
Number of Rules: {{rules.length}}
12 |
13 |
14 |
15 |
16 | | Rule Name |
17 | Rule Description |
18 | Rule Definition |
19 |
20 |
21 |
22 |
23 | | {{rule.name}} |
24 | {{rule.desc}} |
25 |
26 |
27 | {{rule.source}}
28 | |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/client/css/dashboard.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Base structure
3 | */
4 |
5 | /* Move down content because we have a fixed navbar that is 50px tall */
6 | body {
7 | padding-top: 50px;
8 | }
9 |
10 | /*
11 | * Global add-ons
12 | */
13 |
14 | .sub-header {
15 | padding-bottom: 10px;
16 | border-bottom: 1px solid #eee;
17 | }
18 |
19 |
20 | /*
21 | * Sidebar
22 | */
23 |
24 | /* Hide for mobile, show later */
25 | .sidebar {
26 | display: none;
27 | }
28 | @media (min-width: 768px) {
29 | .sidebar {
30 | position: fixed;
31 | top: 51px;
32 | bottom: 0;
33 | left: 0;
34 | z-index: 1000;
35 | display: block;
36 | padding: 20px;
37 | overflow-x: hidden;
38 | overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
39 | background-color: #EAEFF2;
40 | border-right: 1px solid #eee;
41 | }
42 | }
43 |
44 | /* Sidebar navigation */
45 | .nav-sidebar {
46 | margin-right: -21px; /* 20px padding + 1px border */
47 | margin-bottom: 20px;
48 | margin-left: -20px;
49 | }
50 | .nav-sidebar > li > a {
51 | padding-right: 20px;
52 | padding-left: 20px;
53 | }
54 | .nav-sidebar > .active > a {
55 | color: #fff;
56 | background-color: #00539F;
57 | }
58 |
59 |
60 | /*
61 | * Main content
62 | */
63 |
64 | .main {
65 | padding: 20px;
66 | }
67 | @media (min-width: 768px) {
68 | .main {
69 | padding-right: 40px;
70 | padding-left: 40px;
71 | }
72 | }
73 | .main .page-header {
74 | margin-top: 0;
75 | }
76 |
77 |
78 | /*
79 | * Placeholder dashboard ideas
80 | */
81 |
82 | .placeholders {
83 | margin-bottom: 30px;
84 | text-align: center;
85 | }
86 | .placeholders h4 {
87 | margin-bottom: 0;
88 | }
89 | .placeholder {
90 | margin-bottom: 20px;
91 | }
92 | .placeholder img {
93 | display: inline-block;
94 | border-radius: 50%;
95 | }
96 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Copyright
2 | =====
3 |
4 | Duarte Monteiro (etraud123) JSPwn
5 |
6 | Nishant Das Patnaik (nishant.dp@) JsPrime
7 |
8 | Paul Theriault (pauljt) Scanjs
9 |
10 | Introduction
11 | =====
12 |
13 | This Application was built in a month under a Summer Internship at Blip.pt (BetFair). A special thanks to AppSec team @ blip.pt and Betfair for all the good feedback and ideas for future implementations.
14 |
15 | JSpwn
16 | =====
17 |
18 | JavaScript Code Analysis
19 |
20 | JSPwn is a modified version of Scanjs + JSPrime.
21 | This tool allow the developers to detect Sinks And Sources of their Applications and find XSS vulnerabilities and DOM XSS (Beta).
22 |
23 | With the engine of ScanJS to detect vulnerabilities and the code flux feature of JSprime, this app has the compatibility of detect the vulnerabilities point and backtrack the code.
24 |
25 | Video: https://www.youtube.com/watch?v=RWE3852ubH0&
26 |
27 | Example
28 | =====
29 |
30 | *GUI
31 |
32 | [1]$ cd jspwn-master
33 |
34 | [2]$ npm install
35 |
36 | [3]$ node server.js.
37 |
38 | Go to: http://localhost:4000/client/#/scan.
39 |
40 | Select File from folder.
41 |
42 | Enable REGEXP Custom.
43 |
44 | Press "Scan"
45 |
46 | *CLI
47 |
48 | Usage: $node jspwn.js -t [path/to/app] -j [for json output]
49 |
50 |
51 | Note: Output is automatic generated
52 |
53 | Custom Scanning
54 | ======
55 |
56 | FOR WEB INTERFACE VERSION ::
57 |
58 | Source Array: Analyzer.js:26
59 | Sink Array: Analyzer.js:27
60 |
61 | Regex: scanctrl.js: 44/45/46
62 |
63 | User-Input-Validator: scanctrl.js:865
64 |
65 | Attack-vector: scanctrl.js:900
66 |
67 | FOR CLI VERSION ::
68 |
69 | Add -c argument for loading custom rules from file:
70 |
71 | custom_userinput.txt
72 |
73 | custom_source.txt
74 |
75 | custom_sink.txt
76 |
77 | Future Features
78 | ======
79 | > Developing a browser extension for JSpwn
80 |
--------------------------------------------------------------------------------
/client/js/build/test/dumper.coffee:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013 Yusuke Suzuki
2 | #
3 | # Redistribution and use in source and binary forms, with or without
4 | # modification, are permitted provided that the following conditions are met:
5 | #
6 | # * Redistributions of source code must retain the above copyright
7 | # notice, this list of conditions and the following disclaimer.
8 | # * Redistributions in binary form must reproduce the above copyright
9 | # notice, this list of conditions and the following disclaimer in the
10 | # documentation and/or other materials provided with the distribution.
11 | #
12 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
13 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15 | # ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
16 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 |
23 | 'use strict'
24 |
25 | estraverse = require '..'
26 |
27 | module.exports = class Dumper
28 | constructor: ->
29 | @logs = []
30 |
31 | log: (str) ->
32 | @logs.push str
33 |
34 | result: ->
35 | @logs.join '\n'
36 |
37 | @dump: (tree) ->
38 | dumper = new Dumper
39 |
40 | estraverse.traverse tree,
41 | enter: (node) ->
42 | dumper.log("enter - #{node.type}")
43 |
44 | leave: (node) ->
45 | dumper.log("leave - #{node.type}")
46 |
47 | dumper.result()
48 |
--------------------------------------------------------------------------------
/client/js/experimentctrl.js:
--------------------------------------------------------------------------------
1 | scanjsModule.controller('ExperimentCtrl', ['$scope', 'ScanSvc', function ExperimentCtrl($scope, ScanSvc) {
2 | if (!document.getElementById("experiment-mirror").children.length) {
3 | $scope.codeMirror = new CodeMirror(document.getElementById('experiment-mirror'), {
4 | mode: 'javascript',
5 | lineNumbers: true,
6 | theme: 'mdn-like',
7 | value: "bar.foo\nfoo=something\nbaz.bar=stuff\nfoo(something)\nfoo.bar\nfoo.bar()\neval(test)\nfoo.innerHTML=danger",
8 | tabsize: 2,
9 | styleActiveLine: true
10 | });
11 | }
12 | $scope.results=[];
13 | $scope.ready=false;
14 | $scope.rule="eval()"
15 |
16 | var ruleData={
17 | "name": "manual rule",
18 | "source": $scope.rule,
19 | "testhit": $scope.rule,
20 | "testmiss": "",
21 | "desc": "Manual input.",
22 | "threat": "example"
23 | };
24 |
25 | $scope.runScan = function () {
26 | $scope.results=[];
27 | code = $scope.codeMirror.getValue();
28 | ScanJS.loadRules(ScanSvc.rules);
29 | $scope.results=ScanJS.scan(code);
30 | $scope.lastScan=$scope.runScan;
31 | };
32 |
33 |
34 | $scope.runManualScan = function () {
35 | ruleData.source=$scope.rule;
36 | ScanJS.loadRules([ruleData]);
37 |
38 | $scope.results=[];
39 | code = $scope.codeMirror.getValue();
40 | //put ast on global variable for debugging purposes.
41 | try{
42 | window.ast=acorn.parse(code);
43 | }catch(e){
44 |
45 | }
46 | //ScanJS.setResultCallback(found);
47 | $scope.results=ScanJS.scan(code);
48 | $scope.lastScan=$scope.runManualScan;
49 | };
50 |
51 | $scope.showResult = function (filename,line, col) {
52 | document.querySelector("#code-mirror-wrapper").classList.toggle("hidden",false);
53 | $scope.codeMirror.setCursor(line - 1, col || 0);
54 | $scope.codeMirror.focus();
55 | };
56 |
57 | $scope.add_placeholder_char = function() {
58 | $scope.rule += '$_any';
59 | }
60 | $scope.lastScan=$scope.runScan;
61 |
62 | }]);
63 |
--------------------------------------------------------------------------------
/client/js/scanservice.js:
--------------------------------------------------------------------------------
1 | scanjsModule.factory('ScanSvc', ['$rootScope', '$http', function($rootScope, $http) {
2 | var ScanService = {
3 | //results:[],
4 | ready:false,
5 | rules:null,
6 | init:function(rules){
7 | this.rules=rules;
8 | this.ready=true;
9 | },
10 | newScan: function(file,source) {
11 | var fileName = file || 'inline';
12 | this.scanWorker.postMessage({call: 'scan', arguments: [source, fileName]});
13 | },
14 | addResults: function(results) {
15 | $rootScope.$broadcast('NewResults', results);
16 | },
17 | loadRules:function(ruleData){
18 | this.rules=ruleData;
19 | this.scanWorker.postMessage({call: 'updateRules', rules: ruleData});
20 | }
21 | };
22 | ScanService.scanWorker = new Worker("js/scanworker.js");
23 | ScanService.scanWorker.addEventListener("message", function (evt) {
24 | if (('findings' in evt.data) && ('filename' in evt.data)) {
25 | if (evt.data.findings.length > 0) {
26 | if (evt.data.findings[0].type == 'error') {
27 | $rootScope.$broadcast('ScanError', evt.data.findings[0])
28 | return;
29 | }
30 | }
31 | ScanService.addResults(evt.data);
32 | }
33 | else if ('error' in evt.data) {
34 | // This is for errors in the worker, not in the scanning.
35 | // Exceptions (like SyntaxErrors) when scanning files
36 | // are in the findings.
37 | var exception = evt.data.error;
38 | if (e instanceof SyntaxError) {
39 | $rootScope.$broadcast('ScanError', {filename: evt.data.filename, name: exception.name, loc: exception.loc, message: exception.message })
40 | } else {
41 | throw e; // keep throwing unexpected things.
42 | }
43 | }
44 | });
45 |
46 | ScanService.scanWorker.onerror = function (e) { console.log('ScanWorker Error: ', e) };
47 |
48 | $http({method: 'GET', url: "../common/rules.json"}).
49 | success(function(data, status, headers, config) {
50 | ScanService.loadRules(data);
51 | });
52 |
53 | return ScanService;
54 | }]);
55 |
--------------------------------------------------------------------------------
/client/partials/experiment.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Results
24 |
25 |
26 |
27 |
28 | | Line |
29 | Rule |
30 | Source |
31 | Description of Issue |
32 |
33 |
34 |
35 | | Line {{result.line}}
36 | | {{result.rule.name }} |
37 | {{result.rule.source }} |
38 | {{result.rule.desc}}
39 | |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/client/partials/experiment.html~:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
57 |
58 |
59 |
60 |
61 |