diff --git a/.travis.yml b/.travis.yml index cbbdb66..7a195bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,5 @@ language: ruby rvm: - "2.0.0" before_script: rake db:setup +before_script: bundle exec rake db:setup env: RAILSGOAT_MAINTAINER=true \ No newline at end of file diff --git a/Gemfile b/Gemfile index 7bffb9c..c939fa8 100755 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,10 @@ source 'https://rubygems.org' -gem 'rails', '3.2.15' +#don't upgrade +gem 'rails', '3.2.11' +gem 'rack', '1.4.0' + +gem 'rack-ssl', '1.3.4' ruby '2.0.0' @@ -27,12 +31,12 @@ end gem 'gauntlt' -gem 'simplecov', '0.8.0.pre2', :require => false, :group => :test +gem 'simplecov', :require => false, :group => :test group :development, :test do gem 'launchy' gem 'capybara' - gem 'database_cleaner', '< 1.1.0' + gem 'database_cleaner' gem 'poltergeist' gem 'rspec-rails' end @@ -49,7 +53,6 @@ group :assets do gem 'uglifier' end - gem 'jquery-rails' # To use ActiveModel has_secure_password @@ -78,3 +81,5 @@ gem 'aruba' gem 'execjs' gem 'therubyracer' +# Add SMTP server support using MailCatcher +gem 'mailcatcher' diff --git a/Gemfile.lock b/Gemfile.lock index aed7bd1..0cbaddd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,60 +1,62 @@ GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.15) - actionpack (= 3.2.15) - mail (~> 2.5.4) - actionpack (3.2.15) - activemodel (= 3.2.15) - activesupport (= 3.2.15) + actionmailer (3.2.11) + actionpack (= 3.2.11) + mail (~> 2.4.4) + actionpack (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) - rack (~> 1.4.5) + rack (~> 1.4.0) rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.2.1) - activemodel (3.2.15) - activesupport (= 3.2.15) + activemodel (3.2.11) + activesupport (= 3.2.11) builder (~> 3.0.0) - activerecord (3.2.15) - activemodel (= 3.2.15) - activesupport (= 3.2.15) + activerecord (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.15) - activemodel (= 3.2.15) - activesupport (= 3.2.15) - activesupport (3.2.15) - i18n (~> 0.6, >= 0.6.4) + activeresource (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) + activesupport (3.2.11) + i18n (~> 0.6) multi_json (~> 1.0) - addressable (2.3.5) - arel (3.0.2) - aruba (0.5.3) + addressable (2.3.6) + arel (3.0.3) + aruba (0.5.4) childprocess (>= 0.3.6) cucumber (>= 1.1.1) rspec-expectations (>= 2.7.0) - bcrypt-ruby (3.1.2) - better_errors (1.0.1) + bcrypt (3.1.7) + bcrypt-ruby (3.1.5) + bcrypt (>= 3.1.3) + better_errors (1.1.0) coderay (>= 1.0.0) erubis (>= 2.6.6) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - brakeman (2.2.0) + brakeman (2.4.3) erubis (~> 2.6) fastercsv (~> 1.5) haml (>= 3.0, < 5.0) highline (~> 1.6.20) multi_json (~> 1.2) ruby2ruby (~> 2.0.5) - ruby_parser (~> 3.2.2) + ruby_parser (~> 3.4.0) sass (~> 3.0) slim (>= 1.3.6, < 3.0) terminal-table (~> 1.4) builder (3.0.4) - bundler-audit (0.2.0) + bundler-audit (0.3.0) bundler (~> 1.2) - capybara (2.1.0) + capybara (2.2.1) mime-types (>= 1.16) nokogiri (>= 1.3.3) rack (>= 1.0.0) @@ -62,9 +64,12 @@ GEM xpath (~> 2.0) celluloid (0.15.2) timers (~> 1.1.0) - childprocess (0.3.9) + celluloid-io (0.15.0) + celluloid (>= 0.15.0) + nio4r (>= 0.5.0) + childprocess (0.5.2) ffi (~> 1.0, >= 1.0.11) - cliver (0.2.2) + cliver (0.3.2) coderay (1.1.0) coffee-rails (3.2.2) coffee-script (>= 2.2.0) @@ -72,18 +77,19 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.6.3) - cucumber (1.3.8) + coffee-script-source (1.7.0) + cucumber (1.3.11) builder (>= 2.1.2) diff-lcs (>= 1.1.3) - gherkin (~> 2.12.1) + gherkin (~> 2.12) multi_json (>= 1.7.5, < 2.0) multi_test (>= 0.0.2) - database_cleaner (1.0.1) + daemons (1.1.9) + database_cleaner (1.2.0) debug_inspector (0.0.2) - diff-lcs (1.2.4) - docile (1.1.0) - dotenv (0.9.0) + diff-lcs (1.2.5) + docile (1.1.3) + dotenv (0.10.0) em-websocket (0.5.0) eventmachine (>= 0.12.9) http_parser.rb (~> 0.5.3) @@ -91,105 +97,124 @@ GEM eventmachine (1.0.3) execjs (2.0.2) fastercsv (1.5.5) - ffi (1.9.0) + ffi (1.9.3) foreman (0.63.0) dotenv (>= 0.7) thor (>= 0.13.6) - gauntlt (1.0.6) - aruba - cucumber - nokogiri (~> 1.5.0) - trollop + formatador (0.2.4) + gauntlt (1.0.8) + aruba (= 0.5.4) + cucumber (= 1.3.11) + nokogiri (= 1.6.1) + trollop (~> 2.0) gherkin (2.12.2) multi_json (~> 1.3) - guard (1.4.0) - listen (>= 0.4.2) - thor (>= 0.14.6) + guard (2.6.0) + formatador (>= 0.2.4) + listen (~> 2.7) + lumberjack (~> 1.0) + pry (>= 0.9.12) + thor (>= 0.18.1) guard-brakeman (0.8.1) brakeman (>= 2.1.1) guard (>= 1.1.0) - guard-livereload (1.0.3) - em-websocket (>= 0.2.0) + guard-livereload (2.1.2) + em-websocket (~> 0.5) + guard (~> 2.0) + multi_json (~> 1.8) + guard-rspec (4.2.8) + guard (~> 2.1) + rspec (>= 2.14, < 4.0) + guard-shell (0.6.1) guard (>= 1.1.0) - multi_json (~> 1.0) - guard-rspec (2.5.4) - guard (>= 1.1) - rspec (~> 2.11) - guard-shell (0.5.1) - guard (>= 1.1.0) - haml (4.0.3) + haml (4.0.5) tilt hashr (0.0.22) - highline (1.6.20) + highline (1.6.21) hike (1.2.3) http_parser.rb (0.5.3) - i18n (0.6.5) + i18n (0.6.9) journey (1.0.4) jquery-fileupload-rails (0.4.1) actionpack (>= 3.1) railties (>= 3.1) - jquery-rails (3.0.4) + jquery-rails (3.1.0) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) json (1.8.1) - kgio (2.8.1) - launchy (2.3.0) + kgio (2.9.2) + launchy (2.4.2) addressable (~> 2.3) libv8 (3.16.14.3) - listen (2.1.2) + listen (2.7.1) celluloid (>= 0.15.2) + celluloid-io (>= 0.15.0) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - lockfile (2.1.0) - mail (2.5.4) + lumberjack (1.0.5) + mail (2.4.4) + i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) + mailcatcher (0.5.12) + activesupport (~> 3.0) + eventmachine (~> 1.0.0) + haml (>= 3.1, < 5) + mail (~> 2.3) + sinatra (~> 1.2) + skinny (~> 0.2.3) + sqlite3 (~> 1.3) + thin (~> 1.5.0) method_source (0.8.2) - mime-types (1.25) - multi_json (1.8.2) - multi_test (0.0.2) - nokogiri (1.5.10) - poltergeist (1.4.1) - capybara (~> 2.1.0) - cliver (~> 0.2.1) + mime-types (1.25.1) + mini_portile (0.5.3) + multi_json (1.9.2) + multi_test (0.1.1) + nio4r (1.0.0) + nokogiri (1.6.1) + mini_portile (~> 0.5.0) + poltergeist (1.5.0) + capybara (~> 2.1) + cliver (~> 0.3.1) multi_json (~> 1.0) websocket-driver (>= 0.2.0) - polyglot (0.3.3) - powder (0.2.0) + polyglot (0.3.4) + powder (0.2.1) thor (>= 0.11.5) - pry (0.9.6) - coderay (>= 0.9.8) - method_source (>= 0.6.5) - ruby_parser (>= 2.0.5) - slop (~> 2.1.0) - rack (1.4.5) + pry (0.9.12.6) + coderay (~> 1.0) + method_source (~> 0.8) + slop (~> 3.4) + rack (1.4.0) rack-cache (1.2) rack (>= 0.4) rack-livereload (0.3.15) rack - rack-ssl (1.3.3) + rack-protection (1.5.2) + rack + rack-ssl (1.3.4) rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.15) - actionmailer (= 3.2.15) - actionpack (= 3.2.15) - activerecord (= 3.2.15) - activeresource (= 3.2.15) - activesupport (= 3.2.15) + rails (3.2.11) + actionmailer (= 3.2.11) + actionpack (= 3.2.11) + activerecord (= 3.2.11) + activeresource (= 3.2.11) + activesupport (= 3.2.11) bundler (~> 1.0) - railties (= 3.2.15) - railties (3.2.15) - actionpack (= 3.2.15) - activesupport (= 3.2.15) + railties (= 3.2.11) + railties (3.2.11) + actionpack (= 3.2.11) + activesupport (= 3.2.11) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - raindrops (0.12.0) - rake (10.1.0) - rb-fsevent (0.9.3) - rb-inotify (0.9.2) + raindrops (0.13.0) + rake (10.2.2) + rb-fsevent (0.9.4) + rb-inotify (0.9.3) ffi (>= 0.5.0) rdoc (3.12.2) json (~> 1.4) @@ -198,67 +223,80 @@ GEM rspec-core (~> 2.14.0) rspec-expectations (~> 2.14.0) rspec-mocks (~> 2.14.0) - rspec-core (2.14.6) - rspec-expectations (2.14.3) + rspec-core (2.14.8) + rspec-expectations (2.14.5) diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.14.4) - rspec-rails (2.14.0) + rspec-mocks (2.14.6) + rspec-rails (2.14.2) actionpack (>= 3.0) + activemodel (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) rspec-core (~> 2.14.0) rspec-expectations (~> 2.14.0) rspec-mocks (~> 2.14.0) - ruby2ruby (2.0.6) + ruby2ruby (2.0.8) ruby_parser (~> 3.1) sexp_processor (~> 4.0) - ruby_parser (3.2.2) + ruby_parser (3.4.1) sexp_processor (~> 4.1) - sass (3.2.12) + safe_yaml (0.9.7) + sass (3.3.4) sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - sexp_processor (4.4.0) - simplecov (0.8.0.pre2) + sexp_processor (4.4.3) + simplecov (0.8.2) docile (~> 1.1.0) - lockfile (>= 2.1.0) multi_json - simplecov-html (~> 0.7.1) - simplecov-html (0.7.1) + simplecov-html (~> 0.8.0) + simplecov-html (0.8.0) + sinatra (1.4.4) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (~> 1.3, >= 1.3.4) + skinny (0.2.3) + eventmachine (~> 1.0.0) + thin (~> 1.5.0) slim (2.0.2) temple (~> 0.6.6) tilt (>= 1.3.3, < 2.1) - slop (2.1.0) + slop (3.5.0) sprockets (2.2.2) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sqlite3 (1.3.8) + sqlite3 (1.3.9) temple (0.6.7) terminal-table (1.4.5) - therubyracer (0.12.0) + therubyracer (0.12.1) libv8 (~> 3.16.14.0) ref - thor (0.18.1) + thin (1.5.1) + daemons (>= 1.0.9) + eventmachine (>= 0.12.6) + rack (>= 1.0.0) + thor (0.19.1) tilt (1.4.1) timers (1.1.0) - travis-lint (1.7.0) + travis-lint (1.8.0) hashr (~> 0.0.22) + safe_yaml (~> 0.9.0) treetop (1.4.15) polyglot polyglot (>= 0.3.1) trollop (2.0) - tzinfo (0.3.38) - uglifier (2.3.0) + tzinfo (0.3.39) + uglifier (2.5.0) execjs (>= 0.3.0) json (>= 1.8.0) - unicorn (4.6.3) + unicorn (4.8.2) kgio (~> 2.6) rack raindrops (~> 0.7) - websocket-driver (0.3.0) + websocket-driver (0.3.2) xpath (2.0.0) nokogiri (~> 1.3) @@ -274,7 +312,7 @@ DEPENDENCIES bundler-audit capybara coffee-rails - database_cleaner (< 1.1.0) + database_cleaner execjs foreman gauntlt @@ -285,15 +323,18 @@ DEPENDENCIES jquery-fileupload-rails jquery-rails launchy + mailcatcher poltergeist powder pry + rack (= 1.4.0) rack-livereload - rails (= 3.2.15) + rack-ssl (= 1.3.4) + rails (= 3.2.11) rb-fsevent rspec-rails sass-rails - simplecov (= 0.8.0.pre2) + simplecov sqlite3 therubyracer travis-lint diff --git a/README.md b/README.md index 67afc81..7e1aac2 100755 --- a/README.md +++ b/README.md @@ -1,78 +1,110 @@ -## Getting Started ## -#### With Ruby, Rubygems, Git, and Bundler installed #### +# RailsGoat [![Build Status](https://api.travis-ci.org/OWASP/railsgoat.png?branch=master)](https://travis-ci.org/OWASP/railsgoat) [![Code Climate](https://codeclimate.com/github/OWASP/railsgoat.png)](https://codeclimate.com/github/OWASP/railsgoat) - git clone https://github.com/OWASP/railsgoat.git +RailsGoat is a vulnerable version of the Ruby on Rails Framework. It includes vulnerabilities from the OWASP Top 10, as well as some "extras" that the initial project contributors felt worthwhile to share. This project is designed to educate both developers, as well as security professionals. - cd railsgoat +## Getting Started - rvm use 2.0.0@railsgoat --create # https://rvm.io/ - bundle - rake db:setup +To begin, install the Ruby Version Manager (RVM): - rails s +``` +$ curl -L https://get.rvm.io | bash -s stable --autolibs=3 --ruby=1.9.3 +$ rvm use 2.0.0@railsgoat --create # https://rvm.io/ +``` - open http://0.0.0.0:3000 +After installing the package, clone this repo: - Start hacking!!! +``` +$ git clone git@github.com:OWASP/railsgoat.git +``` -### Running Capybara Tests ### +Navigate into the directory and accept the notice by typing `yes`: +``` +**************************************************************************************************** +* NOTICE * +**************************************************************************************************** +* RVM has encountered a new or modified .rvmrc file in the current directory, this is a shell * +* script and therefore may contain any shell commands. * +* * +* Examine the contents of this file carefully to be sure the contents are safe before trusting it! * +* Do you wish to trust '/path/to/railsgoat/.rvmrc'? * +* Choose v[view] below to view the contents * +**************************************************************************************************** +y[es], n[o], v[iew], c[cancel]> +``` -RailsGoat now includes a set of _failing_ Capybara RSpecs, each one indicating a separate vulnerability exists -in the application. +Install the project dependencies: -To run them, though, you'll first need to [install PhantomJS](https://github.com/jonleighton/poltergeist#installing-phantomjs), -which is required by the Poltergeist Capybara driver. Then just rake: +``` +$ bundle install +``` - rake training +If you receive an error, make sure you have `bundler` installed: -NOTE: As vulnerabilities are fixed in the application, these specs won't change from to passing but to _pending_. +``` +$ gem install bundler +``` -### Developer Note ### +Initialize the database: -As changes are made to the application, the Capybara RSpecs can be used to verify the vulnerabilities -in the application are still intact. To use them in this way, and have them _pass_ instead of fail, -set the `RAILSGOAT_MAINTAINER` environment variable. +``` +$ rake db:setup +``` -

