• Stars
    star
    335
  • Rank 125,904 (Top 3 %)
  • Language
    JavaScript
  • Created about 11 years ago
  • Updated about 11 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Go on an educational Web security adventure!

Build Status

This repository contains an exciting quest to learn about Web security by learning about vulnerabilities, exploiting them, and then crafting code to protect against them.

Prerequisites

Before embarking on this adventure, make sure you have the skills taught in learnyounode and levelmeup.

Also, make sure phantomjs is installed and on your path (as well as node 0.10 and npm).

Start The Adventure!

Via npm

Start the adventure like so:

sudo npm install -g security-adventure
security-adventure

That's all there is to it; the security-adventure program will instruct you further.

Via git

Alternatively, you can clone this git repository and follow the instructions in the rest of this README:

git clone https://github.com/toolness/security-adventure.git
cd security-adventure
npm install
cp app-vulnerable.js app.js

app.js is a full web application in about 150 lines of code that allows users to create password-protected accounts and store private plaintext notes in the cloud.

Run node app.js and then browse to http://localhost:3000 to familiarize yourself with the behavior of the application by creating a user and saving some notes. Then read the source of app.js to get a basic idea of how everything works.

app.js contains lots of vulnerabilities, and your quest is to learn about and fix all of them!

Vulnerability: Regular Expression Denial of Service

The regular expression used to validate usernames has a Regular Expression Denial of Service vulnerability in it.

Read about this vulnerability, and then try exploiting it manually by visiting the app in your browser and entering an invalid username that will cause the app to hang.

Then fix app.js.

Run bin/verify.js redos to verify that your solution works.

Vulnerability: Reflected Cross Site Scripting

The home page of the app accepts a msg querystring argument containing a hex-encoded status message to display. This is used, for instance, when users fail to authenticate properly and the server needs to provide feedback.

This isn't exactly a best practice for various reasons, but most importantly, it contains a Reflected Cross Site Scripting vulnerability!

Read about the vulnerability, and then try crafting a URL that, when visited, causes a logged-in user's browser to display an alert dialog that contains their session cookie (accessible through document.cookie).

Stopping Cookie Theft

Cookie theft is a particularly big danger because it allows attackers to do anything on a user's behalf, whenever they want. So first, mitigate the effects of XSS vulnerabilities by modifying sessionCookie.serialize() in app.js to issue HttpOnly cookies.

Manually test your solution by loading your specially crafted URL from the previous section; you shouldn't see the session cookie in that alert dialog anymore (you will have to log out and log back in for the HttpOnly cookie to be set properly).

Run bin/verify.js httponly to verify that your solution works.

Defining a Content Security Policy

It's nice that the damage that can be done via the XSS attack is somewhat mitigated, but it's way better to prevent the attack entirely!

The Content Security Policy specification is one of the most awesome security innovations to come to browsers in recent years. It allows servers to change the default allowances for what kinds of script can be executed, and even what kinds of embedded resources (such as iframes, images, and style sheets) can be included in a page. This is in accordance with the Principle of Least Authority, which is a good best practice for any secure system.

Since our app doesn't actually have any client-side script or embedded content, we can enforce the most restrictive CSP possible by setting the Content-Security-Policy header to default-src 'none'.

Once you've done this, load your specially crafted URL again; you shouldn't even see an alert dialog, and your browser's debugging console might even explain why your JS wasn't executed.

Run bin/verify.js csp to verify that your solution works.

Stopping XSS with HTML Escaping

CSP is only available on the most modern browsers, and we need to protect users on older ones too. Besides that, of course, we actually want to display the message content in a correct and useful way.

This can be done by properly escaping the untrusted input coming in from the msg querystring argument.

The OWASP XSS Prevention Cheat Sheet is indispensable here. Check it out and use a reliable function like underscore's _.escape to escape the msg argument before inserting it into your HTML. (Note that if you decide to use underscore, you'll want to install it first using npm install underscore.)

Run bin/verify.js html-escaping to verify that your solution works.

Vulnerability: Cross-Site Request Forgery

Cookies are a form of ambient authority, which means that they get sent with every request to a website--even when that request comes from a different website!

Consider a website called killyournotes.com which contains the following form:

<body onload="document.forms[0].submit()">
  <form method="POST" action="http://localhost:3000/">
    <input type="hidden" name="notes" value="gotcha.">
  </form>
</body>

Every user logged in to your application would immediately have their notes deleted whenever they visited killyournotes.com!

