├── .gitignore ├── README.md ├── bcrypt-sample ├── index.js └── package.json ├── git-ssh └── rotate-ssh-keys.sh ├── helmet ├── package.json ├── server.js └── static │ └── index.html ├── https-server ├── .gitignore ├── package.json └── server.js ├── mixed-content ├── http │ └── index.html ├── https │ └── index.html ├── httpserver.js ├── httpsserver.js └── package.json └── xss ├── index.html ├── package.json ├── results.html ├── safe.html └── shibe.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | *.pem 2 | node_modules 3 | npm-debug.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Intro to Security for Developers 2 | 3 | An incomplete introduction to security for developers. Topics include device security, account security, developer tools security, and application security (SSL/TLS, cross-site scripting, authentication systems, information disclosure, and common security headers). 4 | 5 | Also check out my [personal security checklist](https://github.com/alulsh/personal-security-checklist) for handy checklist to secure your devices and accounts. 6 | 7 | ## Presentation 8 | 9 | Slides are available on my website at [www.alexandraulsh.com/intro-to-security-for-developers/slides](http://www.alexandraulsh.com/intro-to-security-for-developers/slides/#/). They are hosted on the `gh-pages` branch of this repo. 10 | 11 | ### View slides locally 12 | 13 | If you'd like to view the presentation locally: 14 | 15 | ```sh 16 | git clone git@github.com:alulsh/intro-to-security-for-developers.git 17 | git checkout gh-pages 18 | cd slides 19 | npm install 20 | npm start 21 | ``` 22 | 23 | Your default web browser should open the slides on `http://localhost:8000/#/` automatically. 24 | 25 | ### Presentation History 26 | 27 | I've given this presentation at the following events. I've tagged each presentation as a release in this repo. 28 | 29 | | Event | Date | Release | 30 | |-------|------|---------| 31 | | [Women Who Code DC Tech Talk](https://www.meetup.com/Women-Who-Code-DC/events/235989630/) | Feburary 9th, 2017 | `wwcdc-tech-talk` | 32 | | [Mapbox Miniconf](https://miniconfmapbox.splashthat.com/) | October 8th, 2016 | [`mapbox-miniconf`](https://github.com/alulsh/intro-to-security-for-developers/releases/tag/mapbox-miniconf) | 33 | | [Tech Lady Hackathon #4](http://techladyhackathon.org/) | October 22nd, 2016 | [`techlady-hackathon-2016`](https://github.com/alulsh/intro-to-security-for-developers/releases/tag/techlady-hackathon-2016) | 34 | 35 | ## Code Samples 36 | 37 | This presentation uses code samples written in Node.js to interactively teach security concepts. The code samples are hosted in the default `code-samples` branch. 38 | 39 | I do not host these demos on my website since it uses GitHub Pages (can't run a web server) and I don't want live cross-site scripting vulnerabilities on my domain. These demos must be run locally on your machine or on a cloud IDE such as [Cloud9](https://c9.io/). 40 | 41 | ### Prerequisites 42 | 43 | You will need to install [node.js](https://nodejs.org/en/download/) and [npm](https://docs.npmjs.com/getting-started/installing-node) in order to use these code samples. I recommend installing node.js with [nvm](https://github.com/creationix/nvm) (Node Version Manager). 44 | 45 | I used node 4.6.0 and npm 2.15.9 to create these code samples, but they may work on earlier or later versions of node/npm. If the samples don't work on your machine, try them with Node 4.6.0 (`nvm install 4.6.0` if you use nvm) and npm 2.15.9 before opening up an issue. 46 | 47 | ### Installation 48 | 49 | To install the code samples: 50 | 51 | ```sh 52 | git clone git@github.com:alulsh/intro-to-security-for-developers.git 53 | cd 54 | npm install 55 | npm start 56 | ``` 57 | 58 | For example, to run the cross-site scripting demos: 59 | 60 | ```sh 61 | git clone git@github.com:alulsh/intro-to-security-for-developers.git 62 | cd xss 63 | npm install 64 | npm start 65 | ``` 66 | 67 | ## License 68 | 69 | These slides and code samples are open source so I can more easily share them with the world. If you want to re-use them, give me credit or a shout out and let me know! I'd love to hear how you are using them. 70 | 71 | ## Questions? 72 | 73 | Create a new GitHub issue or Tweet at me - [@AlexUlsh](https://twitter.com/AlexUlsh). -------------------------------------------------------------------------------- /bcrypt-sample/index.js: -------------------------------------------------------------------------------- 1 | var bcrypt = require('bcrypt'); 2 | var password = 'supersecurepassword' 3 | var saltRounds = 10; 4 | 5 | bcrypt.hash(password, saltRounds, function(err, hash) { 6 | console.log('The password is ' + password + ' with ' + saltRounds + ' salt rounds'); 7 | console.log('The password hash is ' + hash); 8 | 9 | // Compare password to the hash in your database 10 | bcrypt.compare(password, hash, function(err, res) { 11 | // res should be "true" 12 | console.log(res); 13 | }); 14 | 15 | // Compare a bad password to what's in your database 16 | bcrypt.compare('not my actual password', hash, function(err, res) { 17 | // res should be "false" 18 | console.log(res); 19 | }); 20 | 21 | }); -------------------------------------------------------------------------------- /bcrypt-sample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bcrypt-sample", 3 | "version": "1.0.0", 4 | "description": "Sample code to learn bcrypt", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node index.js" 9 | }, 10 | "author": "Alexandra Ulsh", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcrypt": "^1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /git-ssh/rotate-ssh-keys.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is for OS X and should not be executed 4 | # This is a consolidatation of all commands for easier copying and pasting 5 | 6 | # Backup current ssh folder 7 | cp -a ~/.ssh ~/ssh-backup 8 | 9 | # Go ahead and generate a strong pass phrase for your SSH keys using 1Password or another tool 10 | open -a 1Password 11 | 12 | # Generate new SSH key pair with a passphrase 13 | ssh-keygen -t rsa -b 4096 -C "your_email@email.com" -f ~/.ssh/id_rsa 14 | 15 | # Start the ssh-agent 16 | eval "$(ssh-agent -s)" 17 | 18 | # Add newly generated SSH key to the SSH agent and add to OS X Keychain 19 | ssh-add -K ~/.ssh/id_rsa 20 | 21 | # Add your public SSH Key to your Github account - do manually on the website 22 | # Emphasis on public - file extension should be .pub 23 | pbcopy < ~/.ssh/id_rsa.pub 24 | open https://github.com/settings/ssh 25 | 26 | # Login to Github with the new SSH key to verify 27 | ssh -T git@github.com -i ~/.ssh/id_rsa 28 | 29 | # Remove old SSH key from Github 30 | open https://github.com/settings/ssh 31 | 32 | # Get the key fingerprint of your old public key from the backup copy 33 | ssh-keygen -E md5 -lf ~/ssh-backup/id_rsa.pub -------------------------------------------------------------------------------- /helmet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helmet-example", 3 | "version": "1.0.0", 4 | "description": "Example server running helmet for Intro to Security for Developers presentation", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.14.0", 14 | "helmet": "^2.3.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /helmet/server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var http = require('http'); 3 | var fs = require('fs'); 4 | var express = require('express'); 5 | var helmet = require('helmet'); 6 | var app = express(); 7 | 8 | // var options = { 9 | // key: fs.readFileSync('privatekey.pem'), 10 | // cert: fs.readFileSync('cert.pem') 11 | // } 12 | 13 | http.createServer(app).listen(3000, function(err){ 14 | if (err) throw err; 15 | console.log('Server started on port 3000'); 16 | }); 17 | 18 | app.use(helmet()) 19 | 20 | app.use('/', express.static('static')); -------------------------------------------------------------------------------- /helmet/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mixed Content 6 | 7 | 8 | 9 |

Helmet Expressjs Module

10 |

Open up your browser developer tools network console, and see that the following headers are configured on an HTTP website:

11 |
    12 |
  1. X-Content-Type-Options:nosniff
  2. 13 |
  3. X-DNS-Prefetch-Control:off
  4. 14 |
  5. X-Download-Options:noopen
  6. 15 |
  7. X-Frame-Options:SAMEORIGIN
  8. 16 |
  9. X-XSS-Protection:1; mode=block
  10. 17 |
18 | 19 | -------------------------------------------------------------------------------- /https-server/.gitignore: -------------------------------------------------------------------------------- 1 | *.pem 2 | node_modules -------------------------------------------------------------------------------- /https-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "https-server", 3 | "version": "1.0.0", 4 | "description": "Code sample for a simple HTTPS expressjs server", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "npm run cert && node server.js", 8 | "cert": "openssl req -x509 -newkey rsa:2048 -keyout privatekey.pem -out cert.pem -days 365 -subj '/C=US/ST=DC/O=MyOrganization' -nodes", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "engines": { 12 | "node": "4.6.0", 13 | "npm": "2.15.9" 14 | }, 15 | "author": "Alexandra Ulsh", 16 | "license": "ISC", 17 | "dependencies": { 18 | "express": "^4.14.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /https-server/server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var https = require('https'); 3 | var fs = require('fs'); 4 | var app = express(); 5 | 6 | var options = { 7 | key: fs.readFileSync('privatekey.pem'), 8 | cert: fs.readFileSync('cert.pem') 9 | } 10 | 11 | https.createServer(options, app).listen(4000, function(err){ 12 | if (err) throw err; 13 | console.log('Server started on port 4000'); 14 | }); 15 | 16 | app.get('/', function (req, res) { 17 | res.header('Content-type', 'text/html'); 18 | return res.end('

Served over HTTPS

'); 19 | }); -------------------------------------------------------------------------------- /mixed-content/http/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mixed Content 6 | 7 | 8 | 9 | 10 |

Mixed Content

11 |

HTTP page with GIF served over HTTPS

12 | Cute shibe being pet by owner 13 |

No security issues here - everybody is happy.

14 | 15 | -------------------------------------------------------------------------------- /mixed-content/https/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mixed Content 6 | 7 | 8 | 9 |

Mixed Content

10 |

HTTPS page with meme served over HTTP

11 | Hipster shibe 12 | 13 | -------------------------------------------------------------------------------- /mixed-content/httpserver.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var http = require('http'); 3 | var app = express(); 4 | 5 | http.createServer(app).listen(3000, function(err){ 6 | if (err) throw err; 7 | console.log('Server started on port 3000'); 8 | }); 9 | 10 | app.use('/', express.static('http')); -------------------------------------------------------------------------------- /mixed-content/httpsserver.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var https = require('https'); 3 | var fs = require('fs'); 4 | var app = express(); 5 | 6 | var options = { 7 | key: fs.readFileSync('privatekey.pem'), 8 | cert: fs.readFileSync('cert.pem') 9 | } 10 | 11 | https.createServer(options, app).listen(4000, function(err){ 12 | if (err) throw err; 13 | console.log('Server started on port 4000'); 14 | }); 15 | 16 | app.use('/', express.static('https')); -------------------------------------------------------------------------------- /mixed-content/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mixed-content", 3 | "version": "1.0.0", 4 | "description": "Mixed content demo for Intro to Security for Developers presentation", 5 | "main": "httpsserver.js", 6 | "scripts": { 7 | "start": "npm run cert && node httpsserver.js", 8 | "cert": "openssl req -x509 -newkey rsa:2048 -keyout privatekey.pem -out cert.pem -days 365 -subj '/C=US/ST=DC/O=MyOrganization' -nodes", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "Alexandra Ulsh", 12 | "license": "ISC", 13 | "dependencies": { 14 | "express": "^4.14.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /xss/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | XSS Demos 6 | 7 | 8 | 9 |

Best Shibe Memes Site

10 | shibe 11 |

Search our database of the best shibe memes!

12 | 13 | 14 |

See a random shibe!

15 | 16 |

Search for <svg onload=alert(1)> if you want to see a cute shibe!

17 | 18 |

Worried about bad doges? Try Shibe Safe Search

19 | 20 | 21 | 22 | 33 | 34 | -------------------------------------------------------------------------------- /xss/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xss-demos", 3 | "version": "1.0.0", 4 | "description": "XSS demos for Intro to Security for Developers presentation", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "serve", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Alexandra Ulsh", 11 | "license": "ISC", 12 | "dependencies": { 13 | "serve": "^11.2.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /xss/results.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | XSS Demos 6 | 7 | 8 | 9 |

Best Shibe Memes Site

10 |

Here are your doges

11 |
12 | 22 | 23 | -------------------------------------------------------------------------------- /xss/safe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | XSS Demos 6 | 7 | 8 | 9 | 10 |

Best Shibe Memes Site - SAFE SEARCH

11 |

Here are your doge results, no bad doges here!

12 |
13 | 23 | 24 | -------------------------------------------------------------------------------- /xss/shibe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alulsh/intro-to-security-for-developers/a6295558243724e29c8941422c812828fa7e4c7d/xss/shibe.jpg --------------------------------------------------------------------------------