├── .gitignore ├── A01 - Injection ├── app │ ├── models │ │ └── user.rb │ ├── actions.rb │ └── views │ │ └── index.erb ├── Rakefile ├── db │ ├── db.sqlite3 │ ├── migrate │ │ └── 1_create_users.rb │ ├── seeds.rb │ └── schema.rb ├── config.ru ├── config │ ├── database.rb │ └── environment.rb ├── Gemfile ├── README.md └── Gemfile.lock ├── A09 - Using Known Vulnerable Components ├── node_modules │ ├── .bin │ │ └── marked │ └── marked │ │ ├── doc │ │ ├── todo.md │ │ └── broken.md │ │ ├── .npmignore │ │ ├── index.js │ │ ├── .travis.yml │ │ ├── Makefile │ │ ├── component.json │ │ ├── LICENSE │ │ ├── package.json │ │ ├── man │ │ └── marked.1 │ │ ├── bin │ │ └── marked │ │ ├── README.md │ │ └── lib │ │ └── marked.js ├── package.json ├── server.js └── README.md ├── A06 - Sensitive Data Exposure ├── app │ ├── models │ │ └── user.rb │ ├── actions.rb │ └── views │ │ └── index.erb ├── Rakefile ├── config.ru ├── db │ ├── db.sqlite3 │ ├── migrate │ │ └── 1_create_users.rb │ ├── seeds.rb │ └── schema.rb ├── config │ ├── database.rb │ └── environment.rb ├── Gemfile ├── README.md └── Gemfile.lock ├── A03 - Cross-Site Scripting (XSS) ├── app │ ├── models │ │ └── user.rb │ ├── actions.rb │ └── views │ │ └── index.erb ├── Rakefile ├── config.ru ├── db │ ├── db.sqlite3 │ ├── migrate │ │ └── 1_create_users.rb │ ├── seeds.rb │ └── schema.rb ├── config │ ├── database.rb │ └── environment.rb ├── Gemfile ├── README.md └── Gemfile.lock ├── A05 - Security Misconfiguration ├── app │ ├── models │ │ └── user.rb │ ├── actions.rb │ └── views │ │ └── index.erb ├── Rakefile ├── db │ ├── db.sqlite3 │ ├── seeds.rb │ ├── migrate │ │ └── 1_create_users.rb │ └── schema.rb ├── config.ru ├── config │ ├── database.rb │ └── environment.rb ├── Gemfile ├── README.md └── Gemfile.lock ├── A10 - Unvalidated Redirects and Forwards ├── app │ ├── models │ │ └── user.rb │ ├── actions.rb │ └── views │ │ └── index.erb ├── Rakefile ├── config.ru ├── db │ ├── db.sqlite3 │ ├── migrate │ │ └── 1_create_users.rb │ ├── seeds.rb │ └── schema.rb ├── config │ ├── database.rb │ └── environment.rb ├── Gemfile ├── README.md └── Gemfile.lock ├── A07 - Missing Function Level Access Control ├── app │ ├── models │ │ └── user.rb │ ├── actions.rb │ └── views │ │ └── index.erb ├── Rakefile ├── config.ru ├── db │ ├── db.sqlite3 │ ├── migrate │ │ └── 1_create_users.rb │ ├── seeds.rb │ └── schema.rb ├── config │ ├── database.rb │ └── environment.rb ├── Gemfile ├── README.md └── Gemfile.lock ├── A02 - Broken Authentication and Session Management ├── app │ ├── models │ │ └── user.rb │ ├── actions.rb │ └── views │ │ └── index.erb ├── Rakefile ├── config.ru ├── db │ ├── db.sqlite3 │ ├── migrate │ │ └── 1_create_users.rb │ ├── seeds.rb │ └── schema.rb ├── config │ ├── database.rb │ └── environment.rb ├── Gemfile ├── README.md └── Gemfile.lock ├── A08 - Cross-Site Request Forgery (CSRF) ├── vulnerable_app │ ├── app │ │ ├── models │ │ │ └── user.rb │ │ ├── views │ │ │ └── index.erb │ │ └── actions.rb │ ├── Rakefile │ ├── config.ru │ ├── db │ │ ├── db.sqlite3 │ │ ├── migrate │ │ │ └── 1_create_users.rb │ │ ├── seeds.rb │ │ └── schema.rb │ ├── config │ │ ├── database.rb │ │ └── environment.rb │ ├── Gemfile │ ├── README.md │ └── Gemfile.lock ├── attacker_site.html └── README.md ├── OWASP Top 10 - 2013.pdf └── A04 - Insecure Direct Object References ├── app ├── models │ ├── note.rb │ └── user.rb ├── views │ ├── note.erb │ └── index.erb └── actions.rb ├── Rakefile ├── config.ru ├── db ├── db.sqlite3 ├── migrate │ ├── 2_create_notes.rb │ └── 1_create_users.rb ├── seeds.rb └── schema.rb ├── Gemfile ├── config ├── database.rb └── environment.rb ├── README.md └── Gemfile.lock /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /A01 - Injection/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/.bin/marked: -------------------------------------------------------------------------------- 1 | ../marked/bin/marked -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/doc/todo.md: -------------------------------------------------------------------------------- 1 | # Todo 2 | 3 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/.npmignore: -------------------------------------------------------------------------------- 1 | .git* 2 | test/ 3 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/app/actions.rb: -------------------------------------------------------------------------------- 1 | get '/' do 2 | @users = User.all 3 | erb :index 4 | end 5 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/marked'); 2 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | end 4 | -------------------------------------------------------------------------------- /OWASP Top 10 - 2013.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/OWASP Top 10 - 2013.pdf -------------------------------------------------------------------------------- /A01 - Injection/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A01 - Injection/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A01 - Injection/db/db.sqlite3 -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/app/models/note.rb: -------------------------------------------------------------------------------- 1 | class Note < ActiveRecord::Base 2 | 3 | belongs_to :user 4 | 5 | end 6 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | has_many :notes 4 | 5 | end 6 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/app/actions.rb: -------------------------------------------------------------------------------- 1 | get '/' do 2 | erb :index 3 | end 4 | 5 | get '/users' do 6 | User.all.to_json 7 | end 8 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "a09", 3 | "dependencies": { 4 | "marked": "v0.3.2" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /A01 - Injection/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "0.8" 5 | - "0.6" 6 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A05 - Security Misconfiguration/db/db.sqlite3 -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A06 - Sensitive Data Exposure/db/db.sqlite3 -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A03 - Cross-Site Scripting (XSS)/db/db.sqlite3 -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'sinatra/activerecord/rake' 3 | require_relative 'config/environment' 4 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A04 - Insecure Direct Object References/db/db.sqlite3 -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A10 - Unvalidated Redirects and Forwards/db/db.sqlite3 -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A07 - Missing Function Level Access Control/db/db.sqlite3 -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/config.ru: -------------------------------------------------------------------------------- 1 | require ::File.expand_path('../config/environment', __FILE__) 2 | set :app_file, __FILE__ 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /A01 - Injection/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A02 - Broken Authentication and Session Management/db/db.sqlite3 -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/db/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lighthouse-labs/owasp-top-10-examples/HEAD/A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/db/db.sqlite3 -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A01 - Injection/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | end 8 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/config/database.rb: -------------------------------------------------------------------------------- 1 | configure do 2 | set :database, { 3 | adapter: 'sqlite3', 4 | database: 'db/db.sqlite3' 5 | } 6 | require_relative '../app/models/user' 7 | require_relative '../app/models/note' 8 | end 9 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'rake' 2 | gem 'activesupport' 3 | gem 'sinatra' 4 | gem 'sinatra-contrib' 5 | gem 'sinatra-activerecord' 6 | gem 'puma' 7 | group :development do 8 | gem 'shotgun' 9 | gem 'sqlite3' 10 | end 11 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @cp lib/marked.js marked.js 3 | @uglifyjs -o marked.min.js marked.js 4 | 5 | clean: 6 | @rm marked.js 7 | @rm marked.min.js 8 | 9 | bench: 10 | @node test --bench 11 | 12 | .PHONY: clean all 13 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/db/migrate/2_create_notes.rb: -------------------------------------------------------------------------------- 1 | class CreateNotes < ActiveRecord::Migration 2 | def change 3 | create_table :notes do |t| 4 | t.string :title 5 | t.string :content 6 | t.references :user 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/attacker_site.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Totally Legit Website 5 | 6 | 7 |

Totally Legit Website

8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /A01 - Injection/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A01 - Injection/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/README.md: -------------------------------------------------------------------------------- 1 | # A03 - Cross-Site Scripting (XSS) 2 | 3 | This is a simple example of cross-site scripting. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/` 7 | 8 | Whoa! Somehow a script got injected into the page, and this page gets rendered for every user of the site. What happened? 9 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A03 - Cross-Site Scripting (XSS) 5 | 6 | 7 |

A03 - Cross-Site Scripting (XSS)

8 |

User list

9 | <% @users.each do |user| %> 10 |

<%= user.real_name %>

11 | <% end %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/app/views/note.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A04 - Insecure Direct Object References 5 | 6 | 7 |

A04 - Insecure Direct Object References

8 |

<%= @note.title %>

9 |

<%= @note.content %>

10 | 11 | 12 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "marked", 3 | "version": "0.3.2", 4 | "repo": "chjj/marked", 5 | "description": "A markdown parser built for speed", 6 | "keywords": ["markdown", "markup", "html"], 7 | "scripts": ["lib/marked.js"], 8 | "main": "lib/marked.js", 9 | "license": "MIT" 10 | } 11 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/README.md: -------------------------------------------------------------------------------- 1 | # A06 - Sensitive Data Exposure 2 | 3 | This is a simple example of a data leak. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - open your dev tools in your browser and go to the network tab 7 | - load `http://localhost:3000/` 8 | - open the content of the request to `/users` 9 | 10 | See anything that maybe shouldn't be there? 11 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/db/migrate/1_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :real_name 5 | t.string :email 6 | t.string :username 7 | t.string :password 8 | t.boolean :admin 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/db/seeds.rb: -------------------------------------------------------------------------------- 1 | User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | 9 | User.create( 10 | real_name: 'U. User ', 11 | email: 'user@example.net', 12 | username: 'user', 13 | password: 'user', 14 | admin: false 15 | ) 16 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/README.md: -------------------------------------------------------------------------------- 1 | # A05 - Security Misconfiguration 2 | 3 | This is a simple example of security misconfiguration. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/` 7 | - try to sign in with the username `o'reilly` 8 | 9 | Oh, snap! The default error pages are being displayed, revealing the security problem from the A01 10 | example for the world to see! 11 | -------------------------------------------------------------------------------- /A01 - Injection/app/actions.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def current_user 3 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 4 | end 5 | end 6 | 7 | get '/' do 8 | erb :index 9 | end 10 | 11 | post '/login' do 12 | user = User.find_by("username = '#{params[:username]}' AND password = '#{params[:password]}'") 13 | session[:user_id] = user.id if user 14 | redirect '/' 15 | end 16 | 17 | get '/logout' do 18 | session.clear 19 | redirect '/' 20 | end 21 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/app/actions.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def current_user 3 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 4 | end 5 | end 6 | 7 | get '/' do 8 | erb :index 9 | end 10 | 11 | post '/login' do 12 | user = User.find_by("username = '#{params[:username]}' AND password = '#{params[:password]}'") 13 | session[:user_id] = user.id if user 14 | redirect '/' 15 | end 16 | 17 | get '/logout' do 18 | session.clear 19 | redirect '/' 20 | end 21 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/app/actions.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def current_user 3 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 4 | end 5 | end 6 | 7 | get '/' do 8 | erb :index 9 | end 10 | 11 | post '/login' do 12 | user = User.find_by(username: params[:username], password: params[:password]) 13 | session[:user_id] = user.id if user 14 | redirect '/' 15 | end 16 | 17 | get '/logout' do 18 | session.clear 19 | redirect '/' 20 | end 21 | -------------------------------------------------------------------------------- /A01 - Injection/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A01 - Injection 5 | 6 | 7 |