Try doing this now: copy the above text and paste it into an HTML file anywhere. Then visit the file in your browser and see what happens.

This is called a Cross-Site Request Forgery (CSRF) because it involves another site "forging" a request to your application and taking advantage of the ambient authority provided by cookies. In security parlance, your application has unwittingly become a confused deputy.

This exploit can be protected against by requiring that every incoming request that changes your application's state (e.g. a POST request) also come with an explicit token guaranteeing that the request indeed came from a page on your site, and not someone else's.

To complete this mission, you'll need to do a number of things:

  • When a GET request arrives at your application, check to see if the session has a value called csrfToken. If it doesn't, create one using crypto.randomBytes() and set the session cookie.

  • Whenever your site displays a form, add a hidden input with the name csrfToken to the form, and set its value to that of session.csrfToken.

  • Whenever your site processes a POST request, ensure that the incoming form data has a value for csrfToken that matches that of session.csrfToken. If it doesn't, return a 403 (forbidden) reponse code.

Once you've done this, your exploit should result in a 403 instead of deleting the current user's notes, and your application should still retain all existing functionality.

Run bin/verify.js csrf to verify that your solution works.

Hooray!

You've completed all the challenges so far. You can verify that your app.js protects against all the problems you've solved, and still retains its basic functionality, by running bin/verify.js all.

If you want to learn more about Web security, you should read Michal Zalewski's The Tangled Web. It is hilarious and very educational.

Goals and Future Plans

app-vulnerable.js intentionally contains a number of OWASP-defined security vulnerabilities that aren't currently part of the quest, such as:

Learners should first exploit these vulnerabilities, so they understand how they work, and then modify the code to implement defenses against them.

Ideally, the tutorial will also teach users about more recent innovations in browser security, such as HTTP Strict Transport Security. It should also teach developers how to use security tools like the Zed Attack Proxy to easily detect for vulnerabilities in their own applications.

By the end of the tutorial, users will have familiarized themselves with a variety of types of attacks. The will also have familiarized themselves with the OWASP website and will be equipped to independently learn about security in the future.

More Repositories

1

slowmo-js

Execute JavaScript in slow motion.
JavaScript
351
star
2

accessible-color-matrix

An Elm-based prototype to help designers build accessible color palettes.
JavaScript
323
star
3

p5.js-widget

A reusable widget for embedding editable p5 sketches in web pages.
TypeScript
160
star
4

webxray

Web X-Ray Goggles provide a simple, easy way for non-technical people to inspect Web pages and learn about how they are put together.
JavaScript
57
star
5

instapoppin

Make Popcorn with just HTML and CSS.
JavaScript
48
star
6

postmessage-proxied-xhr

A simple polyfill for cross-origin ajax requests.
JavaScript
41
star
7

jsondown

A drop-in replacement for LevelDOWN that writes to a JSON file on disk.
JavaScript
35
star
8

tap-prettify

Make Test Anything Protocol test runner output nicely readable.
JavaScript
35
star
9

bugzilla-dashboard

A simple HTML dashboard for Mozilla's Bugzilla instance.
JavaScript
32
star
10

quickpreso

Quickly prototype presentations the same way you prototype HTML pages.
Python
30
star
11

brocco

A port of docco to the browser.
JavaScript
29
star
12

boromir

A text-based re-enactment of Boromir's death scene from The Fellowship of the Ring.
JavaScript
26
star
13

steampunk

Simple web-based IRC client with integrated bouncer.
JavaScript
23
star
14

passage-emscripten

Jason Rohrer's game "Passage" (2007), ported to the web via Emscripten.
C++
20
star
15

csharpbindgen

A Rust library for generating C# bindings from Rust code.
Rust
20
star
16

hackasaurus-parable

The Parable of The Hackasaurus - an experiment in interactive narrative.
JavaScript
20
star
17

css-selector-game

A very simple mobile-friendly game that teaches CSS selectors.
JavaScript
19
star
18

htmlpad

Use Etherpad to write and collaborate on HTML, CSS, and JavaScript.
Python
15
star
19

friendly-error-fellowship

Documentation and materials for Jess Klein and Atul Varma's 2016 Processing Fellowship
JavaScript
13
star
20

tiny-turtle

Minimalist canvas-based turtle graphics in 50 lines of JS.
JavaScript
13
star
21

p5.js-docker

Experimental docker setup to make p5.js + p5js.org development easier.
JavaScript
12
star
22

chicago-badge-studio

Badge image creation tool for Chicago Summer of Learning.
JavaScript
11
star
23

