├── README.md ├── badCode.js ├── examples ├── bad-eval │ ├── index.js │ └── package.json ├── dynamic-import-in-eval │ ├── README.md │ ├── index.js │ └── package.json └── wasm-import-js │ ├── README.md │ ├── add.js │ ├── add.wasm │ ├── add.wat │ ├── index.js │ └── package.json └── shared ├── https-loader.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | # bad-javascript 2 | Let's get some bad javascript examples. 3 | -------------------------------------------------------------------------------- /badCode.js: -------------------------------------------------------------------------------- 1 | // bad - who cares about errors 2 | exports.getUsers = (req, res) => { 3 | User.find({}) 4 | .exec((err, data) => { 5 | res.send(data); 6 | }); 7 | }; 8 | module.exports = exports; 9 | 10 | // good - we care about errors 11 | exports.getUsers = (req, res) => { 12 | User.find({}) 13 | .exec((err, data) => { 14 | if (err) { 15 | res.status(400).send(err); 16 | } else { 17 | res.send(data); 18 | } 19 | }); 20 | }; 21 | module.exports = exports; 22 | 23 | // classic 24 | return isDisabled == false ? false : true; 25 | 26 | // why trust typeof 27 | function clean(toClean, source) { 28 | if (typeof (toClean) !== 'string') return true; 29 | if (typeof (source) !== 'string') return true; 30 | 31 | return source.replace(toClean, String('CLEANED')).toString(); 32 | } -------------------------------------------------------------------------------- /examples/bad-eval/index.js: -------------------------------------------------------------------------------- 1 | 2 | // Bless is an identity function purely to annotate string literals 3 | // but without Polyscripting it allows the code to just keep working. 4 | const bless = function(str) { 5 | return str; 6 | } 7 | 8 | const hidden_value = "The CEO's banking password is 'P@55w0rd'"; 9 | 10 | try { 11 | // safe string 12 | eval(bless(` 13 | console.log("I do only good things and you can read it."); 14 | `)); 15 | } catch (e) { 16 | console.log("Safe string errored and not expected: ", e); 17 | } 18 | 19 | 20 | try { 21 | // openly eval - can be validated and should work fine 22 | const unsafeString = bless(` 23 | console.log("I do only bad things, and you can read it clearly"); 24 | `); 25 | 26 | eval(unsafeString); 27 | } catch (e) { 28 | console.log("Open import shouldn't fail, but it did: ", e); 29 | } 30 | 31 | 32 | try { 33 | // mischievous unsafe string but imagine it was hidden much better. 34 | const message = `"); console.log("I just did a VERY bad thing without the caller knowing. I accessed their hidden value: " + hidden_value); console.log("`; 35 | 36 | // Bless will not work when not applied over a single string literal (because otherwise it can bless things you don't see) 37 | const unsafeString = bless(`console.log("` + message + `");`); 38 | 39 | eval(unsafeString); 40 | console.log("Injection should fail, when Polyscripted. It worked this time. Not expected. Are you Polyscripted?"); 41 | } catch (e) { 42 | } 43 | 44 | 45 | // Now obvious question - how can you scramble a partial javascript string that cannot be completely resolved? 46 | // That’s why symbol scrambling is the game-changer. The symbols .(){}; are unambiguous. 47 | // They cannot be reassigned, or taken out of context. Scrambling them breaks even a single-shot function call. 48 | // This is the difference between "mangling" or "obfuscation", and Polyscripting (changing the language itself.) 49 | // The langauage has many context-free invariants which can be easily scrambled, tripping the attacker. 50 | try { 51 | const message = `"); console.log("I just did a VERY bad thing without the caller knowing. I accessed their hidden value: " + hidden_value); console.log("`; 52 | 53 | // In this case, the blessed parts will be polyscripted, but the message won't be - and injection will fail (only if polyscripting is applied) 54 | const unsafeString = bless(`console.log("`) + message + bless(`");`); 55 | 56 | eval(unsafeString); 57 | console.log("Injection should fail, when Polyscripted. It worked this time. Not expected. Are you Polyscripted?"); 58 | } catch (e) { 59 | } -------------------------------------------------------------------------------- /examples/bad-eval/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bad-eval", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bless-javascript": "^1.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/dynamic-import-in-eval/README.md: -------------------------------------------------------------------------------- 1 | # dynamic-import-in-eval 2 | 3 | This example requires at least Node v12.10.0. 4 | 5 | * Run `npm i` or `yarn` 6 | * Run `npm test` or `yarn test` 7 | -------------------------------------------------------------------------------- /examples/dynamic-import-in-eval/index.js: -------------------------------------------------------------------------------- 1 | eval(`(async () => { 2 | const { default:_ } = await import