A01 - Injection

8 | <% if current_user %> 9 |

Hi, <%= current_user.real_name %>

10 |

Sign out

11 | <% else %> 12 |
13 | 14 | 15 | 16 |
17 | <% end %> 18 | 19 | 20 | -------------------------------------------------------------------------------- /A01 - Injection/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/db/seeds.rb: -------------------------------------------------------------------------------- 1 | u = User.create( 2 | real_name: 'A. Administrator', 3 | email: 'admin@example.net', 4 | username: 'admin', 5 | password: 'admin', 6 | admin: true 7 | ) 8 | u.notes.create( 9 | title: 'An Admin Note', 10 | content: 'This is only for me, A. Administrator.' 11 | ) 12 | 13 | u = User.create( 14 | real_name: 'U. User', 15 | email: 'user@example.net', 16 | username: 'user', 17 | password: 'user', 18 | admin: false 19 | ) 20 | u.notes.create( 21 | title: 'A User Note', 22 | content: 'This is only for me, U. User.' 23 | ) 24 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/config/environment.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'sinatra' 3 | require 'sinatra/activerecord' 4 | require 'sinatra/contrib/all' 5 | 6 | APP_ROOT = Pathname.new(File.expand_path('../../', __FILE__)) 7 | 8 | configure do 9 | set :root, APP_ROOT.to_path 10 | set :server, :puma 11 | enable :sessions 12 | set :session_secret, ENV['SESSION_KEY'] || 'secret' 13 | set :views, File.join(Sinatra::Application.root, 'app', 'views') 14 | end 15 | 16 | require_relative '../config/database' 17 | require_relative '../app/actions' 18 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/app/actions.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def current_user 3 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 4 | end 5 | end 6 | 7 | get '/' do 8 | erb :index 9 | end 10 | 11 | post '/login' do 12 | user = User.find_by(username: params[:username], password: params[:password]) 13 | session[:user_id] = user.id if user 14 | redirect '/' 15 | end 16 | 17 | get '/logout' do 18 | session.clear 19 | redirect '/' 20 | end 21 | 22 | get '/admins_only' do 23 | 'This content is only available to authenticated administrators' 24 | end 25 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A05 - Security Misconfiguration 5 | 6 | 7 |

A05 - Security Misconfiguration

8 | <% if current_user %> 9 |

Hi, <%= current_user.real_name %>

10 |

Sign out

11 | <% else %> 12 |
13 | 14 | 15 | 16 |
17 | <% end %> 18 | 19 | 20 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/README.md: -------------------------------------------------------------------------------- 1 | # A10 - Unvalidated Redirects and Forwards 2 | 3 | This is a simple example to show an unvalidated redirect. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/must_be_logged_in` 7 | - sign in as the admin user with the username `admin` and password `admin` 8 | 9 | You should be redirected to `http://localhost:3000/must_be_logged_in`. Ok, now try: 10 | 11 | - sign out by going back and clicking the link 12 | - load `http://localhost:3000/?redirect_to=http://example.com/` 13 | - sign in again 14 | 15 | Wait, where are you now? 16 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/app/actions.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def current_user 3 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 4 | end 5 | end 6 | 7 | get '/' do 8 | @notes = current_user.notes if current_user 9 | erb :index 10 | end 11 | 12 | get '/notes/:id' do |id| 13 | @note = Note.find(id) 14 | erb :note 15 | end 16 | 17 | post '/login' do 18 | user = User.find_by(username: params[:username], password: params[:password]) 19 | session[:user_id] = user.id if user 20 | redirect '/' 21 | end 22 | 23 | get '/logout' do 24 | session.clear 25 | redirect '/' 26 | end 27 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/README.md: -------------------------------------------------------------------------------- 1 | # A07 - Missing Function Level Access Control 2 | 3 | This is a simple example to demonstrate function level access control. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/` 7 | - sign in as the admin user with the username `admin` and password `admin` 8 | - click the "For admins only" link 9 | 10 | All well and good. Next: 11 | 12 | - go back and sign out by following the link 13 | - now try reloading the page that the link took you to, `http://localhost:3000/admins_only` 14 | 15 | Well, ain't that a pity. Loads up without a fuss. 16 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A08 - Cross-Site Request Forgery (CSRF) 5 | 6 | 7 |

A08 - Cross-Site Request Forgery (CSRF)

8 | <% if current_user %> 9 |

Hi, <%= current_user.real_name %>

10 |

Sign out

11 | <% else %> 12 |
13 | 14 | 15 | 16 |
17 | <% end %> 18 | 19 | 20 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A02 - Broken Authentication and Session Management 5 | 6 | 7 |

A02 - Broken Authentication and Session Management

8 | <% if current_user %> 9 |

Hi, <%= current_user.real_name %>

10 |

Sign out

11 | <% else %> 12 |
13 | 14 | 15 | 16 |
17 | <% end %> 18 | 19 | 20 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/app/actions.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def current_user 3 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 4 | end 5 | end 6 | 7 | get '/' do 8 | erb :index 9 | end 10 | 11 | post '/login' do 12 | user = User.find_by(username: params[:username], password: params[:password]) 13 | session[:user_id] = user.id if user 14 | redirect params[:redirect_to] || '/' 15 | end 16 | 17 | get '/logout' do 18 | session.clear 19 | redirect '/' 20 | end 21 | 22 | get '/must_be_logged_in' do 23 | if current_user 24 | 'You have been authenticated if you can see this.' 25 | else 26 | redirect '/?redirect_to=/must_be_logged_in' 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A10 - Unvalidated Redirects and Forwards 5 | 6 | 7 |

A10 - Unvalidated Redirects and Forwards

8 | <% if current_user %> 9 |

Hi, <%= current_user.real_name %>

10 |

Sign out