animated-focus-ring

Animate the focus ring so keyboard users have an easier time locating it.
JavaScript
11
star
24

pybugzilla

Python library and command-line tools for interacting with Bugzilla via Gervase Markham's REST API.
Python
10
star
25

werewolves-and-wanderer-rs

A Rust implementation of the first project from Tim Hartnell's book "Creating Adventure Games on Your Computer".
Rust
10
star
26

mp4-to-gif

Simple webpage that converts MP4 videos to animated GIFs.
JavaScript
9
star
27

openbadges.org

Website for Mozilla's Open Badges project.
JavaScript
9
star
28

django-browserid-auth

A Django auth backend for BrowserID.
Python
8
star
29

lovebomb.me

Create, publish, and remix love bombs using HTML and CSS.
JavaScript
8
star
30

descrambler-games

Games/challenges built around the idea of "descrambling" source code via touch/drag-and-drop.
JavaScript
8
star
31

minicade

Collaboratively create an arcade of HTML-5 based minigames with your friends.
JavaScript
7
star
32

alternafox

Install and update Firefox Aurora and Nightly on OSX as separate browsers with their own profiles.
Python
6
star
33

stubbyid

A simple client-side "simulator" for the Persona login service.
JavaScript
6
star
34

blockly-dom-tutorial

A tutorial on the Document Object Model using Blockly.
JavaScript
6
star
35

tiny-conference

Simple conference with Twilio using an Etherpad as a back-channel.
JavaScript
6
star
36

all-my-etherpads

A simple mobile web app for storing etherpads offline.
Python
6
star
37

pode

A simple code editor for beginners who are visually impaired.
Python
6
star
38

mobile-microgame-maker

Attempt at building a mobile microgame maker for Minicade.
JavaScript
6
star
39

electron-youtube-docker-dl

A weird Electron app that downloads videos via a Dockerized youtube-dl container.
TypeScript
6
star
40

paint-manhattan

A web-based game to help players learn the history of Manhattan, as told by its streets.
TypeScript
5
star
41

fleeting

Easily spin up experimental project branches in short-lived EC2 instances.
JavaScript
5
star
42

addons-builder-helper

A Firefox addon for use with the Mozilla Add-ons Builder (formerly known as FlightDeck).
JavaScript
5
star
43

badge-microformat-fun

Proof of concept of open badges as an HTML microformat.
CSS
5
star
44

jetpack-e10s

Jetpack + Electrolysis Integration Package (out-of-process Jetpack)
JavaScript
5
star
45

web-audio-synth

Just some experimentation with web audio synthesis.
JavaScript
5
star
46

badgemaker-prototype

Prototype for an SVG-based badge maker.
JavaScript
5
star
47

pathfinder-unity-fun

Attempting to build a Unity native plugin for Pathfinder's Canvas API.
Rust
5
star
48

twitblob

A tiny JSON bin for every Twitter user, usable anywhere on the Web.
Python
5
star
49

storything

Prototype to teach journalists the basics of HTML/CSS.
JavaScript
5
star
50

webmaking-tutorial-prototype

Prototype tutorial and code challenge for Mozilla's Webmaking 101 initiatives
JavaScript
5
star
51

simple-live-screen-casting

A futile, hackneyed attempt at simple live screen-casting for OS X.
C
5
star
52

hackasaurus-puppet-data

An attempt to concisely define the server configuration for Hackasaurus sites.
Python
4
star
53

texas-hold-em-buddy

A simple tool to perform analysis of Texas Hold 'Em games.
Rust
4
star
54

nyc-421a-xls

A scraper to convert NYC's 421a excel workbooks into a single massive CSV file.
Python
4
star
55

vignelli-mta-map

Static, offline-capable version of Massimo Vignelli's 2011 NYC subway map.
Python
4
star
56

algorithm-fun

Experiments with algorithms and stuff.
JavaScript
4
star
57

kitchen-party

Gather round the kitchen with friends and play.
JavaScript
4
star
58

moo-web

A MOO server exposed through a Web interface with a Parchment-like look and feel.
C
4
star
59

openbadges-site-prototype

Prototype site for openbadges.org, using a wiki as a back-end content store.
JavaScript
4
star
60

blockly-l10n-editor

Prototype for editing non-trivial localization content using Blockly.
JavaScript
4
star
61

badgelab

Pedagogical website that makes it easy to create "hand-made" Open Badges badges.
JavaScript
4
star
62

weblitmapper