-Conversion to the OWASP Top 10, 2013 is under way. +Start the WEBrick HTTP Server: -You can view progress within the top-10-2013 branch. +``` +$ rails server +``` - git fetch origin - git checkout top-10-2013 -Then proceed with browsing the site as normal :thumbsup: -


+Open your favorite browser, navigate to `http://localhost:3000` and start hacking! -### Build Info ### +## Capybara Tests -[![Code Climate](https://codeclimate.com/github/OWASP/railsgoat.png)](https://codeclimate.com/github/OWASP/railsgoat) +RailsGoat now includes a set of failing Capybara RSpecs, each one indicating that a separate vulnerability exists in the application. To run them, you first need to install [PhantomJS](https://github.com/jonleighton/poltergeist#installing-phantomjs), which is required by the Poltergeist Capybara driver. Upon installation, simply run the following rake task: -[![Build Status](https://travis-ci.org/OWASP/railsgoat.png?branch=master)](https://travis-ci.org/OWASP/railsgoat) +``` +$ rake training +``` -### License Stuff ### +NOTE: As vulnerabilities are fixed in the application, these specs will not change to `passing`, but to `pending`. + +## Processing Email + +In order for RailsGoat to effectively process email, you will first need to run MailCatcher, an SMTP server that will intercept email messages and display them in a web interface. + +To start an instance of MailCatcher, simply run: + +``` +$ mailcatcher +``` + +If successful, you should see the following output: + +``` +Starting MailCatcher +==> smtp://127.0.0.1:1025 +==> http://127.0.0.1:1080 +*** MailCatcher runs as a daemon by default. Go to the web interface to quit. +``` + +Alternatively, you can run MailCatcher in the foreground by running `mailcatcher -f` in your terminal. + +## Contributing + +As changes are made to the application, the Capybara RSpecs can be used to verify that the vulnerabilities in the application are still intact. To use them in this way, and have them `pass` instead of `fail`, set the `RAILSGOAT_MAINTAINER` environment variable. + +Conversion to the OWASP Top Ten 2013 completed in November, 2013. + +# License The MIT License (MIT) -Copyright (c) 2013 The Open Web Application Security Project +Copyright (c) 2013 The Open Web Application Security Project -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.rdoc b/README.rdoc deleted file mode 100755 index 3e1c15c..0000000 --- a/README.rdoc +++ /dev/null @@ -1,261 +0,0 @@ -== Welcome to Rails - -Rails is a web-application framework that includes everything needed to create -database-backed web applications according to the Model-View-Control pattern. - -This pattern splits the view (also called the presentation) into "dumb" -templates that are primarily responsible for inserting pre-built data in between -HTML tags. The model contains the "smart" domain objects (such as Account, -Product, Person, Post) that holds all the business logic and knows how to -persist themselves to a database. The controller handles the incoming requests -(such as Save New Account, Update Product, Show Post) by manipulating the model -and directing data to the view. - -In Rails, the model is handled by what's called an object-relational mapping -layer entitled Active Record. This layer allows you to present the data from -database rows as objects and embellish these data objects with business logic -methods. You can read more about Active Record in -link:files/vendor/rails/activerecord/README.html. - -The controller and view are handled by the Action Pack, which handles both -layers by its two parts: Action View and Action Controller. These two layers -are bundled in a single package due to their heavy interdependence. This is -unlike the relationship between the Active Record and Action Pack that is much -more separate. Each of these packages can be used independently outside of -Rails. You can read more about Action Pack in -link:files/vendor/rails/actionpack/README.html. - - -== Getting Started - -1. At the command prompt, create a new Rails application: - rails new myapp (where myapp is the application name) - -2. Change directory to myapp and start the web server: - cd myapp; rails server (run with --help for options) - -3. Go to http://localhost:3000/ and you'll see: - "Welcome aboard: You're riding Ruby on Rails!" - -4. Follow the guidelines to start developing your application. You can find -the following resources handy: - -* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html -* Ruby on Rails Tutorial Book: http://www.railstutorial.org/ - - -== Debugging Rails - -Sometimes your application goes wrong. Fortunately there are a lot of tools that -will help you debug it and get it back on the rails. - -First area to check is the application log files. Have "tail -f" commands -running on the server.log and development.log. Rails will automatically display -debugging and runtime information to these files. Debugging info will also be -shown in the browser on requests from 127.0.0.1. - -You can also log your own messages directly into the log file from your code -using the Ruby logger class from inside your controllers. Example: - - class WeblogController < ActionController::Base - def destroy - @weblog = Weblog.find(params[:id]) - @weblog.destroy - logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") - end - end - -The result will be a message in your log file along the lines of: - - Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! - -More information on how to use the logger is at http://www.ruby-doc.org/core/ - -Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are -several books available online as well: - -* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) -* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) - -These two books will bring you up to speed on the Ruby language and also on -programming in general. - - -== Debugger - -Debugger support is available through the debugger command when you start your -Mongrel or WEBrick server with --debugger. This means that you can break out of -execution at any point in the code, investigate and change the model, and then, -resume execution! You need to install ruby-debug to run the server in debugging -mode. With gems, use sudo gem install ruby-debug. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.all - debugger - end - end - -So the controller will accept the action, run the first line, then present you -with a IRB prompt in the server window. Here you can do things like: - - >> @posts.inspect - => "[#nil, "body"=>nil, "id"=>"1"}>, - #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" - >> @posts.first.title = "hello from a debugger" - => "hello from a debugger" - -...and even better, you can examine how your runtime objects actually work: - - >> f = @posts.first - => #nil, "body"=>nil, "id"=>"1"}> - >> f. - Display all 152 possibilities? (y or n) - -Finally, when you're ready to resume execution, you can enter "cont". - - -== Console - -The console is a Ruby shell, which allows you to interact with your -application's domain model. Here you'll have all parts of the application -configured, just like it is when the application is running. You can inspect -domain models, change values, and save to the database. Starting the script -without arguments will launch it in the development environment. - -To start the console, run rails console from the application -directory. - -Options: - -* Passing the -s, --sandbox argument will rollback any modifications - made to the database. -* Passing an environment name as an argument will load the corresponding - environment. Example: rails console production. - -To reload your controllers and models after launching the console run -reload! - -More information about irb can be found at: -link:http://www.rubycentral.org/pickaxe/irb.html - - -== dbconsole - -You can go to the command line of your database directly through rails -dbconsole. You would be connected to the database with the credentials -defined in database.yml. Starting the script without arguments will connect you -to the development database. Passing an argument will connect you to a different -database, like rails dbconsole production. Currently works for MySQL, -PostgreSQL and SQLite 3. - -== Description of Contents - -The default directory structure of a generated Ruby on Rails application: - - |-- app - | |-- assets - | | |-- images - | | |-- javascripts - | | `-- stylesheets - | |-- controllers - | |-- helpers - | |-- mailers - | |-- models - | `-- views - | `-- layouts - |-- config - | |-- environments - | |-- initializers - | `-- locales - |-- db - |-- doc - |-- lib - | |-- assets - | `-- tasks - |-- log - |-- public - |-- script - |-- test - | |-- fixtures - | |-- functional - | |-- integration - | |-- performance - | `-- unit - |-- tmp - | `-- cache - | `-- assets - `-- vendor - |-- assets - | |-- javascripts - | `-- stylesheets - `-- plugins - -app - Holds all the code that's specific to this particular application. - -app/assets - Contains subdirectories for images, stylesheets, and JavaScript files. - -app/controllers - Holds controllers that should be named like weblogs_controller.rb for - automated URL mapping. All controllers should descend from - ApplicationController which itself descends from ActionController::Base. - -app/models - Holds models that should be named like post.rb. Models descend from - ActiveRecord::Base by default. - -app/views - Holds the template files for the view that should be named like - weblogs/index.html.erb for the WeblogsController#index action. All views use - eRuby syntax by default. - -app/views/layouts - Holds the template files for layouts to be used with views. This models the - common header/footer method of wrapping views. In your views, define a layout - using the layout :default and create a file named default.html.erb. - Inside default.html.erb, call <% yield %> to render the view using this - layout. - -app/helpers - Holds view helpers that should be named like weblogs_helper.rb. These are - generated for you automatically when using generators for controllers. - Helpers can be used to wrap functionality for your views into methods. - -config - Configuration files for the Rails environment, the routing map, the database, - and other dependencies. - -db - Contains the database schema in schema.rb. db/migrate contains all the - sequence of Migrations for your schema. - -doc - This directory is where your application documentation will be stored when - generated using rake doc:app - -lib - Application specific libraries. Basically, any kind of custom code that - doesn't belong under controllers, models, or helpers. This directory is in - the load path. - -public - The directory available for the web server. Also contains the dispatchers and the - default HTML files. This should be set as the DOCUMENT_ROOT of your web - server. - -script - Helper scripts for automation and generation. - -test - Unit and functional tests along with fixtures. When using the rails generate - command, template test files will be generated for you and placed in this - directory. - -vendor - External libraries that the application depends on. Also includes the plugins - subdirectory. If the app has frozen rails, those gems also go here, under - vendor/rails/. This directory is in the load path. diff --git a/app/assets/javascripts/password_resets.js.coffee b/app/assets/javascripts/password_resets.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/password_resets.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/password_resets.css.scss b/app/assets/stylesheets/password_resets.css.scss new file mode 100644 index 0000000..8160ad8 --- /dev/null +++ b/app/assets/stylesheets/password_resets.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the password_resets controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 5926b40..d7efbdb 100755 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -1,6 +1,6 @@ class AdminController < ApplicationController - # before_filter :administrative + before_filter :administrative, :if => :admin_param skip_before_filter :has_info def dashboard @@ -44,5 +44,11 @@ class AdminController < ApplicationController format.json { render :json => { :msg => message ? "success" : "failure"} } end end + + private + + def admin_param + params[:admin_id] != '1' + end end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb new file mode 100644 index 0000000..6866774 --- /dev/null +++ b/app/controllers/api/v1/users_controller.rb @@ -0,0 +1,57 @@ +class Api::V1::UsersController < ApplicationController + + skip_before_filter :authenticated + before_filter :valid_api_token + before_filter :extrapolate_user + + respond_to :json + + def index + # We removed the .as_json code from the model, just seemed like extra work. + # dunno, maybe useful at a later time? + #respond_with @user.admin ? User.all.as_json : @user.as_json + + respond_with @user.admin ? User.all : @user + end + + def show + respond_with @user.as_json + end + +private + + def valid_api_token + authenticate_or_request_with_http_token do |token, options| + # TODO :add some functionality to check if the HTTP Header is valid + identify_user(token) + end + end + + def identify_user(token="") + # We've had issues with URL encoding, etc. causing issues so just to be safe + # we will go ahead and unescape the user's token + unescape_token(token) + @clean_token =~ /(.*?)-(.*)/ + id = $1 + hash = $2 + (id && hash) ? true : false + check_hash(id, hash) ? true : false + end + + def check_hash(id, hash) + digest = OpenSSL::Digest::SHA1.hexdigest("#{ACCESS_TOKEN_SALT}:#{id}") + hash == digest + end + + # We had some issues with the token and url encoding... + # this is an attempt to normalize the data. + def unescape_token(token="") + @clean_token = CGI::unescape(token) + end + + # Added a method to make it easy to figure out who the user is. + def extrapolate_user + @user = User.find_by_id(@clean_token.split("-").first) + end + +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a0ef5cf..56ad260 100755 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,36 +2,39 @@ class ApplicationController < ActionController::Base before_filter :authenticated, :has_info helper_method :current_user, :is_admin? - + # Our security guy keep talking about sea-surfing, cool story bro. # protect_from_forgery - + private def current_user - @current_user ||= User.find_by_user_id(session[:user_id].to_s) + @current_user ||= ( + User.find_by_auth_token(cookies[:auth_token].to_s) || + User.find_by_user_id(session[:user_id].to_s) + ) end - + def authenticated path = request.fullpath.present? ? root_url(:url => request.fullpath) : root_url redirect_to path and reset_session if not current_user end def is_admin? - current_user.admin if current_user + current_user.admin if current_user end def administrative if not is_admin? - reset_session + #reset_session redirect_to root_url end end - + def has_info redirect = false if current_user - begin + begin if !(current_user.retirement || current_user.paid_time_off.schedule || current_user.paid_time_off || current_user.work_info || current_user.performance) redirect = true end @@ -41,5 +44,5 @@ class ApplicationController < ActionController::Base end redirect_to home_dashboard_index_path if redirect end - + end diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb new file mode 100644 index 0000000..533643a --- /dev/null +++ b/app/controllers/password_resets_controller.rb @@ -0,0 +1,63 @@ +class PasswordResetsController < ApplicationController + skip_before_filter :authenticated + + + def reset_password + user = Marshal.load(Base64.decode64(params[:user])) unless params[:user].nil? + + if user && params[:password] && params[:confirm_password] && params[:password] == params[:confirm_password] + user.password = params[:password] + user.save! + flash[:success] = "Your password has been reset please login" + redirect_to :login + else + flash[:error] = "Error resetting your password. Please try again." + redirect_to :login + end + end + + def confirm_token + if !params[:token].nil? && is_valid?(params[:token]) + flash[:success] = "Password reset token confirmed! Please create a new password." + render :reset_password + else + flash[:error] = "Invalid password reset token. Please try again." + redirect_to :login + end + end + + def forgot_password + @user = User.find_by_email(params[:email]) unless params[:email].nil? + + if @user && password_reset_mailer(@user) + flash[:success] = "Password reset email sent to #{params[:email]}" + redirect_to :login + else + flash[:error] = "There was an issue sending password reset email to #{params[:email]}".html_safe unless params[:email].nil? + end + end + + private + + def password_reset_mailer(user) + token = generate_token(user.id, user.email) + UserMailer.forgot_password(user.email, token).deliver + end + + def generate_token(id, email) + hash = Digest::MD5.hexdigest(email) + "#{id}-#{hash}" + end + + def is_valid?(token) + if token =~ /(?\d+)-(?[A-Z0-9]{32})/i + + # Fetch the user by their id, and hash their email address + @user = User.find_by_id($~[:user_id]) + email = Digest::MD5.hexdigest(@user.email) + + # Compare and validate our hashes + return true if email == $~[:email_hash] + end + end +end diff --git a/app/controllers/pay_controller.rb b/app/controllers/pay_controller.rb new file mode 100644 index 0000000..6a71dc3 --- /dev/null +++ b/app/controllers/pay_controller.rb @@ -0,0 +1,43 @@ +class PayController < ApplicationController + + def index + end + + def update_dd_info + msg = false + pay = Pay.new( + :bank_account_num => params[:bank_account_num], + :bank_routing_num => params[:bank_routing_num], + :percent_of_deposit => params[:dd_percent] + ) + pay.user_id = current_user.user_id + msg = true if pay.save! + respond_to do |format| + format.json {render :json => {:msg => msg } } + end + end + + def show + respond_to do |format| + format.json { render :json => {:user => current_user.pay.as_json} } + end + end + + def destroy + pay = Pay.find_by_id(params[:id]) + if pay.present? and pay.destroy + flash[:success] = "Successfully Deleted Entry" + else + flash[:error] = "Unable to process that request at this time" + end + redirect_to user_pay_index_path + end + + def decrypted_bank_acct_num + decrypted = Encryption.decrypt_sensitive_value(params[:value_to_decrypt]) + respond_to do |format| + format.json {render :json => {:account_num => decrypted || "No Data" }} + end + end + +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 3f84173..a13bbc7 100755 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -8,7 +8,6 @@ class SessionsController < ApplicationController redirect_to home_dashboard_index_path if current_user end - def create path = params[:url].present? ? params[:url] : home_dashboard_index_path begin @@ -19,7 +18,11 @@ class SessionsController < ApplicationController end if user - session[:user_id] = user.user_id if User.where(:user_id => user.user_id).exists? + if params[:remember_me] + cookies.permanent[:auth_token] = user.auth_token if User.where(:user_id => user.user_id).exists? + else + session[:user_id] = user.user_id if User.where(:user_id => user.user_id).exists? + end redirect_to path else # Removed this code, just doesn't seem specific enough! @@ -30,6 +33,7 @@ class SessionsController < ApplicationController end def destroy + cookies.delete(:auth_token) reset_session redirect_to root_path end diff --git a/app/controllers/tutorials_controller.rb b/app/controllers/tutorials_controller.rb index d27a0ca..69df74f 100755 --- a/app/controllers/tutorials_controller.rb +++ b/app/controllers/tutorials_controller.rb @@ -15,7 +15,6 @@ class TutorialsController < ApplicationController end def injection - end def xss @@ -62,6 +61,12 @@ class TutorialsController < ApplicationController def misconfig end + + def insecure_components + end + + def access_control + end def crypto end @@ -78,55 +83,16 @@ class TutorialsController < ApplicationController def guard end - def info_disclosure - @bad_code_1 = - %q{ - - - - - - - - - - - - - - - - - - - - - - - -
Full NameIncomeBonusesYears w/ MetaCorpSSNDoB
<%= "#{@user.first_name} #{@user.last_name}" %><%= @user.work_info.income %><%= @user.work_info.bonuses %><%= @user.work_info.years_worked %><%= @user.work_info.SSN %><%= @user.work_info.DoB %>
- } - - @good_code_1 = %q{ - class WorkInfo < ActiveRecord::Base - attr_accessible :DoB, :SSN, :bonuses, :income, :years_worked - belongs_to :user - - # We should probably use this - def last_four - "***-**-" << self.SSN[-4,4] - end - - end - } - - @bad_code_2 = %q{<%= @user.work_info.SSN %>} - @good_code_2 = %q{<%= @user.work_info.last_four %>} + def logic_flaws end def mass_assignment end + def guantlt + + end + def constantize end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e7f1684..9a48c27 100755 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -3,6 +3,7 @@ class UsersController < ApplicationController skip_before_filter :has_info skip_before_filter :authenticated, :only => [:new, :create] + def new @user = User.new end @@ -16,7 +17,7 @@ class UsersController < ApplicationController else @user = user flash[:error] = user.errors.full_messages.to_sentence - redirect_to :sign_up + redirect_to :signup end end @@ -52,4 +53,4 @@ class UsersController < ApplicationController end end -end \ No newline at end of file +end diff --git a/app/helpers/api/v1/users_helper.rb b/app/helpers/api/v1/users_helper.rb new file mode 100644 index 0000000..4d5288c --- /dev/null +++ b/app/helpers/api/v1/users_helper.rb @@ -0,0 +1,2 @@ +module Api::V1::UsersHelper +end diff --git a/app/helpers/password_resets_helper.rb b/app/helpers/password_resets_helper.rb new file mode 100644 index 0000000..0c9d96e --- /dev/null +++ b/app/helpers/password_resets_helper.rb @@ -0,0 +1,2 @@ +module PasswordResetsHelper +end diff --git a/app/helpers/pay_helper.rb b/app/helpers/pay_helper.rb new file mode 100644 index 0000000..0af6719 --- /dev/null +++ b/app/helpers/pay_helper.rb @@ -0,0 +1,2 @@ +module PayHelper +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 0000000..209b839 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,10 @@ +class UserMailer < ActionMailer::Base + default from: "noreply@railsgoat.dev" + + def forgot_password(email, token) + @token = token + @url = url_for(controller: "password_resets", action: "reset_password", only_path: false) + "?token=#{token}" + + mail(to: "#{email}", subject: "Reset your MetaCorp password") + end +end diff --git a/app/models/key_management.rb b/app/models/key_management.rb new file mode 100644 index 0000000..174b80c --- /dev/null +++ b/app/models/key_management.rb @@ -0,0 +1,6 @@ +class KeyManagement < ActiveRecord::Base + attr_accessible :iv, :user_id + belongs_to :work_info + belongs_to :user + +end diff --git a/app/models/pay.rb b/app/models/pay.rb new file mode 100644 index 0000000..78f0278 --- /dev/null +++ b/app/models/pay.rb @@ -0,0 +1,25 @@ +class Pay < ActiveRecord::Base + + # mass-assignable attributes + attr_accessible :bank_account_num, :bank_routing_num, :percent_of_deposit + + # Associations + belongs_to :user + + # Validations + validates :bank_account_num, presence: true + validates :bank_routing_num, presence: true + validates :percent_of_deposit, presence: true + + # callbacks + before_save :encrypt_bank_account_num + + def as_json + super(only: [:bank_account_num, :bank_routing_num, :percent_of_deposit, :id]) + end + + def encrypt_bank_account_num + self.bank_account_num = Encryption.encrypt_sensitive_value(self.bank_account_num) + end + +end diff --git a/app/models/user.rb b/app/models/user.rb index 58e93b2..261703e 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,11 +1,19 @@ +require 'encryption' + class User < ActiveRecord::Base + attr_accessible :email, :admin, :first_name, :last_name, :user_id, :password, :password_confirmation validates :password, :presence => true, :confirmation => true, :length => {:within => 6..40}, :on => :create, - :if => :password#, - #:format => {:with => /\A.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\@\#\$\%\^\&\+\=]).*\z/} + :if => :password +=begin + validates :password, :presence => true, + :confirmation => true, + :if => :password, + :format => {:with => /\A.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\@\#\$\%\^\&\+\=]).*\z/} +=end validates_presence_of :email validates_uniqueness_of :email validates_format_of :email, :with => /.+@.+\..+/i @@ -18,36 +26,55 @@ class User < ActiveRecord::Base has_one :work_info, :foreign_key => :user_id, :primary_key => :user_id, :dependent => :destroy has_many :performance, :foreign_key => :user_id, :primary_key => :user_id, :dependent => :destroy has_many :messages, :foreign_key => :receiver_id, :primary_key => :user_id, :dependent => :destroy - + has_many :pay, :foreign_key => :user_id, :primary_key => :user_id, :dependent => :destroy + before_create { generate_token(:auth_token) } def build_benefits_data build_retirement(POPULATE_RETIREMENTS.shuffle.first) build_paid_time_off(POPULATE_PAID_TIME_OFF.shuffle.first).schedule.build(POPULATE_SCHEDULE.shuffle.first) build_work_info(POPULATE_WORK_INFO.shuffle.first) + # Uncomment below line to use encrypted SSN(s) + #work_info.build_key_management(:iv => SecureRandom.hex(32)) performance.build(POPULATE_PERFORMANCE.shuffle.first) end def full_name "#{self.first_name} #{self.last_name}" end + +=begin + # Instead of the entire user object being returned, we can use this to filter. + def as_json + super(only: [:user_id, :email, :first_name, :last_name]) + end +=end private def self.authenticate(email, password) auth = nil user = find_by_email(email) - if user + raise "#{email} doesn't exist!" if !(user) if user.password == Digest::MD5.hexdigest(password) auth = user else raise "Incorrect Password!" end - else - raise "#{email} doesn't exist!" - end return auth end +=begin + # More secure version, still lacking a decent hashing routine, this is for timing attack prevention + def self.authenticate(email, password) + user = find_by_email(email) || User.new(:password => "") + if Rack::Utils.secure_compare(user.password, Digest::MD5.hexdigest(password)) + return user + else + raise "Incorrect username or password" + end + end +=end + def assign_user_id unless @skip_user_id_assign.present? || self.user_id.present? user = User.order("user_id").last @@ -63,5 +90,11 @@ private end end end + + def generate_token(column) + begin + self[column] = Encryption.encrypt_sensitive_value(self.user_id) + end while User.exists?(column => self[column]) + end end diff --git a/app/models/work_info.rb b/app/models/work_info.rb index c3b70b6..c8e30d8 100644 --- a/app/models/work_info.rb +++ b/app/models/work_info.rb @@ -1,17 +1,44 @@ class WorkInfo < ActiveRecord::Base attr_accessible :DoB, :SSN, :bonuses, :income, :years_worked belongs_to :user + has_one :key_management, :foreign_key => :user_id, :primary_key => :user_id, :dependent => :destroy #before_save :encrypt_ssn + # We should probably use this def last_four - "***-**-" << self.SSN[-4,4] + "***-**-" << self.decrypt_ssn[-4,4] end def encrypt_ssn + aes = OpenSSL::Cipher::Cipher.new(cipher_type) + aes.encrypt + aes.key = key + aes.iv = iv if iv != nil + self.encrypted_ssn = aes.update(self.SSN) + aes.final + self.SSN = nil end def decrypt_ssn + aes = OpenSSL::Cipher::Cipher.new(cipher_type) + aes.decrypt + aes.key = key + aes.iv = iv if iv != nil + aes.update(self.encrypted_ssn) + aes.final + end + + def key + raise "Key Missing" if !(KEY) + KEY + end + + def iv + raise "No IV for this User" if !(self.key_management.iv) + self.key_management.iv + end + + def cipher_type + 'aes-256-cbc' end end diff --git a/app/views/admin/dashboard.html.erb b/app/views/admin/dashboard.html.erb index 3e1466c..da2c845 100755 --- a/app/views/admin/dashboard.html.erb +++ b/app/views/admin/dashboard.html.erb @@ -59,7 +59,7 @@ function makeActive(){ }; function loadTable(){ - $("#userDataTable").load("/admin/"+ <%=current_user.user_id %> + "/get_all_users") + $("#userDataTable").load("/admin/"+ <%= params[:admin_id] %> + "/get_all_users") }; $(document).ready( diff --git a/app/views/layouts/admin/_get_user.html.erb b/app/views/layouts/admin/_get_user.html.erb index eda97d7..9557b7d 100755 --- a/app/views/layouts/admin/_get_user.html.erb +++ b/app/views/layouts/admin/_get_user.html.erb @@ -83,7 +83,7 @@ $('#delete_button').click(function() { $("#editAcct").modal('hide'); $.ajax({ - url: "/admin/" + <%= @user.user_id %> + "/delete_user.json", + url: "/admin/" + <%= params[:admin_id] %> + "/delete_user.json", type: "POST", success: function(response) { $('#success').show(500).delay(1500).fadeOut(); diff --git a/app/views/layouts/shared/_sidebar.html.erb b/app/views/layouts/shared/_sidebar.html.erb index 1add2e3..7114b08 100755 --- a/app/views/layouts/shared/_sidebar.html.erb +++ b/app/views/layouts/shared/_sidebar.html.erb @@ -65,6 +65,14 @@ Messages <% end %> + +
  • + <%= link_to user_pay_index_path(:user_id => current_user.user_id) do %> +
    + +
    + Pay + <% end %>
  • diff --git a/app/views/layouts/tutorial/_sidebar.html.erb b/app/views/layouts/tutorial/_sidebar.html.erb index fde5442..644b772 100755 --- a/app/views/layouts/tutorial/_sidebar.html.erb +++ b/app/views/layouts/tutorial/_sidebar.html.erb @@ -15,23 +15,24 @@ A1 Injection <% end %> + +
  • + <%= link_to broken_auth_tutorials_path do %> +
    + +
    + A2 Broken Auth + <% end %>
  • <%= link_to xss_tutorials_path do %>
    - A2 XSS - <% end %> -
  • -
  • - <%= link_to broken_auth_tutorials_path do %> -
    - -
    - A3 Broken Auth + A3 XSS <% end %>
  • +
  • <%= link_to insecure_dor_tutorials_path do %>
    @@ -40,44 +41,44 @@ A4 Insecure DOR <% end %>
  • -
  • - <%= link_to csrf_tutorials_path do %> -
    - -
    - A5 CSRF - <% end %> -
  • -
  • +
  • <%= link_to misconfig_tutorials_path do %>
    - A6 Misconfig + A5 Misconfig <% end %>
  • -
  • - <%= link_to crypto_tutorials_path do %> +
  • + <%= link_to exposure_tutorials_path do %>
    - A7 Crypto + A6 Exposure <% end %>
  • -
  • - <%= link_to url_access_tutorials_path do %> +
  • + <%= link_to access_control_tutorials_path do %>
    - A8 URL Access + A7 Access Control <% end %>
  • -
  • - <%= link_to ssl_tls_tutorials_path do %> +
  • + <%= link_to csrf_tutorials_path do %>
    - A9 SSL/TLS + A8 CSRF + <% end %> +
  • +
  • + <%= link_to insecure_components_tutorials_path do %> +
    + +
    + A9 Components <% end %>
  • @@ -96,21 +97,24 @@ Extras
      +
    • + <%= link_to "gauntlt", gauntlt_tutorials_path %> +
    • <%= link_to "Guard", guard_tutorials_path %>
    • -
    • - <%= link_to "Info Dislosure", info_disclosure_tutorials_path %> -
    • <%= link_to "Mass Assignment", mass_assignment_tutorials_path %>
    • <%= link_to "Constantize", constantize_tutorials_path %>
    • +
    • + <%= link_to "Logic Flaws", logic_flaws_tutorials_path %> +
    • + + + + + + + + + diff --git a/app/views/pay/index.html.erb b/app/views/pay/index.html.erb new file mode 100644 index 0000000..3895d4b --- /dev/null +++ b/app/views/pay/index.html.erb @@ -0,0 +1,301 @@ +
      +
      +
      +
      + +
      +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      + Direct Deposit +
      +
      +
      +
      + <%= form_tag "#", {:class => "form-horizontal", :id => "bank_info_form" } do %> + + +
      + <%= text_field_tag :bank_account_num, params[:bank_account_num], {:placeholder => "Bank Account Number"} %> + # +
      + +
      + <%= text_field_tag :bank_routing_num, params[:bank_routing_num], {:placeholder => "Bank Routing Number"} %> + # +
      + + +
      + <%= text_field_tag :dd_percent, params[:dd_percent], {:placeholder => "Percentage of Deposit"} %> + % +
      + + + <%= submit_tag "Submit", {:id => "dd_form_btn", :style => "margin-left: 10px;", :class => "btn btn-medium btn-primary"} %> + <% end %> +
      +
      +
      +
      +
      + + + + +
      +
      +
      + + +
      +
      + Accounts +
      +
      + +
      +
      + + + + + + + + + + + + +
      + Encrypted Bank Account Number + <%=link_to "#", { :style => "color:#AA6F93", :id => "encrypted_acct_question"} do %> + + + + <% end %> + + Bank Routing Number + + Percentage of Deposit + + Action +
      +
      +
      +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      + Decrypt Bank Account Number +
      +
      +
      +
      + <%= form_tag "#", {:class => "form-horizontal", :id => "decrypt_form" } do %> + + +
      + <%= text_field_tag :value_to_decrypt, params[:value_to_decrypt], {:placeholder => "Bank Account Number"} %> + # +
      + + + <%= submit_tag "Submit", {:id => "decrypt_btn", :style => "margin-left: 10px;", :class => "btn btn-medium btn-primary"} %> + <% end %> +
      +
      +
      +
      +
      + +
      +
      + +<%= javascript_include_tag "jquery.dataTables.js" %> + + \ No newline at end of file diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb index 481763a..dbeea1f 100755 --- a/app/views/sessions/new.html.erb +++ b/app/views/sessions/new.html.erb @@ -1,33 +1,41 @@
      -

      MetaCorp

      -

      A GoatGroup Company

      +

      MetaCorp

      +

      A GoatGroup Company

      -
      -
      - \ No newline at end of file +
      +
      \ No newline at end of file diff --git a/app/views/tutorials/info_disclosure.html.erb b/app/views/tutorials/access_control.html.erb similarity index 61% rename from app/views/tutorials/info_disclosure.html.erb rename to app/views/tutorials/access_control.html.erb index b482a01..6796302 100644 --- a/app/views/tutorials/info_disclosure.html.erb +++ b/app/views/tutorials/access_control.html.erb @@ -2,7 +2,7 @@
      - <%= render :partial => "layouts/tutorial/info_disclosure/ssn_disclosure"%> + <%= render :partial => "layouts/tutorial/access_control/access_control_first" %>
      @@ -10,8 +10,7 @@ \ No newline at end of file diff --git a/app/views/tutorials/insecure_components.html.erb b/app/views/tutorials/insecure_components.html.erb new file mode 100644 index 0000000..271f7a9 --- /dev/null +++ b/app/views/tutorials/insecure_components.html.erb @@ -0,0 +1,17 @@ +
      +
      +
      +
      + <%= render :partial => "layouts/tutorial/insecure_components/insecure_components_first" %> +
      +
      +
      +
      + + \ No newline at end of file diff --git a/app/views/tutorials/logic_flaws.html.erb b/app/views/tutorials/logic_flaws.html.erb new file mode 100644 index 0000000..ed83c4f --- /dev/null +++ b/app/views/tutorials/logic_flaws.html.erb @@ -0,0 +1,24 @@ +
      +
      +
      +
      + <%= render :partial => ("layouts/tutorial/logic_flaws/broken_regexp")%> +
      +
      +
      +
      + <%= render :partial => ("layouts/tutorial/logic_flaws/insecure_crypto_reuse")%> +
      +
      +
      +
      + + + \ No newline at end of file diff --git a/app/views/tutorials/misconfig.html.erb b/app/views/tutorials/misconfig.html.erb index da9c0fc..e7cf527 100755 --- a/app/views/tutorials/misconfig.html.erb +++ b/app/views/tutorials/misconfig.html.erb @@ -5,6 +5,11 @@ <%= render :partial => "layouts/tutorial/misconfig/misconfig_first"%>
      +
      +
      + <%= render :partial => "layouts/tutorial/misconfig/misconfig_second"%> +
      +
      diff --git a/app/views/user_mailer/forgot_password.html.erb b/app/views/user_mailer/forgot_password.html.erb new file mode 100644 index 0000000..ca2fe76 --- /dev/null +++ b/app/views/user_mailer/forgot_password.html.erb @@ -0,0 +1,23 @@ + + + + + + +

      Need help logging in?

      +

      + A password reset was requested for your user account.
      +
      + + To reset your MetaCorp password, simply click on the + following link and follow the instructions:
      +
      + + <%= link_to "Click here to reset your password", @url %>
      +
      + + If you don't want to change your password, you can ignore this email. +

      +

      Thanks, and have a great day!

      + + \ No newline at end of file diff --git a/app/views/user_mailer/forgot_password.text.erb b/app/views/user_mailer/forgot_password.text.erb new file mode 100644 index 0000000..92067db --- /dev/null +++ b/app/views/user_mailer/forgot_password.text.erb @@ -0,0 +1,13 @@ +Need help logging in? +========================================================== + +A password reset was requested for your user account. + +To reset your MetaCorp password, simply copy the +following link and follow the instructions: + +<%= @url %> + +If you don't want to change your password, you can ignore this email. + +Thanks, and have a great day! \ No newline at end of file diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 27f3738..cf03ae2 100755 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -13,22 +13,17 @@
      - <%= f.label "Email Address" %> - <%= f.text_field :email, {:class => "input input-block-level"} %> + <%= f.text_field :email, {:class => "input input-block-level", :placeholder => "Email"} %> - <%= f.label "First Name" %> - <%= f.text_field :first_name, {:class => "input input-block-level"} %> + <%= f.text_field :first_name, {:class => "input input-block-level", :placeholder => "First Name"} %> - <%= f.label "Last Name" %> - <%= f.text_field :last_name, {:class => "input input-block-level"} %> + <%= f.text_field :last_name, {:class => "input input-block-level", :placeholder => "Last Name"} %>
      - <%= f.label :password, nil %> - <%= f.password_field :password, {:class => "input input-block-level"}%> + <%= f.password_field :password, {:class => "input input-block-level", :placeholder => "Password"}%>
      - <%= f.label :confirm_password %> - <%= f.password_field :password_confirmation, {:class => "input input-block-level"}%> + <%= f.password_field :password_confirmation, {:class => "input input-block-level", :placeholder => "Confirm Password"}%>
      diff --git a/app/views/work_info/index.html.erb b/app/views/work_info/index.html.erb index 1b429b5..96fb928 100644 --- a/app/views/work_info/index.html.erb +++ b/app/views/work_info/index.html.erb @@ -28,6 +28,9 @@ <%= @user.work_info.bonuses %> <%= @user.work_info.years_worked %> <%= @user.work_info.SSN %> + + + <%= @user.work_info.DoB %> diff --git a/config/application.rb b/config/application.rb index 4bac9da..1597890 100755 --- a/config/application.rb +++ b/config/application.rb @@ -40,7 +40,7 @@ module Railsgoat config.filter_parameters += [:password] # Enable escaping HTML in JSON. - config.active_support.escape_html_entities_in_json = true + #config.active_support.escape_html_entities_in_json = false # Use SQL instead of Active Record's schema dumper when creating the database. # This is necessary if your schema can't be completely dumped by the schema dumper, @@ -51,7 +51,7 @@ module Railsgoat # This will create an empty whitelist of attributes available for mass-assignment for all models # in your app. As such, your models will need to explicitly whitelist or blacklist accessible # parameters by using an attr_accessible or attr_protected declaration. - config.active_record.whitelist_attributes = true + config.active_record.whitelist_attributes = false # Enable the asset pipeline config.assets.enabled = true @@ -61,5 +61,7 @@ module Railsgoat # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' + + I18n.config.enforce_available_locales = false end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 9db258d..9ff11cf 100755 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -28,13 +28,21 @@ Railsgoat::Application.configure do # Log the query plan for queries taking more than this (works # with SQLite, MySQL, and PostgreSQL) config.active_record.auto_explain_threshold_in_seconds = 0.5 + + # Tired of caching causing issues + config.middleware.delete Rack::ETag # Do not compress assets config.assets.compress = false # Expands the lines which load the assets config.assets.debug = true - + + # ActionMailer settings for email support + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 } + config.action_mailer.default_url_options = { :host => "localhost:3000" } + config.middleware.insert_before( Rack::Lock, Rack::LiveReload, :min_delay => 500, diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb new file mode 100644 index 0000000..086522f --- /dev/null +++ b/config/initializers/constants.rb @@ -0,0 +1,3 @@ +ACCESS_TOKEN_SALT = "S4828341189aefiasd#ASDF" + +RG_IV = "PPKLKAJDKGHALDJL482823458028" \ No newline at end of file diff --git a/config/initializers/html_entities.rb b/config/initializers/html_entities.rb new file mode 100644 index 0000000..4db1c30 --- /dev/null +++ b/config/initializers/html_entities.rb @@ -0,0 +1 @@ +ActiveSupport::JSON::Encoding::escape_html_entities_in_json = false diff --git a/config/initializers/key.rb b/config/initializers/key.rb new file mode 100644 index 0000000..89022ee --- /dev/null +++ b/config/initializers/key.rb @@ -0,0 +1,5 @@ +if Rails.env.production? + # Specify env variable/location/etc. to retrieve key from +else + KEY = "123456789101112123456789101112123456789101112" +end diff --git a/config/routes.rb b/config/routes.rb index 5770161..9386fd0 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,83 +1,102 @@ Railsgoat::Application.routes.draw do -get "login" => "sessions#new" -get "signup" => "users#new" -get "logout" => "sessions#destroy" + get "login" => "sessions#new" + get "signup" => "users#new" + get "logout" => "sessions#destroy" + match "forgot_password" => "password_resets#forgot_password" + get "password_resets" => "password_resets#confirm_token" + post "password_resets" => "password_resets#reset_password" -resources :sessions do -end + resources :sessions do + end -resources :users do - get "account_settings" - - resources :retirement do - end - - resources :paid_time_off do - end - - resources :work_info do - end - - resources :performance do - - end - - resources :benefit_forms do + resources :users do + get "account_settings" + + resources :retirement do + end + + resources :paid_time_off do + end + + resources :work_info do + end + + resources :performance do + + end + + resources :benefit_forms do + + end + + resources :messages do + end + resources :pay do + collection do + post "update_dd_info" + post "decrypted_bank_acct_num" + end + end + end - resources :messages do + get "download" => "benefit_forms#download" + post "upload" => "benefit_forms#upload" + + resources :tutorials do + collection do + get "credentials" + get "injection" + get "xss" + get "broken_auth" + get "insecure_dor" + get "csrf" + get "misconfig" + get "exposure" + get "url_access" + get "insecure_components" + get "access_control" + get "ssl_tls" + get "redirects" + get "guard" + get "mass_assignment" + get "constantize" + get "gauntlt" + get "logic_flaws" + end + end + + resources :schedule do + collection do + get "get_pto_schedule" + end + + end + + resources :admin do + get "dashboard" + get "get_user" + post "delete_user" + put "update_user" + get "get_all_users" + end + + resources :dashboard do + collection do + get "home" + end end -end - -get "download" => "benefit_forms#download" -post "upload" => "benefit_forms#upload" - -resources :tutorials do - collection do - get "credentials" - get "injection" - get "xss" - get "broken_auth" - get "insecure_dor" - get "csrf" - get "misconfig" - get "crypto" - get "url_access" - get "ssl_tls" - get "redirects" - get "guard" - get "info_disclosure" - get "mass_assignment" - get "constantize" - end -end - -resources :schedule do - collection do - get "get_pto_schedule" - end - -end - -resources :admin do - get "dashboard" - get "get_user" - post "delete_user" - put "update_user" - get "get_all_users" -end - -resources :dashboard do - collection do - get "home" - end -end + namespace :api, defaults: {format: 'json'} do + namespace :v1 do + resources :users + end + end -root :to => "sessions#new" + root :to => "sessions#new" end diff --git a/db/migrate/20131112235256_add_encrypted_ssn_to_work_infos.rb b/db/migrate/20131112235256_add_encrypted_ssn_to_work_infos.rb new file mode 100644 index 0000000..2c7935a --- /dev/null +++ b/db/migrate/20131112235256_add_encrypted_ssn_to_work_infos.rb @@ -0,0 +1,5 @@ +class AddEncryptedSsnToWorkInfos < ActiveRecord::Migration + def change + add_column :work_infos, :encrypted_ssn, :binary + end +end diff --git a/db/migrate/20131113200708_create_key_managements.rb b/db/migrate/20131113200708_create_key_managements.rb new file mode 100644 index 0000000..96ce247 --- /dev/null +++ b/db/migrate/20131113200708_create_key_managements.rb @@ -0,0 +1,10 @@ +class CreateKeyManagements < ActiveRecord::Migration + def change + create_table :key_managements do |t| + t.string :iv + t.integer :user_id + + t.timestamps + end + end +end diff --git a/db/migrate/20140312002642_add_auth_token_to_users.rb b/db/migrate/20140312002642_add_auth_token_to_users.rb new file mode 100644 index 0000000..2c83ac1 --- /dev/null +++ b/db/migrate/20140312002642_add_auth_token_to_users.rb @@ -0,0 +1,5 @@ +class AddAuthTokenToUsers < ActiveRecord::Migration + def change + add_column :users, :auth_token, :string + end +end diff --git a/db/migrate/20140315002730_create_pays.rb b/db/migrate/20140315002730_create_pays.rb new file mode 100644 index 0000000..78a9b37 --- /dev/null +++ b/db/migrate/20140315002730_create_pays.rb @@ -0,0 +1,12 @@ +class CreatePays < ActiveRecord::Migration + def change + create_table :pays do |t| + t.integer :user_id + t.string :bank_account_num + t.string :bank_routing_num + t.integer :percent_of_deposit + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 2adcc14..a32189b 100755 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,13 +11,20 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20131011180207) do +ActiveRecord::Schema.define(:version => 20140315002730) do create_table "benefits", :force => true do |t| t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end + create_table "key_managements", :force => true do |t| + t.string "iv" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "messages", :force => true do |t| t.integer "creator_id" t.integer "receiver_id" @@ -37,6 +44,15 @@ ActiveRecord::Schema.define(:version => 20131011180207) do t.datetime "updated_at", :null => false end + create_table "pays", :force => true do |t| + t.integer "user_id" + t.string "bank_account_num" + t.string "bank_routing_num" + t.integer "percent_of_deposit" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "performances", :force => true do |t| t.integer "user_id" t.date "date_submitted" @@ -76,6 +92,7 @@ ActiveRecord::Schema.define(:version => 20131011180207) do t.integer "user_id" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false + t.string "auth_token" end create_table "work_infos", :force => true do |t| @@ -85,8 +102,9 @@ ActiveRecord::Schema.define(:version => 20131011180207) do t.integer "years_worked" t.string "SSN" t.date "DoB" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.binary "encrypted_ssn" end end diff --git a/db/seeds.rb b/db/seeds.rb index 3533d20..9750f25 100755 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -33,8 +33,8 @@ users = [ { :email => "mike@metacorp.com", :admin => false, - :password => "motorcross1445", - :password_confirmation => "motorcross1445", + :password => "motocross1445", + :password_confirmation => "motocross1445", :first_name => "Mike", :last_name => "McCabe", :user_id =>4 @@ -289,12 +289,6 @@ schedule.each do |event| sched.save end -work_info.each do |wi| - info = WorkInfo.new(wi.reject {|k| k == :user_id}) - info.user_id = wi[:user_id] - info.save -end - performance.each do |perf| p = Performance.new(perf.reject {|k| k == :user_id}) p.user_id = perf[:user_id] @@ -306,3 +300,21 @@ messages.each do |message| m.creator_id = message[:creator_id] m.save end + +work_info.each do |wi| + info = WorkInfo.new(wi.reject {|k| k == :user_id } ) + info.user_id = wi[:user_id] + info.save +end + + +=begin +work_info.each do |wi| + list = [:user_id, :SSN] + info = WorkInfo.new(wi.reject {|k| list.include?(k)}) + info.user_id = wi[:user_id] + info.build_key_management({:user_id => wi[:user_id], :iv => SecureRandom.hex(32) }) + info.SSN = wi[:SSN] + info.save +end +=end diff --git a/lib/encryption.rb b/lib/encryption.rb new file mode 100644 index 0000000..defa525 --- /dev/null +++ b/lib/encryption.rb @@ -0,0 +1,36 @@ +module Encryption + + # Added a re-usable encryption routine, shouldn't be an issue! + def self.encrypt_sensitive_value(val="") + aes = OpenSSL::Cipher::Cipher.new(cipher_type) + aes.encrypt + aes.key = key + aes.iv = iv if iv != nil + new_val = aes.update("#{val}") + aes.final + Base64.strict_encode64(new_val).encode('utf-8') + end + + def self.decrypt_sensitive_value(val="") + aes = OpenSSL::Cipher::Cipher.new(cipher_type) + aes.decrypt + aes.key = key + aes.iv = iv if iv != nil + decoded = Base64.strict_decode64("#{val}") + aes.update("#{decoded}") + aes.final + end + + # Should be able to just re-use the same key we already have! + def self.key + raise "Key Missing" if !(KEY) + KEY + end + + def self.iv + RG_IV + end + + def self.cipher_type + 'aes-256-cbc' + end + +end \ No newline at end of file diff --git a/spec/controllers/api/v1/users_controller_spec.rb b/spec/controllers/api/v1/users_controller_spec.rb new file mode 100644 index 0000000..9b5309e --- /dev/null +++ b/spec/controllers/api/v1/users_controller_spec.rb @@ -0,0 +1,6 @@ +=begin require 'spec_helper' + +describe Api::V1::UsersController do + +end +=end \ No newline at end of file diff --git a/spec/controllers/messages_controller_spec.rb b/spec/controllers/messages_controller_spec.rb index 503cc98..335cafc 100644 --- a/spec/controllers/messages_controller_spec.rb +++ b/spec/controllers/messages_controller_spec.rb @@ -1,5 +1 @@ -require 'spec_helper' - -describe MessagesController do - -end +require 'spec_helper' \ No newline at end of file diff --git a/spec/controllers/password_resets_controller_spec.rb b/spec/controllers/password_resets_controller_spec.rb new file mode 100644 index 0000000..335cafc --- /dev/null +++ b/spec/controllers/password_resets_controller_spec.rb @@ -0,0 +1 @@ +require 'spec_helper' \ No newline at end of file diff --git a/spec/controllers/pay_controller_spec.rb b/spec/controllers/pay_controller_spec.rb new file mode 100644 index 0000000..84b6475 --- /dev/null +++ b/spec/controllers/pay_controller_spec.rb @@ -0,0 +1,6 @@ +=begin require 'spec_helper' + +describe PayController do + +end +=end diff --git a/spec/helpers/api/v1/users_helper_spec.rb b/spec/helpers/api/v1/users_helper_spec.rb new file mode 100644 index 0000000..9619df0 --- /dev/null +++ b/spec/helpers/api/v1/users_helper_spec.rb @@ -0,0 +1,16 @@ +=begin require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the Api::V1::UsersHelper. For example: +# +# describe Api::V1::UsersHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +describe Api::V1::UsersHelper do + pending "add some examples to (or delete) #{__FILE__}" +end +=end \ No newline at end of file diff --git a/spec/helpers/messages_helper_spec.rb b/spec/helpers/messages_helper_spec.rb index a29b665..f8ec369 100644 --- a/spec/helpers/messages_helper_spec.rb +++ b/spec/helpers/messages_helper_spec.rb @@ -1,15 +1 @@ require 'spec_helper' - -# Specs in this file have access to a helper object that includes -# the MessagesHelper. For example: -# -# describe MessagesHelper do -# describe "string concat" do -# it "concats two strings with spaces" do -# expect(helper.concat_strings("this","that")).to eq("this that") -# end -# end -# end -describe MessagesHelper do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/helpers/password_resets_helper_spec.rb b/spec/helpers/password_resets_helper_spec.rb new file mode 100644 index 0000000..b87346e --- /dev/null +++ b/spec/helpers/password_resets_helper_spec.rb @@ -0,0 +1,16 @@ +=begin require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the PasswordResetsHelper. For example: +# +# describe PasswordResetsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +describe PasswordResetsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end +=end \ No newline at end of file diff --git a/spec/helpers/pay_helper_spec.rb b/spec/helpers/pay_helper_spec.rb new file mode 100644 index 0000000..408d779 --- /dev/null +++ b/spec/helpers/pay_helper_spec.rb @@ -0,0 +1,16 @@ +=begin require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the PayHelper. For example: +# +# describe PayHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +describe PayHelper do + pending "add some examples to (or delete) #{__FILE__}" +end +=end \ No newline at end of file diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb new file mode 100644 index 0000000..a79b75f --- /dev/null +++ b/spec/mailers/user_mailer_spec.rb @@ -0,0 +1 @@ +require "spec_helper" \ No newline at end of file diff --git a/spec/models/key_management_spec.rb b/spec/models/key_management_spec.rb new file mode 100644 index 0000000..335cafc --- /dev/null +++ b/spec/models/key_management_spec.rb @@ -0,0 +1 @@ +require 'spec_helper' \ No newline at end of file diff --git a/spec/models/message_spec.rb b/spec/models/message_spec.rb index a5f59dd..f8ec369 100644 --- a/spec/models/message_spec.rb +++ b/spec/models/message_spec.rb @@ -1,5 +1 @@ require 'spec_helper' - -describe Message do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/models/pay_spec.rb b/spec/models/pay_spec.rb new file mode 100644 index 0000000..1b4399c --- /dev/null +++ b/spec/models/pay_spec.rb @@ -0,0 +1,6 @@ +=begin require 'spec_helper' + +describe Pay do + pending "add some examples to (or delete) #{__FILE__}" +end +=end \ No newline at end of file diff --git a/spec/support/capybara_shared.rb b/spec/support/capybara_shared.rb index 1b323ba..e140dd4 100644 --- a/spec/support/capybara_shared.rb +++ b/spec/support/capybara_shared.rb @@ -13,22 +13,21 @@ def verifying_fixed? if !$displayed_spec_notice && result puts <<-NOTICE -****************************************************************************** - You are running the RailsGoat Capybara Specs in Training mode. These specs - are supposed to fail, indicating vulnerabilities exist. They contain - spoilers, so do not read the code in spec/vulnerabilities if your goal is to - learn more about patching the vulnerabilities. You should fix the - vulnerabilities in the application in order to get these specs to pass**. - You can use them to measure your progress. + ****************************************************************************** + You are running the RailsGoat Capybara Specs in Training mode. These specs + are supposed to fail, indicating vulnerabilities exist. They contain spoilers, + so do not read the code in spec/vulnerabilities if your goal is to learn more + about patching the vulnerabilities. You should fix the vulnerabilities in the + application in order to get these specs to pass**. You can use them to measure + your progress. - These same specs will pass if you set the #{maintainer_env_name} ENV - variable. + These same specs will pass if you set the #{maintainer_env_name} ENV variable. + + **NOTE: The RSpec pending feature is used to toggle the outcome of these specs + between Training mode and RailsGoat Maintainer mode. When the vulnerabilities + are removed, the specs will not "pass," but rather go into a "pending" state. + ****************************************************************************** - **NOTE: The RSpec pending feature is used to toggle the outcome of these - specs between Training mode and RailsGoat Maintainer mode, so when the - vulnerabilities are removed, these specs actually won't 'pass' but go into - a 'pending' state. -****************************************************************************** NOTICE $displayed_spec_notice = true end @@ -43,3 +42,41 @@ def login(user) end click_on 'Login' end + +##Hack to fix PhantomJS errors on Mavericks - https://gist.github.com/ericboehs/7125105 +module Capybara::Poltergeist + class Client + private + def redirect_stdout + prev = STDOUT.dup + prev.autoclose = false + $stdout = @write_io + STDOUT.reopen(@write_io) + + prev = STDERR.dup + prev.autoclose = false + $stderr = @write_io + STDERR.reopen(@write_io) + yield + ensure + STDOUT.reopen(prev) + $stdout = STDOUT + STDERR.reopen(prev) + $stderr = STDERR + end + end +end + +class WarningSuppressor + class << self + def write(message) + if message =~ /QFont::setPixelSize: Pixel size <= 0/ || message =~/CoreText performance note:/ || message =~/Method userSpaceScaleFactor in class NSView/ then 0 else puts(message);1;end + end + end +end + +Capybara.register_driver :poltergeist do |app| + Capybara::Poltergeist::Driver.new(app, phantomjs_logger: WarningSuppressor, timeout: 60) +end + +Capybara.javascript_driver = :poltergeist diff --git a/spec/views/password_resets/new.html.erb_spec.rb b/spec/views/password_resets/new.html.erb_spec.rb new file mode 100644 index 0000000..fcb6721 --- /dev/null +++ b/spec/views/password_resets/new.html.erb_spec.rb @@ -0,0 +1,6 @@ +=begin require 'spec_helper' + +describe "password_resets/new.html.erb" do + pending "add some examples to (or delete) #{__FILE__}" +end +=end \ No newline at end of file diff --git a/spec/vulnerabilities/info_disclosure_spec.rb b/spec/vulnerabilities/sensitive_data_exposure.rb similarity index 91% rename from spec/vulnerabilities/info_disclosure_spec.rb rename to spec/vulnerabilities/sensitive_data_exposure.rb index ce0bd2a..bc1e72e 100644 --- a/spec/vulnerabilities/info_disclosure_spec.rb +++ b/spec/vulnerabilities/sensitive_data_exposure.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'sensitive information disclosure' do +feature 'sensitive data exposure' do before do UserFixture.reset_all_users @normal_user = UserFixture.normal_user