11 | <% else %> 12 |
13 | 14 | 15 | 16 | 17 |
18 | <% end %> 19 | 20 | 21 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/server.js: -------------------------------------------------------------------------------- 1 | const marked = require('marked'); 2 | const http = require('http'); 3 | 4 | const hostname = '0.0.0.0'; 5 | const port = 3000; 6 | 7 | http.createServer((req, res) => { 8 | var body = ""; 9 | req.on('data', function (chunk) { 10 | body += chunk; 11 | }); 12 | req.on('end', function () { 13 | body = marked(body.substr(3)); 14 | res.writeHead(200, {'Content-Type': 'text/html'}); 15 | res.end(body + '

Send some content to see it parsed

'); 16 | }); 17 | }).listen(port, hostname, () => { 18 | console.log(`Server running at http://${hostname}:${port}/`); 19 | }); 20 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A06 - Sensitive Data Exposure 5 | 6 | 7 |

A06 - Sensitive Data Exposure

8 |

Users

9 |
Loading...
10 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A07 - Missing Function Level Access Control 5 | 6 | 7 |

A07 - Missing Function Level Access Control

8 | <% if current_user %> 9 |

Hi, <%= current_user.real_name %>

10 | <% if current_user.admin? %> 11 |

For admins only

12 | <% end %> 13 |

Sign out

14 | <% else %> 15 |
16 | 17 | 18 | 19 |
20 | <% end %> 21 | 22 | 23 | -------------------------------------------------------------------------------- /A01 - Injection/README.md: -------------------------------------------------------------------------------- 1 | # A01 - Injection 2 | 3 | This is a simple example of SQL injection. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/` 7 | - sign in as the admin user with the username `admin` and password `admin` 8 | - sign out from the admin account with the "Sign out" link 9 | - try signing in without a password by just entering the username `admin` but no password 10 | 11 | So, the session code seems to be working correctly. You can sign in with the right password and you 12 | can't sign in with the wrong password. Next try: 13 | 14 | - enter the string `admin' OR 1); --` in the username field and leave the password field blank 15 | 16 | Did you just sign in as a user without knowing their password? How did that happen?! 17 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/app/actions.rb: -------------------------------------------------------------------------------- 1 | helpers do 2 | def current_user 3 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 4 | end 5 | end 6 | 7 | get '/' do 8 | erb :index 9 | end 10 | 11 | post '/login' do 12 | user = User.find_by(username: params[:username], password: params[:password]) 13 | session[:user_id] = user.id if user 14 | redirect '/' 15 | end 16 | 17 | get '/logout' do 18 | session.clear 19 | redirect '/' 20 | end 21 | 22 | get '/protected_route' do 23 | if current_user 24 | puts "Successfully performed a protected action as #{current_user.real_name}" 25 | halt 204 26 | else 27 | puts 'Prevented unauthenticated user from performing protected action' 28 | halt 401 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/README.md: -------------------------------------------------------------------------------- 1 | # A04 - Insecure Direct Object References 2 | 3 | This is a simple example to show insecure direct object references. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/` 7 | - sign in as the user with the username `user` and password `user` 8 | 9 | There is a list of links to the notes that the current user is allowed to view. Users may only view 10 | their own notes. Try it out. 11 | 12 | - click on the link to see the note details 13 | - now you're at the URL `http://localhost:3000/notes/2` 14 | - change the number at the end of the URL to `1` and press enter 15 | 16 | Uh oh. You're not supposed to be able to see this note. The link to this note didn't appear on the 17 | home page; why are you able to see it? 18 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/app/views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A04 - Insecure Direct Object References 5 | 6 | 7 |

A04 - Insecure Direct Object References

8 | <% if current_user %> 9 |

Hi, <%= current_user.real_name %>

10 |

Your notes

11 | 16 |

Sign out

17 | <% else %> 18 |
19 | 20 | 21 | 22 |
23 | <% end %> 24 | 25 | 26 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/README.md: -------------------------------------------------------------------------------- 1 | # A02 - Broken Authentication and Session Management 2 | 3 | This is a simple example to explain broken session management. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/` 7 | - sign in as the admin user with the username `admin` and password `admin` 8 | 9 | So, the session code seems to be working correctly. Next try: 10 | 11 | - close the browser and imagine you are on a public computer 12 | - now imagine you are the next person to use the computer (perhaps an hour later) and open up the browser and navigate to the same site, `http://localhost:3000/` 13 | 14 | Oops! Looks like session timeouts weren't configured to drop the session after a period of inactivity and now the new user can act as you on the website. 15 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/README.md: -------------------------------------------------------------------------------- 1 | # A02 - Broken Authentication and Session Management 2 | 3 | This is a simple example to understand broken session management. To see it in action: 4 | 5 | - run `shotgun -p 3000` 6 | - load `http://localhost:3000/` 7 | - sign in as the admin user with the username `admin` and password `admin` 8 | 9 | So, the session code seems to be working correctly. Next try: 10 | 11 | - close the browser and imagine you are on a public computer 12 | - now imagine you are the next person to use the computer (perhaps an hour later) and open up the browser and navigate to the same site, `http://localhost:3000/` 13 | 14 | Oops! Looks like session timeouts weren't configured to drop the session after a period of inactivity and now the new user can act as you on the website. 15 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/README.md: -------------------------------------------------------------------------------- 1 | # A08 - Cross-Site Request Forgery (CSRF) 2 | 3 | This is a simple example of a cross-site request forgery. To see it in action: 4 | 5 | - cd into `vulnerable_app` 6 | - run `shotgun -p 3000` 7 | - load `http://localhost:3000/` 8 | - sign in as the admin user with the username `admin` and password `admin` 9 | 10 | Ok, you now have an active session with the website at `http://localhost:3000/`. Next: 11 | 12 | - open your dev tools in your browser and go to the network tab 13 | - load the file `attacker_site.html` into the browser 14 | 15 | Notice anything in the network tab? It did a request to `http://localhost:3000/protected_route`. 16 | What was the result of the request? Take a look at the console running the vulnerable app. Looks 17 | like the protected action got performed by the administrator. 18 | -------------------------------------------------------------------------------- /A01 - Injection/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 1) do 15 | 16 | create_table "users", force: :cascade do |t| 17 | t.string "real_name" 18 | t.string "email" 19 | t.string "username" 20 | t.string "password" 21 | t.boolean "admin" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 2) do 15 | 16 | create_table "notes", force: :cascade do |t| 17 | t.string "title" 18 | t.string "content" 19 | t.integer "user_id" 20 | t.datetime "created_at", null: false 21 | t.datetime "updated_at", null: false 22 | end 23 | 24 | create_table "users", force: :cascade do |t| 25 | t.string "real_name" 26 | t.string "email" 27 | t.string "username" 28 | t.string "password" 29 | t.boolean "admin" 30 | t.datetime "created_at", null: false 31 | t.datetime "updated_at", null: false 32 | end 33 | 34 | end 35 | -------------------------------------------------------------------------------- /A01 - Injection/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A05 - Security Misconfiguration/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A06 - Sensitive Data Exposure/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A03 - Cross-Site Scripting (XSS)/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A04 - Insecure Direct Object References/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A10 - Unvalidated Redirects and Forwards/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A07 - Missing Function Level Access Control/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A02 - Broken Authentication and Session Management/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A08 - Cross-Site Request Forgery (CSRF)/vulnerable_app/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | activemodel (4.2.5) 4 | activesupport (= 4.2.5) 5 | builder (~> 3.1) 6 | activerecord (4.2.5) 7 | activemodel (= 4.2.5) 8 | activesupport (= 4.2.5) 9 | arel (~> 6.0) 10 | activesupport (4.2.5) 11 | i18n (~> 0.7) 12 | json (~> 1.7, >= 1.7.7) 13 | minitest (~> 5.1) 14 | thread_safe (~> 0.3, >= 0.3.4) 15 | tzinfo (~> 1.1) 16 | arel (6.0.3) 17 | backports (3.6.7) 18 | builder (3.2.2) 19 | i18n (0.7.0) 20 | json (1.8.3) 21 | minitest (5.8.3) 22 | multi_json (1.11.2) 23 | puma (2.15.3) 24 | rack (1.6.4) 25 | rack-protection (1.5.3) 26 | rack 27 | rack-test (0.6.3) 28 | rack (>= 1.0) 29 | rake (10.4.2) 30 | shotgun (0.9.1) 31 | rack (>= 1.0) 32 | sinatra (1.4.6) 33 | rack (~> 1.4) 34 | rack-protection (~> 1.4) 35 | tilt (>= 1.3, < 3) 36 | sinatra-activerecord (2.0.5) 37 | activerecord (>= 3.2) 38 | sinatra (~> 1.0) 39 | sinatra-contrib (1.4.6) 40 | backports (>= 2.0) 41 | multi_json 42 | rack-protection 43 | rack-test 44 | sinatra (~> 1.4.0) 45 | tilt (>= 1.3, < 3) 46 | sqlite3 (1.3.11) 47 | thread_safe (0.3.5) 48 | tilt (2.0.1) 49 | tzinfo (1.2.2) 50 | thread_safe (~> 0.1) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | activesupport 57 | puma 58 | rake 59 | shotgun 60 | sinatra 61 | sinatra-activerecord 62 | sinatra-contrib 63 | sqlite3 64 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | "marked@v0.3.2", 5 | "/Users/david/curriculum/webseclec/A09---Using-Known-Vulnerable–Components" 6 | ] 7 | ], 8 | "_from": "marked@0.3.2", 9 | "_id": "marked@0.3.2", 10 | "_inCache": true, 11 | "_installable": true, 12 | "_location": "/marked", 13 | "_npmUser": { 14 | "email": "chjjeffrey@gmail.com", 15 | "name": "chjj" 16 | }, 17 | "_npmVersion": "1.4.3", 18 | "_phantomChildren": {}, 19 | "_requested": { 20 | "name": "marked", 21 | "raw": "marked@v0.3.2", 22 | "rawSpec": "v0.3.2", 23 | "scope": null, 24 | "spec": "0.3.2", 25 | "type": "version" 26 | }, 27 | "_requiredBy": [ 28 | "/" 29 | ], 30 | "_resolved": "https://registry.npmjs.org/marked/-/marked-0.3.2.tgz", 31 | "_shasum": "015db158864438f24a64bdd61a0428b418706d09", 32 | "_shrinkwrap": null, 33 | "_spec": "marked@v0.3.2", 34 | "_where": "/Users/david/curriculum/webseclec/A09---Using-Known-Vulnerable–Components", 35 | "author": { 36 | "name": "Christopher Jeffrey" 37 | }, 38 | "bin": { 39 | "marked": "./bin/marked" 40 | }, 41 | "bugs": { 42 | "url": "http://github.com/chjj/marked/issues" 43 | }, 44 | "dependencies": {}, 45 | "description": "A markdown parser built for speed", 46 | "devDependencies": { 47 | "markdown": "*", 48 | "robotskirt": "*", 49 | "showdown": "*" 50 | }, 51 | "directories": {}, 52 | "dist": { 53 | "shasum": "015db158864438f24a64bdd61a0428b418706d09", 54 | "tarball": "http://registry.npmjs.org/marked/-/marked-0.3.2.tgz" 55 | }, 56 | "homepage": "https://github.com/chjj/marked", 57 | "keywords": [ 58 | "html", 59 | "markdown", 60 | "markup" 61 | ], 62 | "license": "MIT", 63 | "main": "./lib/marked.js", 64 | "maintainers": [ 65 | { 66 | "name": "chjj", 67 | "email": "chjjeffrey@gmail.com" 68 | } 69 | ], 70 | "man": [ 71 | "./man/marked.1" 72 | ], 73 | "name": "marked", 74 | "optionalDependencies": {}, 75 | "preferGlobal": true, 76 | "readme": "ERROR: No README data found!", 77 | "repository": { 78 | "type": "git", 79 | "url": "git://github.com/chjj/marked.git" 80 | }, 81 | "scripts": { 82 | "bench": "node test --bench", 83 | "test": "node test" 84 | }, 85 | "tags": [ 86 | "html", 87 | "markdown", 88 | "markup" 89 | ], 90 | "version": "0.3.2" 91 | } 92 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/man/marked.1: -------------------------------------------------------------------------------- 1 | .ds q \N'34' 2 | .TH marked 1 "2014-01-31" "v0.3.1" "marked.js" 3 | 4 | .SH NAME 5 | marked \- a javascript markdown parser 6 | 7 | .SH SYNOPSIS 8 | .B marked 9 | [\-o \fI\fP] [\-i \fI\fP] [\-\-help] 10 | [\-\-tokens] [\-\-pedantic] [\-\-gfm] 11 | [\-\-breaks] [\-\-tables] [\-\-sanitize] 12 | [\-\-smart\-lists] [\-\-lang\-prefix \fI\fP] 13 | [\-\-no\-etc...] [\-\-silent] [\fIfilename\fP] 14 | 15 | .SH DESCRIPTION 16 | .B marked 17 | is a full-featured javascript markdown parser, built for speed. It also includes 18 | multiple GFM features. 19 | 20 | .SH EXAMPLES 21 | .TP 22 | cat in.md | marked > out.html 23 | .TP 24 | echo "hello *world*" | marked 25 | .TP 26 | marked \-o out.html in.md \-\-gfm 27 | .TP 28 | marked \-\-output="hello world.html" \-i in.md \-\-no-breaks 29 | 30 | .SH OPTIONS 31 | .TP 32 | .BI \-o,\ \-\-output\ [\fIoutput\fP] 33 | Specify file output. If none is specified, write to stdout. 34 | .TP 35 | .BI \-i,\ \-\-input\ [\fIinput\fP] 36 | Specify file input, otherwise use last argument as input file. If no input file 37 | is specified, read from stdin. 38 | .TP 39 | .BI \-t,\ \-\-tokens 40 | Output a token stream instead of html. 41 | .TP 42 | .BI \-\-pedantic 43 | Conform to obscure parts of markdown.pl as much as possible. Don't fix original 44 | markdown bugs. 45 | .TP 46 | .BI \-\-gfm 47 | Enable github flavored markdown. 48 | .TP 49 | .BI \-\-breaks 50 | Enable GFM line breaks. Only works with the gfm option. 51 | .TP 52 | .BI \-\-tables 53 | Enable GFM tables. Only works with the gfm option. 54 | .TP 55 | .BI \-\-sanitize 56 | Sanitize output. Ignore any HTML input. 57 | .TP 58 | .BI \-\-smart\-lists 59 | Use smarter list behavior than the original markdown. 60 | .TP 61 | .BI \-\-lang\-prefix\ [\fIprefix\fP] 62 | Set the prefix for code block classes. 63 | .TP 64 | .BI \-\-no\-sanitize,\ \-no-etc... 65 | The inverse of any of the marked options above. 66 | .TP 67 | .BI \-\-silent 68 | Silence error output. 69 | .TP 70 | .BI \-h,\ \-\-help 71 | Display help information. 72 | 73 | .SH CONFIGURATION 74 | For configuring and running programmatically. 75 | 76 | .B Example 77 | 78 | require('marked')('*foo*', { gfm: true }); 79 | 80 | .SH BUGS 81 | Please report any bugs to https://github.com/chjj/marked. 82 | 83 | .SH LICENSE 84 | Copyright (c) 2011-2014, Christopher Jeffrey (MIT License). 85 | 86 | .SH "SEE ALSO" 87 | .BR markdown(1), 88 | .BR node.js(1) 89 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/README.md: -------------------------------------------------------------------------------- 1 | # A09 - Using Known Vulnerable Components 2 | 3 | This is a simple example of a ReDoS attack made possible by a broken library. To see it in action: 4 | 5 | - run `node server` 6 | - load `http://localhost:3000/` 7 | - enter some MarkDown in the textarea and click the Submit button 8 | 9 | As you can see, this app has a feature that converts MarkDown text to HTML. Next try: 10 | 11 | - enter the text `____88888888:::::8::::::::::::::::88888888888888888888
________888_8:::888888:::::::::::::::::::::::::88888888888___888 ___________88:::::88888888::::::m::::::::::::::88888888888____8 _________888888888888888888:M::::::::::::::::8888888888888 ________88888888888888888888:::::::::::::::::M88888888888888 ________8888888888888888888888:::::::::::::M8888888888888888 _________8888888888888888888888::::::::::M888888888888888888 ________8888888888888888::88888:::::::::M88888888888888888888 ______88888888888888888:::88888::::::::M888888888888888___8888 _____88888888888888888:::88888::::::M:::::;o*M*o;888888888____88 ____88888888888888888:::8888:::::::M::::::::::::::::::88888888____8 ___88888888888888888::::88:::::::::M:;:::::::::::::::::::888888888 __8888888888888888888:::8:::::::::M::::aAa::::::::::::M8888888888_______ 8 __88___8888888888::88::::8::::::::M::::::::::::::::::::888888888888888_8 888 _88__88888888888:::8::::::::::::::M:::::::::::;::::::::88:88888888888888 888 _8__8888888888888::::::::::::::::M::::@@@@::::::::8w8888888888888888 __88888888888:888:::::::::::::::M:::::::@a@:::::::M8i888888888888888 _8888888888::::88:::::::::::::::M888:::::::::::::::::M88z888888888888888 88 8888888888:::::8::::::::::::::::M88888::::::::::::MM88888888888888888888 8 888888888:::::8::::::::::::::::M8888888MAmAMVMM88*88888888___88888888 888888_M::::::::::::::::::::::M888888888:::::::::MM8888888888888___88888 88 8888___M:::::::::::::::::::::M88888888888:::::::MM88888888888888____8888 8 _888___M::::::::::::::::::::M8888888888888M:::::mM888888888888____888 __888__M:::::::::::::::::::M8888:8888888888888:::m::Mm8888_8888___888 ___88__M:::::::::::::::::::8888:8888888888888888:::::::::Mm8___8888___88 8 ___88__M::::::::::::::::8888M::88888::888888888888::::::::::Mm8888____88&#160;
___8___MM:::::::::::::8888M::::8888:::::888888888888::::::::::::Mm8_____ 4 _______8M::::::::::::8888M:::::::888::::::::88:::8888888::::::::::::::Mm_____2 ______88MM:::::::::8888M::::::::::88:::::::::8:::::888888:::::::::M::::: :M _____8888M:::::::::888MM::::::::::::8::::::::::::M::::8888:::::::::::M:: ::M ____88888M:::::::::88:M:::::::::::::::8:::::::::::::M:::8888:::::::::::: M::M ___88_888MM::::::888:M:::::::::::::::::::::::::::::::M:8888::::::::::::: :M: ___8_88888M::::::88::M:::::::::::::::::::::::::::::::::MM:88:::::::::::: :::::M _____88888M::::::88::M:::::::::::::::::*88*::::::::::::M:88::::::::::::: :::::::M ____888888M::::::88::M:::::::::::::::88@@88::::::::::M::88:::::::::::::: :::::::M ____888888MM::::88::MM:::::::::::::88@@88:::::::::::M::::8:::::::::::::: :::::::*8 ____88888__M::::::8::MM:::::::::::::::*88*:::::::::::::M:::::::::::::::: ::::::::::::88@
____8888___MM:::::::::MM::::::::::::::::::::::::::::::MM:::::::::::::::: :::::::::::88@@
_____888____M:::::::::::MM:::::::::::::::::::::::::::MM::M:::::::::::::: ::::::::::::888/ _____888____MM:::::::::::MMM:::::::::::::::::::::MM::::MM::::::::::::::: ::::::::::MM ______88_____M:::::::::::::MMMM::::::::::::MMMM::::::::MM::::::::::::::: :::::MMM _______88____MM:::::::::::::::MMMMMMMMMMM:::::::::::::MMM:::::::MMMMMM ________88____MM:::::::::::::::::::MMMMM::::::::::::::::::::MMMMMMMMMMII
_________88___8MM::::::::::::::::::::::::::::::::::::::::::::::::::MMMMM MMM __________8___88MM:::::::::::::::::::::::::::::::::M:::M:::::::::::MMM ______________888MM:::::::::::::::::::::::::::MM::::::::MM::::::MM _____________88888MM::::::::::::::::::::::MMM:::::::::mM:::::MM

` 12 | 13 | Uh...the server froze. Let's try refreshing the page. Looks like the server is not responsive. Damn. 14 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/bin/marked: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Marked CLI 5 | * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License) 6 | */ 7 | 8 | var fs = require('fs') 9 | , util = require('util') 10 | , marked = require('../'); 11 | 12 | /** 13 | * Man Page 14 | */ 15 | 16 | function help() { 17 | var spawn = require('child_process').spawn; 18 | 19 | var options = { 20 | cwd: process.cwd(), 21 | env: process.env, 22 | setsid: false, 23 | customFds: [0, 1, 2] 24 | }; 25 | 26 | spawn('man', 27 | [__dirname + '/../man/marked.1'], 28 | options); 29 | } 30 | 31 | /** 32 | * Main 33 | */ 34 | 35 | function main(argv, callback) { 36 | var files = [] 37 | , options = {} 38 | , input 39 | , output 40 | , arg 41 | , tokens 42 | , opt; 43 | 44 | function getarg() { 45 | var arg = argv.shift(); 46 | 47 | if (arg.indexOf('--') === 0) { 48 | // e.g. --opt 49 | arg = arg.split('='); 50 | if (arg.length > 1) { 51 | // e.g. --opt=val 52 | argv.unshift(arg.slice(1).join('=')); 53 | } 54 | arg = arg[0]; 55 | } else if (arg[0] === '-') { 56 | if (arg.length > 2) { 57 | // e.g. -abc 58 | argv = arg.substring(1).split('').map(function(ch) { 59 | return '-' + ch; 60 | }).concat(argv); 61 | arg = argv.shift(); 62 | } else { 63 | // e.g. -a 64 | } 65 | } else { 66 | // e.g. foo 67 | } 68 | 69 | return arg; 70 | } 71 | 72 | while (argv.length) { 73 | arg = getarg(); 74 | switch (arg) { 75 | case '--test': 76 | return require('../test').main(process.argv.slice()); 77 | case '-o': 78 | case '--output': 79 | output = argv.shift(); 80 | break; 81 | case '-i': 82 | case '--input': 83 | input = argv.shift(); 84 | break; 85 | case '-t': 86 | case '--tokens': 87 | tokens = true; 88 | break; 89 | case '-h': 90 | case '--help': 91 | return help(); 92 | default: 93 | if (arg.indexOf('--') === 0) { 94 | opt = camelize(arg.replace(/^--(no-)?/, '')); 95 | if (!marked.defaults.hasOwnProperty(opt)) { 96 | continue; 97 | } 98 | if (arg.indexOf('--no-') === 0) { 99 | options[opt] = typeof marked.defaults[opt] !== 'boolean' 100 | ? null 101 | : false; 102 | } else { 103 | options[opt] = typeof marked.defaults[opt] !== 'boolean' 104 | ? argv.shift() 105 | : true; 106 | } 107 | } else { 108 | files.push(arg); 109 | } 110 | break; 111 | } 112 | } 113 | 114 | function getData(callback) { 115 | if (!input) { 116 | if (files.length <= 2) { 117 | return getStdin(callback); 118 | } 119 | input = files.pop(); 120 | } 121 | return fs.readFile(input, 'utf8', callback); 122 | } 123 | 124 | return getData(function(err, data) { 125 | if (err) return callback(err); 126 | 127 | data = tokens 128 | ? JSON.stringify(marked.lexer(data, options), null, 2) 129 | : marked(data, options); 130 | 131 | if (!output) { 132 | process.stdout.write(data + '\n'); 133 | return callback(); 134 | } 135 | 136 | return fs.writeFile(output, data, callback); 137 | }); 138 | } 139 | 140 | /** 141 | * Helpers 142 | */ 143 | 144 | function getStdin(callback) { 145 | var stdin = process.stdin 146 | , buff = ''; 147 | 148 | stdin.setEncoding('utf8'); 149 | 150 | stdin.on('data', function(data) { 151 | buff += data; 152 | }); 153 | 154 | stdin.on('error', function(err) { 155 | return callback(err); 156 | }); 157 | 158 | stdin.on('end', function() { 159 | return callback(null, buff); 160 | }); 161 | 162 | try { 163 | stdin.resume(); 164 | } catch (e) { 165 | callback(e); 166 | } 167 | } 168 | 169 | function camelize(text) { 170 | return text.replace(/(\w)-(\w)/g, function(_, a, b) { 171 | return a + b.toUpperCase(); 172 | }); 173 | } 174 | 175 | /** 176 | * Expose / Entry Point 177 | */ 178 | 179 | if (!module.parent) { 180 | process.title = 'marked'; 181 | main(process.argv.slice(), function(err, code) { 182 | if (err) throw err; 183 | return process.exit(code || 0); 184 | }); 185 | } else { 186 | module.exports = main; 187 | } 188 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/doc/broken.md: -------------------------------------------------------------------------------- 1 | # Markdown is broken 2 | 3 | I have a lot of scraps of markdown engine oddities that I've collected over the 4 | years. What you see below is slightly messy, but it's what I've managed to 5 | cobble together to illustrate the differences between markdown engines, and 6 | why, if there ever is a markdown specification, it has to be absolutely 7 | thorough. There are a lot more of these little differences I have documented 8 | elsewhere. I know I will find them lingering on my disk one day, but until 9 | then, I'll continue to add whatever strange nonsensical things I find. 10 | 11 | Some of these examples may only mention a particular engine compared to marked. 12 | However, the examples with markdown.pl could easily be swapped out for 13 | discount, upskirt, or markdown.js, and you would very easily see even more 14 | inconsistencies. 15 | 16 | A lot of this was written when I was very unsatisfied with the inconsistencies 17 | between markdown engines. Please excuse the frustration noticeable in my 18 | writing. 19 | 20 | ## Examples of markdown's "stupid" list parsing 21 | 22 | ``` 23 | $ markdown.pl 24 | 25 | * item1 26 | 27 | * item2 28 | 29 | text 30 | ^D 31 |

40 | ``` 41 | 42 | 43 | ``` 44 | $ marked 45 | * item1 46 | 47 | * item2 48 | 49 | text 50 | ^D 51 | 59 | ``` 60 | 61 | Which looks correct to you? 62 | 63 | - - - 64 | 65 | ``` 66 | $ markdown.pl 67 | * hello 68 | > world 69 | ^D 70 |

76 | 77 | ``` 78 | 79 | ``` 80 | $ marked 81 | * hello 82 | > world 83 | ^D 84 | 90 | ``` 91 | 92 | Again, which looks correct to you? 93 | 94 | - - - 95 | 96 | EXAMPLE: 97 | 98 | ``` 99 | $ markdown.pl 100 | * hello 101 | * world 102 | * hi 103 | code 104 | ^D 105 | 113 | ``` 114 | 115 | The code isn't a code block even though it's after the bullet margin. I know, 116 | lets give it two more spaces, effectively making it 8 spaces past the bullet. 117 | 118 | ``` 119 | $ markdown.pl 120 | * hello 121 | * world 122 | * hi 123 | code 124 | ^D 125 | 133 | ``` 134 | 135 | And, it's still not a code block. Did you also notice that the 3rd item isn't 136 | even its own list? Markdown screws that up too because of its indentation 137 | unaware parsing. 138 | 139 | - - - 140 | 141 | Let's look at some more examples of markdown's list parsing: 142 | 143 | ``` 144 | $ markdown.pl 145 | 146 | * item1 147 | 148 | * item2 149 | 150 | text 151 | ^D 152 |

161 | ``` 162 | 163 | Misnested tags. 164 | 165 | 166 | ``` 167 | $ marked 168 | * item1 169 | 170 | * item2 171 | 172 | text 173 | ^D 174 | 182 | ``` 183 | 184 | Which looks correct to you? 185 | 186 | - - - 187 | 188 | ``` 189 | $ markdown.pl 190 | * hello 191 | > world 192 | ^D 193 |

199 | 200 | ``` 201 | 202 | More misnested tags. 203 | 204 | 205 | ``` 206 | $ marked 207 | * hello 208 | > world 209 | ^D 210 | 216 | ``` 217 | 218 | Again, which looks correct to you? 219 | 220 | - - - 221 | 222 | # Why quality matters - Part 2 223 | 224 | ``` bash 225 | $ markdown.pl 226 | * hello 227 | > world 228 | ^D 229 |

235 | 236 | ``` 237 | 238 | ``` bash 239 | $ sundown # upskirt 240 | * hello 241 | > world 242 | ^D 243 | 247 | ``` 248 | 249 | ``` bash 250 | $ marked 251 | * hello 252 | > world 253 | ^D 254 | 255 | ``` 256 | 257 | Which looks correct to you? 258 | 259 | - - - 260 | 261 | See: https://github.com/evilstreak/markdown-js/issues/23 262 | 263 | ``` bash 264 | $ markdown.pl # upskirt/markdown.js/discount 265 | * hello 266 | var a = 1; 267 | * world 268 | ^D 269 | 274 | ``` 275 | 276 | ``` bash 277 | $ marked 278 | * hello 279 | var a = 1; 280 | * world 281 | ^D 282 | 285 | ``` 286 | 287 | Which looks more reasonable? Why shouldn't code blocks be able to appear in 288 | list items in a sane way? 289 | 290 | - - - 291 | 292 | ``` bash 293 | $ markdown.js 294 |
hello
295 | 296 | hello 297 | ^D 298 |

<div>hello</div>

299 | 300 |

<span>hello</span>

301 | ``` 302 | 303 | ``` bash 304 | $ marked 305 |
hello
306 | 307 | hello 308 | ^D 309 |
hello
310 | 311 | 312 |

hello 313 |

314 | ``` 315 | 316 | - - - 317 | 318 | See: https://github.com/evilstreak/markdown-js/issues/27 319 | 320 | ``` bash 321 | $ markdown.js 322 | [![an image](/image)](/link) 323 | ^D 324 |

![an image

325 | ``` 326 | 327 | ``` bash 328 | $ marked 329 | [![an image](/image)](/link) 330 | ^D 331 |

an image 332 |

333 | ``` 334 | 335 | - - - 336 | 337 | See: https://github.com/evilstreak/markdown-js/issues/24 338 | 339 | ``` bash 340 | $ markdown.js 341 | > a 342 | 343 | > b 344 | 345 | > c 346 | ^D 347 |

a

bundefined> c

348 | ``` 349 | 350 | ``` bash 351 | $ marked 352 | > a 353 | 354 | > b 355 | 356 | > c 357 | ^D 358 |

a 359 | 360 |

361 |

b 362 | 363 |

364 |

c 365 |

366 | ``` 367 | 368 | - - - 369 | 370 | ``` bash 371 | $ markdown.pl 372 | * hello 373 | * world 374 | how 375 | 376 | are 377 | you 378 | 379 | * today 380 | * hi 381 | ^D 382 | 398 | ``` 399 | 400 | ``` bash 401 | $ marked 402 | * hello 403 | * world 404 | how 405 | 406 | are 407 | you 408 | 409 | * today 410 | * hi 411 | ^D 412 | 426 | ``` 427 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/README.md: -------------------------------------------------------------------------------- 1 | # marked 2 | 3 | > A full-featured markdown parser and compiler, written in JavaScript. Built 4 | > for speed. 5 | 6 | [![NPM version](https://badge.fury.io/js/marked.png)][badge] 7 | 8 | ## Install 9 | 10 | ``` bash 11 | npm install marked --save 12 | ``` 13 | 14 | ## Usage 15 | 16 | Minimal usage: 17 | 18 | ```js 19 | var marked = require('marked'); 20 | console.log(marked('I am using __markdown__.')); 21 | // Outputs:

I am using markdown.

22 | ``` 23 | 24 | Example setting options with default values: 25 | 26 | ```js 27 | var marked = require('marked'); 28 | marked.setOptions({ 29 | renderer: new marked.Renderer(), 30 | gfm: true, 31 | tables: true, 32 | breaks: false, 33 | pedantic: false, 34 | sanitize: true, 35 | smartLists: true, 36 | smartypants: false 37 | }); 38 | 39 | console.log(marked('I am using __markdown__.')); 40 | ``` 41 | 42 | ## marked(markdownString [,options] [,callback]) 43 | 44 | ### markdownString 45 | 46 | Type: `string` 47 | 48 | String of markdown source to be compiled. 49 | 50 | ### options 51 | 52 | Type: `object` 53 | 54 | Hash of options. Can also be set using the `marked.setOptions` method as seen 55 | above. 56 | 57 | ### callback 58 | 59 | Type: `function` 60 | 61 | Function called when the `markdownString` has been fully parsed when using 62 | async highlighting. If the `options` argument is omitted, this can be used as 63 | the second argument. 64 | 65 | ## Options 66 | 67 | ### highlight 68 | 69 | Type: `function` 70 | 71 | A function to highlight code blocks. The first example below uses async highlighting with 72 | [node-pygmentize-bundled][pygmentize], and the second is a synchronous example using 73 | [highlight.js][highlight]: 74 | 75 | ```js 76 | var marked = require('marked'); 77 | 78 | var markdownString = '```js\n console.log("hello"); \n```'; 79 | 80 | // Async highlighting with pygmentize-bundled 81 | marked.setOptions({ 82 | highlight: function (code, lang, callback) { 83 | require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) { 84 | callback(err, result.toString()); 85 | }); 86 | } 87 | }); 88 | 89 | // Using async version of marked 90 | marked(markdownString, function (err, content) { 91 | if (err) throw err; 92 | console.log(content); 93 | }); 94 | 95 | // Synchronous highlighting with highlight.js 96 | marked.setOptions({ 97 | highlight: function (code) { 98 | return require('highlight.js').highlightAuto(code).value; 99 | } 100 | }); 101 | 102 | console.log(marked(markdownString)); 103 | ``` 104 | 105 | #### highlight arguments 106 | 107 | `code` 108 | 109 | Type: `string` 110 | 111 | The section of code to pass to the highlighter. 112 | 113 | `lang` 114 | 115 | Type: `string` 116 | 117 | The programming language specified in the code block. 118 | 119 | `callback` 120 | 121 | Type: `function` 122 | 123 | The callback function to call when using an async highlighter. 124 | 125 | ### renderer 126 | 127 | Type: `object` 128 | Default: `new Renderer()` 129 | 130 | An object containing functions to render tokens to HTML. 131 | 132 | #### Overriding renderer methods 133 | 134 | The renderer option allows you to render tokens in a custom manor. Here is an 135 | example of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub: 136 | 137 | ```javascript 138 | var marked = require('marked'); 139 | var renderer = new marked.Renderer(); 140 | 141 | renderer.heading = function (text, level) { 142 | var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-'); 143 | 144 | return '' + 149 | text + ''; 150 | }, 151 | 152 | console.log(marked('# heading+', { renderer: renderer })); 153 | ``` 154 | This code will output the following HTML: 155 | ```html 156 |

157 | 158 | 159 | 160 | heading+ 161 |

162 | ``` 163 | 164 | #### Block level renderer methods 165 | 166 | - code(*string* code, *string* language) 167 | - blockquote(*string* quote) 168 | - html(*string* html) 169 | - heading(*string* text, *number* level) 170 | - hr() 171 | - list(*string* body, *boolean* ordered) 172 | - listitem(*string* text) 173 | - paragraph(*string* text) 174 | - table(*string* header, *string* body) 175 | - tablerow(*string* content) 176 | - tablecell(*string* content, *object* flags) 177 | 178 | `flags` has the following properties: 179 | 180 | ```js 181 | { 182 | header: true || false, 183 | align: 'center' || 'left' || 'right' 184 | } 185 | ``` 186 | 187 | #### Inline level renderer methods 188 | 189 | - strong(*string* text) 190 | - em(*string* text) 191 | - codespan(*string* code) 192 | - br() 193 | - del(*string* text) 194 | - link(*string* href, *string* title, *string* text) 195 | - image(*string* href, *string* title, *string* text) 196 | 197 | ### gfm 198 | 199 | Type: `boolean` 200 | Default: `true` 201 | 202 | Enable [GitHub flavored markdown][gfm]. 203 | 204 | ### tables 205 | 206 | Type: `boolean` 207 | Default: `true` 208 | 209 | Enable GFM [tables][tables]. 210 | This option requires the `gfm` option to be true. 211 | 212 | ### breaks 213 | 214 | Type: `boolean` 215 | Default: `false` 216 | 217 | Enable GFM [line breaks][breaks]. 218 | This option requires the `gfm` option to be true. 219 | 220 | ### pedantic 221 | 222 | Type: `boolean` 223 | Default: `false` 224 | 225 | Conform to obscure parts of `markdown.pl` as much as possible. Don't fix any of 226 | the original markdown bugs or poor behavior. 227 | 228 | ### sanitize 229 | 230 | Type: `boolean` 231 | Default: `false` 232 | 233 | Sanitize the output. Ignore any HTML that has been input. 234 | 235 | ### smartLists 236 | 237 | Type: `boolean` 238 | Default: `true` 239 | 240 | Use smarter list behavior than the original markdown. May eventually be 241 | default with the old behavior moved into `pedantic`. 242 | 243 | ### smartypants 244 | 245 | Type: `boolean` 246 | Default: `false` 247 | 248 | Use "smart" typograhic punctuation for things like quotes and dashes. 249 | 250 | ## Access to lexer and parser 251 | 252 | You also have direct access to the lexer and parser if you so desire. 253 | 254 | ``` js 255 | var tokens = marked.lexer(text, options); 256 | console.log(marked.parser(tokens)); 257 | ``` 258 | 259 | ``` js 260 | var lexer = new marked.Lexer(options); 261 | var tokens = lexer.lex(text); 262 | console.log(tokens); 263 | console.log(lexer.rules); 264 | ``` 265 | 266 | ## CLI 267 | 268 | ``` bash 269 | $ marked -o hello.html 270 | hello world 271 | ^D 272 | $ cat hello.html 273 |

hello world

274 | ``` 275 | 276 | ## Philosophy behind marked 277 | 278 | The point of marked was to create a markdown compiler where it was possible to 279 | frequently parse huge chunks of markdown without having to worry about 280 | caching the compiled output somehow...or blocking for an unnecesarily long time. 281 | 282 | marked is very concise and still implements all markdown features. It is also 283 | now fully compatible with the client-side. 284 | 285 | marked more or less passes the official markdown test suite in its 286 | entirety. This is important because a surprising number of markdown compilers 287 | cannot pass more than a few tests. It was very difficult to get marked as 288 | compliant as it is. It could have cut corners in several areas for the sake 289 | of performance, but did not in order to be exactly what you expect in terms 290 | of a markdown rendering. In fact, this is why marked could be considered at a 291 | disadvantage in the benchmarks above. 292 | 293 | Along with implementing every markdown feature, marked also implements [GFM 294 | features][gfmf]. 295 | 296 | ## Benchmarks 297 | 298 | node v0.8.x 299 | 300 | ``` bash 301 | $ node test --bench 302 | marked completed in 3411ms. 303 | marked (gfm) completed in 3727ms. 304 | marked (pedantic) completed in 3201ms. 305 | robotskirt completed in 808ms. 306 | showdown (reuse converter) completed in 11954ms. 307 | showdown (new converter) completed in 17774ms. 308 | markdown-js completed in 17191ms. 309 | ``` 310 | 311 | __Marked is now faster than Discount, which is written in C.__ 312 | 313 | For those feeling skeptical: These benchmarks run the entire markdown test suite 1000 times. The test suite tests every feature. It doesn't cater to specific aspects. 314 | 315 | ### Pro level 316 | 317 | You also have direct access to the lexer and parser if you so desire. 318 | 319 | ``` js 320 | var tokens = marked.lexer(text, options); 321 | console.log(marked.parser(tokens)); 322 | ``` 323 | 324 | ``` js 325 | var lexer = new marked.Lexer(options); 326 | var tokens = lexer.lex(text); 327 | console.log(tokens); 328 | console.log(lexer.rules); 329 | ``` 330 | 331 | ``` bash 332 | $ node 333 | > require('marked').lexer('> i am using marked.') 334 | [ { type: 'blockquote_start' }, 335 | { type: 'paragraph', 336 | text: 'i am using marked.' }, 337 | { type: 'blockquote_end' }, 338 | links: {} ] 339 | ``` 340 | 341 | ## Running Tests & Contributing 342 | 343 | If you want to submit a pull request, make sure your changes pass the test 344 | suite. If you're adding a new feature, be sure to add your own test. 345 | 346 | The marked test suite is set up slightly strangely: `test/new` is for all tests 347 | that are not part of the original markdown.pl test suite (this is where your 348 | test should go if you make one). `test/original` is only for the original 349 | markdown.pl tests. `test/tests` houses both types of tests after they have been 350 | combined and moved/generated by running `node test --fix` or `marked --test 351 | --fix`. 352 | 353 | In other words, if you have a test to add, add it to `test/new/` and then 354 | regenerate the tests with `node test --fix`. Commit the result. If your test 355 | uses a certain feature, for example, maybe it assumes GFM is *not* enabled, you 356 | can add `.nogfm` to the filename. So, `my-test.text` becomes 357 | `my-test.nogfm.text`. You can do this with any marked option. Say you want 358 | line breaks and smartypants enabled, your filename should be: 359 | `my-test.breaks.smartypants.text`. 360 | 361 | To run the tests: 362 | 363 | ``` bash 364 | cd marked/ 365 | node test 366 | ``` 367 | 368 | ### Contribution and License Agreement 369 | 370 | If you contribute code to this project, you are implicitly allowing your code 371 | to be distributed under the MIT license. You are also implicitly verifying that 372 | all code is your original work. `` 373 | 374 | ## License 375 | 376 | Copyright (c) 2011-2014, Christopher Jeffrey. (MIT License) 377 | 378 | See LICENSE for more info. 379 | 380 | [gfm]: https://help.github.com/articles/github-flavored-markdown 381 | [gfmf]: http://github.github.com/github-flavored-markdown/ 382 | [pygmentize]: https://github.com/rvagg/node-pygmentize-bundled 383 | [highlight]: https://github.com/isagalaev/highlight.js 384 | [badge]: http://badge.fury.io/js/marked 385 | [tables]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables 386 | [breaks]: https://help.github.com/articles/github-flavored-markdown#newlines 387 | -------------------------------------------------------------------------------- /A09 - Using Known Vulnerable Components/node_modules/marked/lib/marked.js: -------------------------------------------------------------------------------- 1 | /** 2 | * marked - a markdown parser 3 | * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed) 4 | * https://github.com/chjj/marked 5 | */ 6 | 7 | ;(function() { 8 | 9 | /** 10 | * Block-Level Grammar 11 | */ 12 | 13 | var block = { 14 | newline: /^\n+/, 15 | code: /^( {4}[^\n]+\n*)+/, 16 | fences: noop, 17 | hr: /^( *[-*_]){3,} *(?:\n+|$)/, 18 | heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, 19 | nptable: noop, 20 | lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/, 21 | blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/, 22 | list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, 23 | html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, 24 | def: /^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, 25 | table: noop, 26 | paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, 27 | text: /^[^\n]+/ 28 | }; 29 | 30 | block.bullet = /(?:[*+-]|\d+\.)/; 31 | block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; 32 | block.item = replace(block.item, 'gm') 33 | (/bull/g, block.bullet) 34 | (); 35 | 36 | block.list = replace(block.list) 37 | (/bull/g, block.bullet) 38 | ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))') 39 | ('def', '\\n+(?=' + block.def.source + ')') 40 | (); 41 | 42 | block.blockquote = replace(block.blockquote) 43 | ('def', block.def) 44 | (); 45 | 46 | block._tag = '(?!(?:' 47 | + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' 48 | + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' 49 | + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b'; 50 | 51 | block.html = replace(block.html) 52 | ('comment', //) 53 | ('closed', /<(tag)[\s\S]+?<\/\1>/) 54 | ('closing', /])*?>/) 55 | (/tag/g, block._tag) 56 | (); 57 | 58 | block.paragraph = replace(block.paragraph) 59 | ('hr', block.hr) 60 | ('heading', block.heading) 61 | ('lheading', block.lheading) 62 | ('blockquote', block.blockquote) 63 | ('tag', '<' + block._tag) 64 | ('def', block.def) 65 | (); 66 | 67 | /** 68 | * Normal Block Grammar 69 | */ 70 | 71 | block.normal = merge({}, block); 72 | 73 | /** 74 | * GFM Block Grammar 75 | */ 76 | 77 | block.gfm = merge({}, block.normal, { 78 | fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, 79 | paragraph: /^/ 80 | }); 81 | 82 | block.gfm.paragraph = replace(block.paragraph) 83 | ('(?!', '(?!' 84 | + block.gfm.fences.source.replace('\\1', '\\2') + '|' 85 | + block.list.source.replace('\\1', '\\3') + '|') 86 | (); 87 | 88 | /** 89 | * GFM + Tables Block Grammar 90 | */ 91 | 92 | block.tables = merge({}, block.gfm, { 93 | nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, 94 | table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ 95 | }); 96 | 97 | /** 98 | * Block Lexer 99 | */ 100 | 101 | function Lexer(options) { 102 | this.tokens = []; 103 | this.tokens.links = {}; 104 | this.options = options || marked.defaults; 105 | this.rules = block.normal; 106 | 107 | if (this.options.gfm) { 108 | if (this.options.tables) { 109 | this.rules = block.tables; 110 | } else { 111 | this.rules = block.gfm; 112 | } 113 | } 114 | } 115 | 116 | /** 117 | * Expose Block Rules 118 | */ 119 | 120 | Lexer.rules = block; 121 | 122 | /** 123 | * Static Lex Method 124 | */ 125 | 126 | Lexer.lex = function(src, options) { 127 | var lexer = new Lexer(options); 128 | return lexer.lex(src); 129 | }; 130 | 131 | /** 132 | * Preprocessing 133 | */ 134 | 135 | Lexer.prototype.lex = function(src) { 136 | src = src 137 | .replace(/\r\n|\r/g, '\n') 138 | .replace(/\t/g, ' ') 139 | .replace(/\u00a0/g, ' ') 140 | .replace(/\u2424/g, '\n'); 141 | 142 | return this.token(src, true); 143 | }; 144 | 145 | /** 146 | * Lexing 147 | */ 148 | 149 | Lexer.prototype.token = function(src, top, bq) { 150 | var src = src.replace(/^ +$/gm, '') 151 | , next 152 | , loose 153 | , cap 154 | , bull 155 | , b 156 | , item 157 | , space 158 | , i 159 | , l; 160 | 161 | while (src) { 162 | // newline 163 | if (cap = this.rules.newline.exec(src)) { 164 | src = src.substring(cap[0].length); 165 | if (cap[0].length > 1) { 166 | this.tokens.push({ 167 | type: 'space' 168 | }); 169 | } 170 | } 171 | 172 | // code 173 | if (cap = this.rules.code.exec(src)) { 174 | src = src.substring(cap[0].length); 175 | cap = cap[0].replace(/^ {4}/gm, ''); 176 | this.tokens.push({ 177 | type: 'code', 178 | text: !this.options.pedantic 179 | ? cap.replace(/\n+$/, '') 180 | : cap 181 | }); 182 | continue; 183 | } 184 | 185 | // fences (gfm) 186 | if (cap = this.rules.fences.exec(src)) { 187 | src = src.substring(cap[0].length); 188 | this.tokens.push({ 189 | type: 'code', 190 | lang: cap[2], 191 | text: cap[3] 192 | }); 193 | continue; 194 | } 195 | 196 | // heading 197 | if (cap = this.rules.heading.exec(src)) { 198 | src = src.substring(cap[0].length); 199 | this.tokens.push({ 200 | type: 'heading', 201 | depth: cap[1].length, 202 | text: cap[2] 203 | }); 204 | continue; 205 | } 206 | 207 | // table no leading pipe (gfm) 208 | if (top && (cap = this.rules.nptable.exec(src))) { 209 | src = src.substring(cap[0].length); 210 | 211 | item = { 212 | type: 'table', 213 | header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), 214 | align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), 215 | cells: cap[3].replace(/\n$/, '').split('\n') 216 | }; 217 | 218 | for (i = 0; i < item.align.length; i++) { 219 | if (/^ *-+: *$/.test(item.align[i])) { 220 | item.align[i] = 'right'; 221 | } else if (/^ *:-+: *$/.test(item.align[i])) { 222 | item.align[i] = 'center'; 223 | } else if (/^ *:-+ *$/.test(item.align[i])) { 224 | item.align[i] = 'left'; 225 | } else { 226 | item.align[i] = null; 227 | } 228 | } 229 | 230 | for (i = 0; i < item.cells.length; i++) { 231 | item.cells[i] = item.cells[i].split(/ *\| */); 232 | } 233 | 234 | this.tokens.push(item); 235 | 236 | continue; 237 | } 238 | 239 | // lheading 240 | if (cap = this.rules.lheading.exec(src)) { 241 | src = src.substring(cap[0].length); 242 | this.tokens.push({ 243 | type: 'heading', 244 | depth: cap[2] === '=' ? 1 : 2, 245 | text: cap[1] 246 | }); 247 | continue; 248 | } 249 | 250 | // hr 251 | if (cap = this.rules.hr.exec(src)) { 252 | src = src.substring(cap[0].length); 253 | this.tokens.push({ 254 | type: 'hr' 255 | }); 256 | continue; 257 | } 258 | 259 | // blockquote 260 | if (cap = this.rules.blockquote.exec(src)) { 261 | src = src.substring(cap[0].length); 262 | 263 | this.tokens.push({ 264 | type: 'blockquote_start' 265 | }); 266 | 267 | cap = cap[0].replace(/^ *> ?/gm, ''); 268 | 269 | // Pass `top` to keep the current 270 | // "toplevel" state. This is exactly 271 | // how markdown.pl works. 272 | this.token(cap, top, true); 273 | 274 | this.tokens.push({ 275 | type: 'blockquote_end' 276 | }); 277 | 278 | continue; 279 | } 280 | 281 | // list 282 | if (cap = this.rules.list.exec(src)) { 283 | src = src.substring(cap[0].length); 284 | bull = cap[2]; 285 | 286 | this.tokens.push({ 287 | type: 'list_start', 288 | ordered: bull.length > 1 289 | }); 290 | 291 | // Get each top-level item. 292 | cap = cap[0].match(this.rules.item); 293 | 294 | next = false; 295 | l = cap.length; 296 | i = 0; 297 | 298 | for (; i < l; i++) { 299 | item = cap[i]; 300 | 301 | // Remove the list item's bullet 302 | // so it is seen as the next token. 303 | space = item.length; 304 | item = item.replace(/^ *([*+-]|\d+\.) +/, ''); 305 | 306 | // Outdent whatever the 307 | // list item contains. Hacky. 308 | if (~item.indexOf('\n ')) { 309 | space -= item.length; 310 | item = !this.options.pedantic 311 | ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') 312 | : item.replace(/^ {1,4}/gm, ''); 313 | } 314 | 315 | // Determine whether the next list item belongs here. 316 | // Backpedal if it does not belong in this list. 317 | if (this.options.smartLists && i !== l - 1) { 318 | b = block.bullet.exec(cap[i + 1])[0]; 319 | if (bull !== b && !(bull.length > 1 && b.length > 1)) { 320 | src = cap.slice(i + 1).join('\n') + src; 321 | i = l - 1; 322 | } 323 | } 324 | 325 | // Determine whether item is loose or not. 326 | // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ 327 | // for discount behavior. 328 | loose = next || /\n\n(?!\s*$)/.test(item); 329 | if (i !== l - 1) { 330 | next = item.charAt(item.length - 1) === '\n'; 331 | if (!loose) loose = next; 332 | } 333 | 334 | this.tokens.push({ 335 | type: loose 336 | ? 'loose_item_start' 337 | : 'list_item_start' 338 | }); 339 | 340 | // Recurse. 341 | this.token(item, false, bq); 342 | 343 | this.tokens.push({ 344 | type: 'list_item_end' 345 | }); 346 | } 347 | 348 | this.tokens.push({ 349 | type: 'list_end' 350 | }); 351 | 352 | continue; 353 | } 354 | 355 | // html 356 | if (cap = this.rules.html.exec(src)) { 357 | src = src.substring(cap[0].length); 358 | this.tokens.push({ 359 | type: this.options.sanitize 360 | ? 'paragraph' 361 | : 'html', 362 | pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style', 363 | text: cap[0] 364 | }); 365 | continue; 366 | } 367 | 368 | // def 369 | if ((!bq && top) && (cap = this.rules.def.exec(src))) { 370 | src = src.substring(cap[0].length); 371 | this.tokens.links[cap[1].toLowerCase()] = { 372 | href: cap[2], 373 | title: cap[3] 374 | }; 375 | continue; 376 | } 377 | 378 | // table (gfm) 379 | if (top && (cap = this.rules.table.exec(src))) { 380 | src = src.substring(cap[0].length); 381 | 382 | item = { 383 | type: 'table', 384 | header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), 385 | align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), 386 | cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') 387 | }; 388 | 389 | for (i = 0; i < item.align.length; i++) { 390 | if (/^ *-+: *$/.test(item.align[i])) { 391 | item.align[i] = 'right'; 392 | } else if (/^ *:-+: *$/.test(item.align[i])) { 393 | item.align[i] = 'center'; 394 | } else if (/^ *:-+ *$/.test(item.align[i])) { 395 | item.align[i] = 'left'; 396 | } else { 397 | item.align[i] = null; 398 | } 399 | } 400 | 401 | for (i = 0; i < item.cells.length; i++) { 402 | item.cells[i] = item.cells[i] 403 | .replace(/^ *\| *| *\| *$/g, '') 404 | .split(/ *\| */); 405 | } 406 | 407 | this.tokens.push(item); 408 | 409 | continue; 410 | } 411 | 412 | // top-level paragraph 413 | if (top && (cap = this.rules.paragraph.exec(src))) { 414 | src = src.substring(cap[0].length); 415 | this.tokens.push({ 416 | type: 'paragraph', 417 | text: cap[1].charAt(cap[1].length - 1) === '\n' 418 | ? cap[1].slice(0, -1) 419 | : cap[1] 420 | }); 421 | continue; 422 | } 423 | 424 | // text 425 | if (cap = this.rules.text.exec(src)) { 426 | // Top-level should never reach here. 427 | src = src.substring(cap[0].length); 428 | this.tokens.push({ 429 | type: 'text', 430 | text: cap[0] 431 | }); 432 | continue; 433 | } 434 | 435 | if (src) { 436 | throw new 437 | Error('Infinite loop on byte: ' + src.charCodeAt(0)); 438 | } 439 | } 440 | 441 | return this.tokens; 442 | }; 443 | 444 | /** 445 | * Inline-Level Grammar 446 | */ 447 | 448 | var inline = { 449 | escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, 450 | autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, 451 | url: noop, 452 | tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, 453 | link: /^!?\[(inside)\]\(href\)/, 454 | reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, 455 | nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, 456 | strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, 457 | em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, 458 | code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, 459 | br: /^ {2,}\n(?!\s*$)/, 460 | del: noop, 461 | text: /^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/; 466 | 467 | inline.link = replace(inline.link) 468 | ('inside', inline._inside) 469 | ('href', inline._href) 470 | (); 471 | 472 | inline.reflink = replace(inline.reflink) 473 | ('inside', inline._inside) 474 | (); 475 | 476 | /** 477 | * Normal Inline Grammar 478 | */ 479 | 480 | inline.normal = merge({}, inline); 481 | 482 | /** 483 | * Pedantic Inline Grammar 484 | */ 485 | 486 | inline.pedantic = merge({}, inline.normal, { 487 | strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, 488 | em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ 489 | }); 490 | 491 | /** 492 | * GFM Inline Grammar 493 | */ 494 | 495 | inline.gfm = merge({}, inline.normal, { 496 | escape: replace(inline.escape)('])', '~|])')(), 497 | url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, 498 | del: /^~~(?=\S)([\s\S]*?\S)~~/, 499 | text: replace(inline.text) 500 | (']|', '~]|') 501 | ('|', '|https?://|') 502 | () 503 | }); 504 | 505 | /** 506 | * GFM + Line Breaks Inline Grammar 507 | */ 508 | 509 | inline.breaks = merge({}, inline.gfm, { 510 | br: replace(inline.br)('{2,}', '*')(), 511 | text: replace(inline.gfm.text)('{2,}', '*')() 512 | }); 513 | 514 | /** 515 | * Inline Lexer & Compiler 516 | */ 517 | 518 | function InlineLexer(links, options) { 519 | this.options = options || marked.defaults; 520 | this.links = links; 521 | this.rules = inline.normal; 522 | this.renderer = this.options.renderer || new Renderer; 523 | this.renderer.options = this.options; 524 | 525 | if (!this.links) { 526 | throw new 527 | Error('Tokens array requires a `links` property.'); 528 | } 529 | 530 | if (this.options.gfm) { 531 | if (this.options.breaks) { 532 | this.rules = inline.breaks; 533 | } else { 534 | this.rules = inline.gfm; 535 | } 536 | } else if (this.options.pedantic) { 537 | this.rules = inline.pedantic; 538 | } 539 | } 540 | 541 | /** 542 | * Expose Inline Rules 543 | */ 544 | 545 | InlineLexer.rules = inline; 546 | 547 | /** 548 | * Static Lexing/Compiling Method 549 | */ 550 | 551 | InlineLexer.output = function(src, links, options) { 552 | var inline = new InlineLexer(links, options); 553 | return inline.output(src); 554 | }; 555 | 556 | /** 557 | * Lexing/Compiling 558 | */ 559 | 560 | InlineLexer.prototype.output = function(src) { 561 | var out = '' 562 | , link 563 | , text 564 | , href 565 | , cap; 566 | 567 | while (src) { 568 | // escape 569 | if (cap = this.rules.escape.exec(src)) { 570 | src = src.substring(cap[0].length); 571 | out += cap[1]; 572 | continue; 573 | } 574 | 575 | // autolink 576 | if (cap = this.rules.autolink.exec(src)) { 577 | src = src.substring(cap[0].length); 578 | if (cap[2] === '@') { 579 | text = cap[1].charAt(6) === ':' 580 | ? this.mangle(cap[1].substring(7)) 581 | : this.mangle(cap[1]); 582 | href = this.mangle('mailto:') + text; 583 | } else { 584 | text = escape(cap[1]); 585 | href = text; 586 | } 587 | out += this.renderer.link(href, null, text); 588 | continue; 589 | } 590 | 591 | // url (gfm) 592 | if (!this.inLink && (cap = this.rules.url.exec(src))) { 593 | src = src.substring(cap[0].length); 594 | text = escape(cap[1]); 595 | href = text; 596 | out += this.renderer.link(href, null, text); 597 | continue; 598 | } 599 | 600 | // tag 601 | if (cap = this.rules.tag.exec(src)) { 602 | if (!this.inLink && /^/i.test(cap[0])) { 605 | this.inLink = false; 606 | } 607 | src = src.substring(cap[0].length); 608 | out += this.options.sanitize 609 | ? escape(cap[0]) 610 | : cap[0]; 611 | continue; 612 | } 613 | 614 | // link 615 | if (cap = this.rules.link.exec(src)) { 616 | src = src.substring(cap[0].length); 617 | this.inLink = true; 618 | out += this.outputLink(cap, { 619 | href: cap[2], 620 | title: cap[3] 621 | }); 622 | this.inLink = false; 623 | continue; 624 | } 625 | 626 | // reflink, nolink 627 | if ((cap = this.rules.reflink.exec(src)) 628 | || (cap = this.rules.nolink.exec(src))) { 629 | src = src.substring(cap[0].length); 630 | link = (cap[2] || cap[1]).replace(/\s+/g, ' '); 631 | link = this.links[link.toLowerCase()]; 632 | if (!link || !link.href) { 633 | out += cap[0].charAt(0); 634 | src = cap[0].substring(1) + src; 635 | continue; 636 | } 637 | this.inLink = true; 638 | out += this.outputLink(cap, link); 639 | this.inLink = false; 640 | continue; 641 | } 642 | 643 | // strong 644 | if (cap = this.rules.strong.exec(src)) { 645 | src = src.substring(cap[0].length); 646 | out += this.renderer.strong(this.output(cap[2] || cap[1])); 647 | continue; 648 | } 649 | 650 | // em 651 | if (cap = this.rules.em.exec(src)) { 652 | src = src.substring(cap[0].length); 653 | out += this.renderer.em(this.output(cap[2] || cap[1])); 654 | continue; 655 | } 656 | 657 | // code 658 | if (cap = this.rules.code.exec(src)) { 659 | src = src.substring(cap[0].length); 660 | out += this.renderer.codespan(escape(cap[2], true)); 661 | continue; 662 | } 663 | 664 | // br 665 | if (cap = this.rules.br.exec(src)) { 666 | src = src.substring(cap[0].length); 667 | out += this.renderer.br(); 668 | continue; 669 | } 670 | 671 | // del (gfm) 672 | if (cap = this.rules.del.exec(src)) { 673 | src = src.substring(cap[0].length); 674 | out += this.renderer.del(this.output(cap[1])); 675 | continue; 676 | } 677 | 678 | // text 679 | if (cap = this.rules.text.exec(src)) { 680 | src = src.substring(cap[0].length); 681 | out += escape(this.smartypants(cap[0])); 682 | continue; 683 | } 684 | 685 | if (src) { 686 | throw new 687 | Error('Infinite loop on byte: ' + src.charCodeAt(0)); 688 | } 689 | } 690 | 691 | return out; 692 | }; 693 | 694 | /** 695 | * Compile Link 696 | */ 697 | 698 | InlineLexer.prototype.outputLink = function(cap, link) { 699 | var href = escape(link.href) 700 | , title = link.title ? escape(link.title) : null; 701 | 702 | return cap[0].charAt(0) !== '!' 703 | ? this.renderer.link(href, title, this.output(cap[1])) 704 | : this.renderer.image(href, title, escape(cap[1])); 705 | }; 706 | 707 | /** 708 | * Smartypants Transformations 709 | */ 710 | 711 | InlineLexer.prototype.smartypants = function(text) { 712 | if (!this.options.smartypants) return text; 713 | return text 714 | // em-dashes 715 | .replace(/--/g, '\u2014') 716 | // opening singles 717 | .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018') 718 | // closing singles & apostrophes 719 | .replace(/'/g, '\u2019') 720 | // opening doubles 721 | .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c') 722 | // closing doubles 723 | .replace(/"/g, '\u201d') 724 | // ellipses 725 | .replace(/\.{3}/g, '\u2026'); 726 | }; 727 | 728 | /** 729 | * Mangle Links 730 | */ 731 | 732 | InlineLexer.prototype.mangle = function(text) { 733 | var out = '' 734 | , l = text.length 735 | , i = 0 736 | , ch; 737 | 738 | for (; i < l; i++) { 739 | ch = text.charCodeAt(i); 740 | if (Math.random() > 0.5) { 741 | ch = 'x' + ch.toString(16); 742 | } 743 | out += '&#' + ch + ';'; 744 | } 745 | 746 | return out; 747 | }; 748 | 749 | /** 750 | * Renderer 751 | */ 752 | 753 | function Renderer(options) { 754 | this.options = options || {}; 755 | } 756 | 757 | Renderer.prototype.code = function(code, lang, escaped) { 758 | if (this.options.highlight) { 759 | var out = this.options.highlight(code, lang); 760 | if (out != null && out !== code) { 761 | escaped = true; 762 | code = out; 763 | } 764 | } 765 | 766 | if (!lang) { 767 | return '
'
 768 |       + (escaped ? code : escape(code, true))
 769 |       + '\n
'; 770 | } 771 | 772 | return '
'
 776 |     + (escaped ? code : escape(code, true))
 777 |     + '\n
\n'; 778 | }; 779 | 780 | Renderer.prototype.blockquote = function(quote) { 781 | return '
\n' + quote + '
\n'; 782 | }; 783 | 784 | Renderer.prototype.html = function(html) { 785 | return html; 786 | }; 787 | 788 | Renderer.prototype.heading = function(text, level, raw) { 789 | return '' 795 | + text 796 | + '\n'; 799 | }; 800 | 801 | Renderer.prototype.hr = function() { 802 | return this.options.xhtml ? '
\n' : '
\n'; 803 | }; 804 | 805 | Renderer.prototype.list = function(body, ordered) { 806 | var type = ordered ? 'ol' : 'ul'; 807 | return '<' + type + '>\n' + body + '\n'; 808 | }; 809 | 810 | Renderer.prototype.listitem = function(text) { 811 | return '
  • ' + text + '
  • \n'; 812 | }; 813 | 814 | Renderer.prototype.paragraph = function(text) { 815 | return '

    ' + text + '

    \n'; 816 | }; 817 | 818 | Renderer.prototype.table = function(header, body) { 819 | return '\n' 820 | + '\n' 821 | + header 822 | + '\n' 823 | + '\n' 824 | + body 825 | + '\n' 826 | + '
    \n'; 827 | }; 828 | 829 | Renderer.prototype.tablerow = function(content) { 830 | return '\n' + content + '\n'; 831 | }; 832 | 833 | Renderer.prototype.tablecell = function(content, flags) { 834 | var type = flags.header ? 'th' : 'td'; 835 | var tag = flags.align 836 | ? '<' + type + ' style="text-align:' + flags.align + '">' 837 | : '<' + type + '>'; 838 | return tag + content + '\n'; 839 | }; 840 | 841 | // span level renderer 842 | Renderer.prototype.strong = function(text) { 843 | return '' + text + ''; 844 | }; 845 | 846 | Renderer.prototype.em = function(text) { 847 | return '' + text + ''; 848 | }; 849 | 850 | Renderer.prototype.codespan = function(text) { 851 | return '' + text + ''; 852 | }; 853 | 854 | Renderer.prototype.br = function() { 855 | return this.options.xhtml ? '
    ' : '
    '; 856 | }; 857 | 858 | Renderer.prototype.del = function(text) { 859 | return '' + text + ''; 860 | }; 861 | 862 | Renderer.prototype.link = function(href, title, text) { 863 | if (this.options.sanitize) { 864 | try { 865 | var prot = decodeURIComponent(unescape(href)) 866 | .replace(/[^\w:]/g, '') 867 | .toLowerCase(); 868 | } catch (e) { 869 | return ''; 870 | } 871 | if (prot.indexOf('javascript:') === 0) { 872 | return ''; 873 | } 874 | } 875 | var out = '
    '; 880 | return out; 881 | }; 882 | 883 | Renderer.prototype.image = function(href, title, text) { 884 | var out = '' + text + '' : '>'; 889 | return out; 890 | }; 891 | 892 | /** 893 | * Parsing & Compiling 894 | */ 895 | 896 | function Parser(options) { 897 | this.tokens = []; 898 | this.token = null; 899 | this.options = options || marked.defaults; 900 | this.options.renderer = this.options.renderer || new Renderer; 901 | this.renderer = this.options.renderer; 902 | this.renderer.options = this.options; 903 | } 904 | 905 | /** 906 | * Static Parse Method 907 | */ 908 | 909 | Parser.parse = function(src, options, renderer) { 910 | var parser = new Parser(options, renderer); 911 | return parser.parse(src); 912 | }; 913 | 914 | /** 915 | * Parse Loop 916 | */ 917 | 918 | Parser.prototype.parse = function(src) { 919 | this.inline = new InlineLexer(src.links, this.options, this.renderer); 920 | this.tokens = src.reverse(); 921 | 922 | var out = ''; 923 | while (this.next()) { 924 | out += this.tok(); 925 | } 926 | 927 | return out; 928 | }; 929 | 930 | /** 931 | * Next Token 932 | */ 933 | 934 | Parser.prototype.next = function() { 935 | return this.token = this.tokens.pop(); 936 | }; 937 | 938 | /** 939 | * Preview Next Token 940 | */ 941 | 942 | Parser.prototype.peek = function() { 943 | return this.tokens[this.tokens.length - 1] || 0; 944 | }; 945 | 946 | /** 947 | * Parse Text Tokens 948 | */ 949 | 950 | Parser.prototype.parseText = function() { 951 | var body = this.token.text; 952 | 953 | while (this.peek().type === 'text') { 954 | body += '\n' + this.next().text; 955 | } 956 | 957 | return this.inline.output(body); 958 | }; 959 | 960 | /** 961 | * Parse Current Token 962 | */ 963 | 964 | Parser.prototype.tok = function() { 965 | switch (this.token.type) { 966 | case 'space': { 967 | return ''; 968 | } 969 | case 'hr': { 970 | return this.renderer.hr(); 971 | } 972 | case 'heading': { 973 | return this.renderer.heading( 974 | this.inline.output(this.token.text), 975 | this.token.depth, 976 | this.token.text); 977 | } 978 | case 'code': { 979 | return this.renderer.code(this.token.text, 980 | this.token.lang, 981 | this.token.escaped); 982 | } 983 | case 'table': { 984 | var header = '' 985 | , body = '' 986 | , i 987 | , row 988 | , cell 989 | , flags 990 | , j; 991 | 992 | // header 993 | cell = ''; 994 | for (i = 0; i < this.token.header.length; i++) { 995 | flags = { header: true, align: this.token.align[i] }; 996 | cell += this.renderer.tablecell( 997 | this.inline.output(this.token.header[i]), 998 | { header: true, align: this.token.align[i] } 999 | ); 1000 | } 1001 | header += this.renderer.tablerow(cell); 1002 | 1003 | for (i = 0; i < this.token.cells.length; i++) { 1004 | row = this.token.cells[i]; 1005 | 1006 | cell = ''; 1007 | for (j = 0; j < row.length; j++) { 1008 | cell += this.renderer.tablecell( 1009 | this.inline.output(row[j]), 1010 | { header: false, align: this.token.align[j] } 1011 | ); 1012 | } 1013 | 1014 | body += this.renderer.tablerow(cell); 1015 | } 1016 | return this.renderer.table(header, body); 1017 | } 1018 | case 'blockquote_start': { 1019 | var body = ''; 1020 | 1021 | while (this.next().type !== 'blockquote_end') { 1022 | body += this.tok(); 1023 | } 1024 | 1025 | return this.renderer.blockquote(body); 1026 | } 1027 | case 'list_start': { 1028 | var body = '' 1029 | , ordered = this.token.ordered; 1030 | 1031 | while (this.next().type !== 'list_end') { 1032 | body += this.tok(); 1033 | } 1034 | 1035 | return this.renderer.list(body, ordered); 1036 | } 1037 | case 'list_item_start': { 1038 | var body = ''; 1039 | 1040 | while (this.next().type !== 'list_item_end') { 1041 | body += this.token.type === 'text' 1042 | ? this.parseText() 1043 | : this.tok(); 1044 | } 1045 | 1046 | return this.renderer.listitem(body); 1047 | } 1048 | case 'loose_item_start': { 1049 | var body = ''; 1050 | 1051 | while (this.next().type !== 'list_item_end') { 1052 | body += this.tok(); 1053 | } 1054 | 1055 | return this.renderer.listitem(body); 1056 | } 1057 | case 'html': { 1058 | var html = !this.token.pre && !this.options.pedantic 1059 | ? this.inline.output(this.token.text) 1060 | : this.token.text; 1061 | return this.renderer.html(html); 1062 | } 1063 | case 'paragraph': { 1064 | return this.renderer.paragraph(this.inline.output(this.token.text)); 1065 | } 1066 | case 'text': { 1067 | return this.renderer.paragraph(this.parseText()); 1068 | } 1069 | } 1070 | }; 1071 | 1072 | /** 1073 | * Helpers 1074 | */ 1075 | 1076 | function escape(html, encode) { 1077 | return html 1078 | .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') 1079 | .replace(//g, '>') 1081 | .replace(/"/g, '"') 1082 | .replace(/'/g, '''); 1083 | } 1084 | 1085 | function unescape(html) { 1086 | return html.replace(/&([#\w]+);/g, function(_, n) { 1087 | n = n.toLowerCase(); 1088 | if (n === 'colon') return ':'; 1089 | if (n.charAt(0) === '#') { 1090 | return n.charAt(1) === 'x' 1091 | ? String.fromCharCode(parseInt(n.substring(2), 16)) 1092 | : String.fromCharCode(+n.substring(1)); 1093 | } 1094 | return ''; 1095 | }); 1096 | } 1097 | 1098 | function replace(regex, opt) { 1099 | regex = regex.source; 1100 | opt = opt || ''; 1101 | return function self(name, val) { 1102 | if (!name) return new RegExp(regex, opt); 1103 | val = val.source || val; 1104 | val = val.replace(/(^|[^\[])\^/g, '$1'); 1105 | regex = regex.replace(name, val); 1106 | return self; 1107 | }; 1108 | } 1109 | 1110 | function noop() {} 1111 | noop.exec = noop; 1112 | 1113 | function merge(obj) { 1114 | var i = 1 1115 | , target 1116 | , key; 1117 | 1118 | for (; i < arguments.length; i++) { 1119 | target = arguments[i]; 1120 | for (key in target) { 1121 | if (Object.prototype.hasOwnProperty.call(target, key)) { 1122 | obj[key] = target[key]; 1123 | } 1124 | } 1125 | } 1126 | 1127 | return obj; 1128 | } 1129 | 1130 | 1131 | /** 1132 | * Marked 1133 | */ 1134 | 1135 | function marked(src, opt, callback) { 1136 | if (callback || typeof opt === 'function') { 1137 | if (!callback) { 1138 | callback = opt; 1139 | opt = null; 1140 | } 1141 | 1142 | opt = merge({}, marked.defaults, opt || {}); 1143 | 1144 | var highlight = opt.highlight 1145 | , tokens 1146 | , pending 1147 | , i = 0; 1148 | 1149 | try { 1150 | tokens = Lexer.lex(src, opt) 1151 | } catch (e) { 1152 | return callback(e); 1153 | } 1154 | 1155 | pending = tokens.length; 1156 | 1157 | var done = function() { 1158 | var out, err; 1159 | 1160 | try { 1161 | out = Parser.parse(tokens, opt); 1162 | } catch (e) { 1163 | err = e; 1164 | } 1165 | 1166 | opt.highlight = highlight; 1167 | 1168 | return err 1169 | ? callback(err) 1170 | : callback(null, out); 1171 | }; 1172 | 1173 | if (!highlight || highlight.length < 3) { 1174 | return done(); 1175 | } 1176 | 1177 | delete opt.highlight; 1178 | 1179 | if (!pending) return done(); 1180 | 1181 | for (; i < tokens.length; i++) { 1182 | (function(token) { 1183 | if (token.type !== 'code') { 1184 | return --pending || done(); 1185 | } 1186 | return highlight(token.text, token.lang, function(err, code) { 1187 | if (code == null || code === token.text) { 1188 | return --pending || done(); 1189 | } 1190 | token.text = code; 1191 | token.escaped = true; 1192 | --pending || done(); 1193 | }); 1194 | })(tokens[i]); 1195 | } 1196 | 1197 | return; 1198 | } 1199 | try { 1200 | if (opt) opt = merge({}, marked.defaults, opt); 1201 | return Parser.parse(Lexer.lex(src, opt), opt); 1202 | } catch (e) { 1203 | e.message += '\nPlease report this to https://github.com/chjj/marked.'; 1204 | if ((opt || marked.defaults).silent) { 1205 | return '

    An error occured:

    '
    1206 |         + escape(e.message + '', true)
    1207 |         + '
    '; 1208 | } 1209 | throw e; 1210 | } 1211 | } 1212 | 1213 | /** 1214 | * Options 1215 | */ 1216 | 1217 | marked.options = 1218 | marked.setOptions = function(opt) { 1219 | merge(marked.defaults, opt); 1220 | return marked; 1221 | }; 1222 | 1223 | marked.defaults = { 1224 | gfm: true, 1225 | tables: true, 1226 | breaks: false, 1227 | pedantic: false, 1228 | sanitize: false, 1229 | smartLists: false, 1230 | silent: false, 1231 | highlight: null, 1232 | langPrefix: 'lang-', 1233 | smartypants: false, 1234 | headerPrefix: '', 1235 | renderer: new Renderer, 1236 | xhtml: false 1237 | }; 1238 | 1239 | /** 1240 | * Expose 1241 | */ 1242 | 1243 | marked.Parser = Parser; 1244 | marked.parser = Parser.parse; 1245 | 1246 | marked.Renderer = Renderer; 1247 | 1248 | marked.Lexer = Lexer; 1249 | marked.lexer = Lexer.lex; 1250 | 1251 | marked.InlineLexer = InlineLexer; 1252 | marked.inlineLexer = InlineLexer.output; 1253 | 1254 | marked.parse = marked; 1255 | 1256 | if (typeof exports === 'object') { 1257 | module.exports = marked; 1258 | } else if (typeof define === 'function' && define.amd) { 1259 | define(function() { return marked; }); 1260 | } else { 1261 | this.marked = marked; 1262 | } 1263 | 1264 | }).call(function() { 1265 | return this || (typeof window !== 'undefined' ? window : global); 1266 | }()); 1267 | --------------------------------------------------------------------------------