Submit Web Literacy Map resources via a bookmarklet.
JavaScript
4
star
63

throxode

A simple throttling HTTP proxy for node.js.
JavaScript
4
star
64

reviewer-dashboard

Simple prototype of a Jetpack code reviewer dashboard
JavaScript
4
star
65

hashsync

Reasonably simple syncing for remote HTML presentations.
JavaScript
3
star
66

memory-profiler

A prototype Firefox add-on that helps you debug a Web page's memory usage.
Python
3
star
67

simplesauce

Simple webdriver/saucelabs CI for static HTML5 projects.
JavaScript
3
star
68

weekly-meeting-slideshow

Prototype to convert Mozilla project-wide meeting wiki page into a slideshow.
JavaScript
3
star
69

docker-uswds

Dockerized development environment for the U.S. Web Design Standards and their docs.
JavaScript
3
star
70

teenydoh

A simple tool for building fully static, internationalized websites. Upgrades to Playdoh.
JavaScript
3
star
71

mozcamp-quilt

A community quilt for MozCamp.
JavaScript
3
star
72

nodepad

Pathetic attempt at my first node.js app.
JavaScript
3
star
73

mas-bebe-itvs-sprint

HTML5 presentation for the ยฟMรกs Bebรฉs? documentary created during the Mozilla+ITVS Popcorn sprint.
JavaScript
3
star
74

daily-edition

Information in moderation: stay informed about what your friends and colleagues are writing about without being overwhelmed.
Python
3
star
75

podsheets

RSS podcast feeds sourced from Google spreadsheets.
JavaScript
3
star
76

hackasaurus-sharing-addon

Add-on that enables sharing of Hackasaurus hacks.
Python
2
star
77

hack-battle-prototype

Prototype for a Hack Battle at the Mozilla Festival 2011
JavaScript
2
star
78

badgepad

Issue Open Badges as static files from the command-line.
Python
2
star
79

mozilla-learning-html

Initial attempt at implementing Webmaker Learning front-page.
HTML
2
star
80

pakreport-jetpack

A Jetpack to make it easier to do CrisisCamp-related stuff on the web.
JavaScript
2
star
81

loldevops

Hilariously lightweight DevOps substitute for experimental projects.
JavaScript
2
star
82

phantom-wd-runner

Run a PhantomJS WebDriver server in a separate process.
JavaScript
2
star
83

justfix-interview-ts-fun

A TypeScript-based interview flow experiment for JustFix.nyc.
TypeScript
2
star
84

addon-sdk-textmate-bundle

A TextMate bundle for Mozilla's Add-on SDK.
2
star
85

geomancer

Very basic node-powered app to track the location of friends.
JavaScript
2
star
86

placedkitten

A tool designed to facilitate learning how web servers and the HTTP protocol work.
JavaScript
2
star
87

hackasaurus-print

Simple web page that allows printing of Hackasaurus hacks.
JavaScript
2
star
88

cooa

Choose Our Own Adventure: a web-based microframework that makes it possible to collaboratively author and play hypertext narratives.
JavaScript
2
star
89

mix-master-dialog

Dialog for the X-Ray Goggles remix functionality.
JavaScript
2
star
90

rust-nycdb-csv-fun

An exploration into updating NYC-DB faster with Rust.
Rust
2
star
91

planet-badges

Ridiculously simple planet-style feed aggregator.
JavaScript
2
star
92

netcode-fun

An exploration of delay and rollback-based netcode in a simulated network environment.
TypeScript
2
star
93

png-baker.js

Easily read/write custom textual data to/from PNG files in the browser.
JavaScript
2
star
94

top-hat

Experimental needs-based AI
JavaScript
2
star
95

bug-616472-extension

An extension to test out assumptions about Firefox bug 616472, "Unify sizes of toolbarbutton images to make life easier for extensions"
2
star
96

github-l10n-fun

Attempting to do L10n through GitHub.
JavaScript
2
star
97

browserid-cors

Express middleware for creating BrowserID-authenticated, CORS-enabled REST APIs.
JavaScript
2
star
98

apple-6502-fun

Exploring 6502 assembly with the Apple II.
Assembly
2
star
99

css-ribbonate

Make "Fork me on GitHub"-style ribbons using plain ol' HTML. Also includes a "Remix Me on Webmaker" ribbon with extra functionality for Thimble.
JavaScript
2
star
100

ethercoaster

One simple Meteor-based solution to the problem of constantly crashing etherpads.
JavaScript
2
star