Defensive Coding

and Hardened JavaScript


built for DEFCON31,
updated for NodeConfEU, Confidence, X33fcon
and now JSNation!

by @naugtur
### how to participate? # 🧑‍💻👩‍💻 > - Find someone to pair with. I mean it! - Clone the exercise repo. Both of you. 😉 https://github.com/naugtur/js-training-examples

Who's that guy?


https://naugtur.pl

npm logo gobble
Wouldn't it be great to fearlessly use them like we did back in 2015?
npm logo gobble
What if a package turns malicious?

exfiltration

fetch, process.env

prototype pollution

RCE

fs

event-stream

### JS can be tweaked and it's no accident - designed in 10 days - humbly assuming there's room for improvement
## polyfills #### and ## prototype poisoning #### are the same thing #### with different intentions
## Prototype poisoning # 🧪🍏 ![]() ```js const a = {}; Object.prototype.toString = ()=>'👻'; console.log(`scary object: ${a}`); ``` ``` scary object: 👻 ```
## exercise time! ## 🏋️ [js-training-examples -> defensive coding](https://github.com/naugtur/js-training-examples)
### Should we reinvent ### the wheel? [ses/src/commons.js](https://github.com/endojs/endo/blob/master/packages/ses/src/commons.js)
### does it scale? how to convince the entire ecosystem to use it? #### We don't really have to
# 🤯 ### JS design is good for security? - Take ECMA + W3C - Add Conway's Law - Separation between language and APIs - Power only reachable through scope #### All we need to do is control scope
process
window
Lambda function
ClFl worker
iframe
thread
process
process
process
📦
📦
ClFl worker
iframe
thread
process
process
process
📢
👂
worker
isolate
thread
process
process
process
### Object Capability vs identity based security - code gets references to capable objects - code doesn't "work on your behalf"
### Object Capability You already know how to use it ```js import { lint } from 'some-linter' import { readFile } from 'node:fs/promises' const fs = { readFile } lint({ fs }) ```
### Object Capability This is called attenuation BTW ```js import { lint } from 'some-linter' import { readFile } from 'node:fs/promises' const fs = { readFile: async (path) => { if(!allowed(path)) { throw Error('nope') } return readFile(path) }, } lint({ fs }) ```
### Hardened Javascript [https://hardenedjs.org](https://hardenedjs.org) - `Compartment` - scope isolation - `lockdown` - makes your Realm secure - `harden` - protects capable objects
#### `lockdown()` #### is #### `Object.freeze()` #### on steroids # 💪
#### So do we need to convince the ecosystem to use OCAP style?
# No! ### There's an app for that
## Story time

Let's install some dependencies!

Ok, catch this: 📦

I'm not runing that.

That's what you think.

npm docs for lifecycle scripts

            "postinstall": "echo 💩 > /etc/hosts"
        
### Ok, wait ``` ✨🐋 npm ci cp node_modules s3:// 🔥🔥🐋🔥🔥 ```

Hold my 🍺


├─app.ts
├─node_modules
│ ├─@naugtur
│ │ └─evilpackage
| │   ├─evilPlots.js --,
| │   └─package.json   |
│ └─typescript         💩
│   ├─lib              |
│   | └─tsc.js <-------'
│   └─package.json
└─package.json
        
## ignore scripts ``` npm ci --ignore-scripts ``` Run selected scritps ``` npm rebuild bcrypt ```
# Oh 💩
#### look what I found! ![lavamoat](./lavamoat-logo.png)

And in that moment
the installation process was protected

#### How about this package? > Dear ${ eslintPluginMaintainer }, > I understand you're busy and I'd be happy to help with maintenance of your tiny but popular plugin...

(Or find a common hallucination to [slopsquat](https://socket.dev/blog/slopsquatting-how-ai-hallucinations-are-fueling-a-new-class-of-supply-chain-attacks))
#### ok, just in case you do ![](./ilus/obfuscated.png)
#### yo, there's an app for that! ![lavamoat](./lavamoat-logo.png)
# how ?! ![](./ilus/hacker3.png)
### I can do frontend too LavaMoat webpack plugin 1.0

I could help you set up LavaMoat in your project

@naugtur   naugtur.pl

naugtur.pl/training

@naugtur   naugtur.pl

naugtur.pl/training