diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..d3ecc46
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,19 @@
+# Ignore root files that are not needed in docker image
+.github
+.jenkins
+.terraform
+.gitignore
+docker-compose.yml
+Dockerfile
+LICENSE.md
+README.md
+
+# Ignore directories that are not needed in docker image
+docs/
+tmp/
+log/*
+public/data/*
+
+# Ignore the dockerenv .env file during docker builds so that credentials are
+# not accedentally built into container images.
+.env
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..5c67e5e
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,16 @@
+# Contrast Agent Authentication Keys
+# CONTRAST__API__URL=https://eval.contrastsecurity.com/Contrast
+# CONTRAST__API__API_KEY=XXXXXX
+# CONTRAST__API__SERVICE_KEY=XXXXXX
+# CONTRAST__API__USER_NAME=XXXXXX
+
+# Override the default application name and code set in config/contrast_security.yml
+# CONTRAST__APPLICATION__NAME=OWASP RailsGoat
+# CONTRAST__APPLICATION__CODE=demo-railsgoat
+
+# Override the default server name and environment set in config/contrast_security.yml
+# CONTRAST__SERVER__NAME=railsgoat-docker
+# CONTRAST__SERVER__ENVIRONMENT=development
+
+# See https://docs.contrastsecurity.com/user-vulnerableapps.html#session
+# CONTRAST__APPLICATION__SESSION_METADATA=""
diff --git a/.overcommit.yml b/.github/.overcommit.yml
similarity index 100%
rename from .overcommit.yml
rename to .github/.overcommit.yml
diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
similarity index 100%
rename from CODE_OF_CONDUCT.md
rename to .github/CODE_OF_CONDUCT.md
diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md
similarity index 100%
rename from CONTRIBUTING.md
rename to .github/CONTRIBUTING.md
diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
similarity index 100%
rename from ISSUE_TEMPLATE.md
rename to .github/ISSUE_TEMPLATE.md
diff --git a/.gitignore b/.gitignore
index e4d9e03..53f203e 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
/.bundle
-/bin
/db/*.sqlite3
/log/*.log
/tmp
@@ -14,4 +13,8 @@ coverage
/vendor/ruby
run.sh
test.sh
-contrast_security.yaml
+
+.env
+**/contrast_security.[yaml, yml]
+contrast_connection.json
+contrast.log
diff --git a/Jenkinsfile b/.jenkins/Jenkinsfile
similarity index 62%
rename from Jenkinsfile
rename to .jenkins/Jenkinsfile
index 49ddf69..f757317 100644
--- a/Jenkinsfile
+++ b/.jenkins/Jenkinsfile
@@ -3,30 +3,33 @@ pipeline {
tools {
terraform 'terraform'
}
+ environment {
+ terraformDir = '.terraform'
+ }
stages {
stage('dependencies') {
steps {
- script {
- withCredentials([file(credentialsId: env.contrast_yaml, variable: 'path')]) {
- def contents = readFile(env.path)
- writeFile file: 'contrast_security.yaml', text: "$contents"
+ dir("$terraformDir") {
+ script {
+ withCredentials([file(credentialsId: env.contrast_yaml, variable: 'path')]) {
+ def contents = readFile(env.path)
+ writeFile file: 'contrast_security.yaml', text: "$contents"
+ }
}
+ sh '''
+ terraform init -upgrade
+ '''
}
- sh '''
- terraform init -upgrade
- '''
}
}
stage('provision') {
steps {
- script {
- env.GIT_SHORT_COMMIT = checkout(scm).GIT_COMMIT.take(7)
- env.GIT_BRANCH = checkout(scm).GIT_BRANCH
-
- withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
- try {
- sh """
+ dir("$terraformDir") {
+ script {
+ withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
+ try {
+ sh """
export ARM_CLIENT_ID=$AZURE_CLIENT_ID
export ARM_CLIENT_SECRET=$AZURE_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=$AZURE_SUBSCRIPTION_ID
@@ -36,14 +39,15 @@ pipeline {
-var 'initials=$initials' \
-var 'environment=qa' \
-var 'servername=jenkins' \
- -var 'session_metadata=branchName=${env.GIT_BRANCH},buildNumber=${BUILD_NUMBER},commitHash=${env.GIT_SHORT_COMMIT},version=1.0' \
+ -var 'session_metadata=branchName=${env.GIT_BRANCH},buildNumber=${BUILD_NUMBER},commitHash=${env.GIT_COMMIT},version=1.0' \
-var 'run_automated_tests=true'
"""
} catch (Exception e) {
- echo "Terraform refresh failed, deleting state"
- sh "rm -rf terraform.tfstate"
- currentBuild.result = "FAILURE"
- error("Aborting the build.")
+ echo 'Terraform refresh failed, deleting state'
+ sh 'rm -rf terraform.tfstate'
+ currentBuild.result = 'FAILURE'
+ error('Aborting the build.')
+ }
}
}
}
@@ -56,13 +60,11 @@ pipeline {
}
stage('provision - dev') {
steps {
- script {
- env.GIT_SHORT_COMMIT = checkout(scm).GIT_COMMIT.take(7)
- env.GIT_BRANCH = checkout(scm).GIT_BRANCH
-
- withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
- try {
- sh """
+ dir("$terraformDir") {
+ script {
+ withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
+ try {
+ sh """
export ARM_CLIENT_ID=$AZURE_CLIENT_ID
export ARM_CLIENT_SECRET=$AZURE_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=$AZURE_SUBSCRIPTION_ID
@@ -72,14 +74,15 @@ pipeline {
-var 'initials=$initials' \
-var 'environment=development' \
-var 'servername=Macbook-Pro' \
- -var 'session_metadata=branchName=${env.GIT_BRANCH},buildNumber=${BUILD_NUMBER},commitHash=${env.GIT_SHORT_COMMIT},version=1.0' \
+ -var 'session_metadata=branchName=${env.GIT_BRANCH},buildNumber=${BUILD_NUMBER},commitHash=${env.GIT_COMMIT},version=1.0' \
-var 'run_automated_tests=true'
"""
} catch (Exception e) {
- echo "Terraform refresh failed, deleting state"
- sh "rm -rf terraform.tfstate"
- currentBuild.result = "FAILURE"
- error("Aborting the build.")
+ echo 'Terraform refresh failed, deleting state'
+ sh 'rm -rf terraform.tfstate'
+ currentBuild.result = 'FAILURE'
+ error('Aborting the build.')
+ }
}
}
}
@@ -92,25 +95,24 @@ pipeline {
}
stage('provision - prod') {
steps {
- script {
- env.GIT_SHORT_COMMIT = checkout(scm).GIT_COMMIT.take(7)
- env.GIT_BRANCH = checkout(scm).GIT_BRANCH
-
- withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
- try {
- sh """
+ dir("$terraformDir") {
+ script {
+ withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
+ try {
+ sh """
export ARM_CLIENT_ID=$AZURE_CLIENT_ID
export ARM_CLIENT_SECRET=$AZURE_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=$AZURE_SUBSCRIPTION_ID
export ARM_TENANT_ID=$AZURE_TENANT_ID
- terraform apply -auto-approve -var 'location=$location' -var 'initials=$initials' -var 'environment=production' -var 'servername=Prod-01' -var 'session_metadata=branchName=${env.GIT_BRANCH},buildNumber=${BUILD_NUMBER},commitHash=${env.GIT_SHORT_COMMIT},version=1.0' -var 'run_automated_tests=true'
+ terraform apply -auto-approve -var 'location=$location' -var 'initials=$initials' -var 'environment=production' -var 'servername=Prod-01' -var 'session_metadata=branchName=${env.GIT_BRANCH},buildNumber=${BUILD_NUMBER},commitHash=${env.GIT_COMMIT},version=1.0' -var 'run_automated_tests=true'
"""
} catch (Exception e) {
- echo "Terraform refresh failed, deleting state"
- sh "rm -rf terraform.tfstate"
- currentBuild.result = "FAILURE"
- error("Aborting the build.")
+ echo 'Terraform refresh failed, deleting state'
+ sh 'rm -rf terraform.tfstate'
+ currentBuild.result = 'FAILURE'
+ error('Aborting the build.')
+ }
}
}
}
@@ -123,8 +125,9 @@ pipeline {
}
stage('destroy') {
steps {
- withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
- sh """
+ dir("$terraformDir") {
+ withCredentials([azureServicePrincipal('ContrastAzureSponsored')]) {
+ sh """
export ARM_CLIENT_ID=\$AZURE_CLIENT_ID
export ARM_CLIENT_SECRET=\$AZURE_CLIENT_SECRET
export ARM_SUBSCRIPTION_ID=\$AZURE_SUBSCRIPTION_ID
@@ -132,6 +135,7 @@ pipeline {
terraform destroy --auto-approve \
-var 'location=$location'
"""
+ }
}
}
}
diff --git a/.ruby-version b/.ruby-version
index 097a15a..0aec50e 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.6.2
+3.1.4
diff --git a/main.tf b/.terraform/main.tf
similarity index 93%
rename from main.tf
rename to .terraform/main.tf
index 44d4e43..f33ad90 100644
--- a/main.tf
+++ b/.terraform/main.tf
@@ -11,7 +11,7 @@ data "external" "yaml" {
#Set up a personal resource group for the SE local to them
resource "azurerm_resource_group" "personal" {
- name = "Sales-Engineer-${var.initials}"
+ name = "Sales-Engineer-Jenkins-${var.initials}"
location = var.location
}
@@ -26,7 +26,7 @@ resource "azurerm_container_group" "app" {
container {
name = "web"
- image = "contrastsecuritydemo/railsgoat:1.0"
+ image = "contrastsecuritydemo/railsgoat:6.1.7"
cpu = "1"
memory = "1.5"
ports {
diff --git a/outputs.tf b/.terraform/outputs.tf
similarity index 100%
rename from outputs.tf
rename to .terraform/outputs.tf
diff --git a/.terraform/parseyaml.py b/.terraform/parseyaml.py
new file mode 100644
index 0000000..974f1b6
--- /dev/null
+++ b/.terraform/parseyaml.py
@@ -0,0 +1,4 @@
+import yaml, json
+with open('../contrast_security.yaml') as f:
+ config = yaml.safe_load(f)
+ print(json.dumps(config['api']))
diff --git a/variables.tf b/.terraform/variables.tf
similarity index 100%
rename from variables.tf
rename to .terraform/variables.tf
diff --git a/versions.tf b/.terraform/versions.tf
similarity index 100%
rename from versions.tf
rename to .terraform/versions.tf
diff --git a/1-Build-Docker-Image.sh b/1-Build-Docker-Image.sh
deleted file mode 100755
index b9f61ad..0000000
--- a/1-Build-Docker-Image.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-docker build . -t railsgoat:1.0 --no-cache
\ No newline at end of file
diff --git a/2-Deploy-Docker-Image-To-Docker-Hub.sh b/2-Deploy-Docker-Image-To-Docker-Hub.sh
deleted file mode 100755
index 0de23a3..0000000
--- a/2-Deploy-Docker-Image-To-Docker-Hub.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-echo "Please log in using your Docker Hub credentials to update the container image"
-docker login
-docker tag railsgoat:1.0 contrastsecuritydemo/railsgoat:1.0
-docker push contrastsecuritydemo/railsgoat:1.0
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 0074015..e3affc8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,68 +1,73 @@
-# TODO: change to slim or alpine
-FROM ruby:2.6.2
+# Multistage docker build which first builds and bundles all Ruby gems before
+# creating build targets for the development and production images.
-ARG username
-ARG service_key
+# Default Ruby version for this project.
+ARG RUBY_VERSION=3.1.4
-# Add build and runtime dependencies
-# TODO: separate build & runtime and purge build dependencies at the end
-RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
+# BASE STAGE
+# Create a base ruby-alpine stage with common configuration
+# that can be used in all other stages.
+FROM ruby:$RUBY_VERSION-alpine as ruby-alpine
-# Install phantomjs dependencies
-RUN apt-get update \
- && apt-get install -y --no-install-recommends \
- ca-certificates \
- bzip2 \
- libfontconfig \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
+# Set environment variables to be shared across all stages.
+ENV GEM_HOME=/usr/local/bundle
+ENV BUNDLE_PATH=$GEM_HOME
+ENV BUNDLE_APP_CONFIG=$BUNDLE_PATH
+ENV RAILS_ENV development
+ENV RACK_ENV development
-# Install phantomjs & clean up
-RUN apt-get update \
- && apt-get install -y --no-install-recommends \
- curl \
- && mkdir /tmp/phantomjs \
- && curl -L https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 \
- | tar -xj --strip-components=1 -C /tmp/phantomjs \
- && cd /tmp/phantomjs \
- && mv bin/phantomjs /usr/local/bin \
- && cd \
- && apt-get purge --auto-remove -y \
- curl \
- && apt-get clean \
- && rm -rf /tmp/* /var/lib/apt/lists/*
+# Add basic packages that are shared across all stages
+RUN apk add --no-cache \
+ nodejs \
+ tzdata
-# Build and package the app
-RUN mkdir /myapp
-WORKDIR /myapp
-ADD Gemfile /myapp/Gemfile
-ADD Gemfile.lock /myapp/Gemfile.lock
+# BUILDER STAGE
+# Build all gems and dependencies in a builder stage,
+# whch can then be copied to other stages.
+FROM ruby-alpine as builder
-# Add Contrast agent
-RUN bundle add contrast-agent
+# Add packages for required for building
+RUN apk add --no-cache \
+ autoconf \
+ build-base \
+ libpq-dev \
+ mariadb-dev
-RUN bundle install
+# Set the working directory for the app.
+WORKDIR /app
-ADD ./app /myapp/app
-ADD ./config /myapp/config
-ADD ./db /myapp/db
-ADD ./doc /myapp/doc
-ADD ./lib /myapp/lib
-ADD ./log /myapp/log
-ADD ./public /myapp/public
-ADD ./script /myapp/script
-ADD ./spec /myapp/spec
-RUN mkdir /myapp/tmp
-ADD ./vendor /myapp/vendor
-ADD ./config.ru /myapp/config.ru
-ADD ./entrypoint.sh /myapp/entrypoint.sh
-ADD ./Rakefile /myapp/Rakefile
+# Copy the Gemfile and Gemfile.lock files to the current directory.
+COPY Gemfile* .
-#Setup the database
-RUN rails db:setup
+# Install gems and remove any unnecessary build artifacts.
+RUN bundle config force_ruby_platform true \
+ && bundle install --jobs 4 --retry 3 \
+ && rm -rf $BUNDLE_PATH/cache/*.gem \
+ && rm -rf $BUNDLE_PATH/ruby/*/cache
-# Make port 3000 available
+# RUNNER STAGE
+# Copy the needed gems and dependenies from the builder stage to
+# create the final minimal image for running the app.
+FROM ruby-alpine as runner
+
+# Add packages required for running the app
+RUN apk add --no-cache \
+ chromium \
+ chromium-chromedriver \
+ libpq \
+ mariadb
+
+# Set the working directory for the app.
+WORKDIR /app
+
+# Copy the bundle directory from the "builder" image
+# and copy all other files to the current directory.
+COPY --from=builder $BUNDLE_PATH $BUNDLE_PATH
+COPY . .
+
+# Expose port 3000 for the application.
EXPOSE 3000
-# Start the app server
-ENTRYPOINT [ "/bin/bash", "-c", "/myapp/entrypoint.sh"]
\ No newline at end of file
+# Run the command to start the Rails server.
+ENTRYPOINT ["/bin/sh"]
+CMD ["/app/entrypoint.sh"]
diff --git a/Gemfile b/Gemfile
index cde13e6..669ae1e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,13 +1,16 @@
# frozen_string_literal: true
source "https://rubygems.org"
-#don't upgrade
-gem "rails", "5.1.7"
+gem "rails", "6.1.7"
-ruby "2.6.2"
+ruby "3.1.4"
+
+# Add the Contrast Agent gem
+gem "contrast-agent"
gem "aruba"
gem "bcrypt"
+gem "bootsnap"
gem "coffee-rails"
gem "execjs"
gem "foreman"
@@ -19,15 +22,15 @@ gem "pry-rails" # not in dev group in case running via prod/staging @ a training
gem "puma"
gem "rails-perftest"
gem "rake"
-gem "responders" #For Rails 4.2 # LOCKED DOWN
+gem "responders"
gem "ruby-prof"
-gem "sass-rails"
+gem "sassc-rails"
gem "simplecov", require: false, group: :test
-gem "sqlite3", "1.3.13" # 2/7/2019: LOCKED DOWN
-gem "therubyracer"
+gem "sqlite3"
gem "turbolinks"
gem "uglifier"
gem "unicorn"
+gem "websocket-driver"
# Add SMTP server support using MailCatcher
# NOTE: https://github.com/sj26/mailcatcher#bundler
@@ -51,7 +54,7 @@ group :development, :test, :mysql do
gem "capybara"
gem "database_cleaner"
gem "launchy"
- gem "poltergeist"
+ gem "cuprite"
gem "rspec-rails"
gem "test-unit"
end
diff --git a/Gemfile.lock b/Gemfile.lock
index e53a145..adb8300 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,128 +1,175 @@
GEM
remote: https://rubygems.org/
specs:
- actioncable (5.1.7)
- actionpack (= 5.1.7)
+ actioncable (6.1.7)
+ actionpack (= 6.1.7)
+ activesupport (= 6.1.7)
nio4r (~> 2.0)
- websocket-driver (~> 0.6.1)
- actionmailer (5.1.7)
- actionpack (= 5.1.7)
- actionview (= 5.1.7)
- activejob (= 5.1.7)
+ websocket-driver (>= 0.6.1)
+ actionmailbox (6.1.7)
+ actionpack (= 6.1.7)
+ activejob (= 6.1.7)
+ activerecord (= 6.1.7)
+ activestorage (= 6.1.7)
+ activesupport (= 6.1.7)
+ mail (>= 2.7.1)
+ actionmailer (6.1.7)
+ actionpack (= 6.1.7)
+ actionview (= 6.1.7)
+ activejob (= 6.1.7)
+ activesupport (= 6.1.7)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
- actionpack (5.1.7)
- actionview (= 5.1.7)
- activesupport (= 5.1.7)
- rack (~> 2.0)
+ actionpack (6.1.7)
+ actionview (= 6.1.7)
+ activesupport (= 6.1.7)
+ rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (5.1.7)
- activesupport (= 5.1.7)
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
+ actiontext (6.1.7)
+ actionpack (= 6.1.7)
+ activerecord (= 6.1.7)
+ activestorage (= 6.1.7)
+ activesupport (= 6.1.7)
+ nokogiri (>= 1.8.5)
+ actionview (6.1.7)
+ activesupport (= 6.1.7)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
- activejob (5.1.7)
- activesupport (= 5.1.7)
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
+ activejob (6.1.7)
+ activesupport (= 6.1.7)
globalid (>= 0.3.6)
- activemodel (5.1.7)
- activesupport (= 5.1.7)
- activerecord (5.1.7)
- activemodel (= 5.1.7)
- activesupport (= 5.1.7)
- arel (~> 8.0)
- activesupport (5.1.7)
+ activemodel (6.1.7)
+ activesupport (= 6.1.7)
+ activerecord (6.1.7)
+ activemodel (= 6.1.7)
+ activesupport (= 6.1.7)
+ activestorage (6.1.7)
+ actionpack (= 6.1.7)
+ activejob (= 6.1.7)
+ activerecord (= 6.1.7)
+ activesupport (= 6.1.7)
+ marcel (~> 1.0)
+ mini_mime (>= 1.1.0)
+ activesupport (6.1.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 0.7, < 2)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
- addressable (2.6.0)
- public_suffix (>= 2.0.2, < 4.0)
- arel (8.0.0)
- aruba (0.14.9)
- childprocess (>= 0.6.3, < 1.1.0)
- contracts (~> 0.9)
- cucumber (>= 1.3.19)
- ffi (~> 1.9)
- rspec-expectations (>= 2.99)
- thor (~> 0.19)
- ast (2.4.0)
- backports (3.13.0)
- bcrypt (3.1.12)
- better_errors (2.5.1)
- coderay (>= 1.0.0)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ zeitwerk (~> 2.3)
+ addressable (2.8.4)
+ public_suffix (>= 2.0.2, < 6.0)
+ aruba (2.1.0)
+ bundler (>= 1.17, < 3.0)
+ childprocess (>= 2.0, < 5.0)
+ contracts (>= 0.16.0, < 0.18.0)
+ cucumber (>= 4.0, < 9.0)
+ rspec-expectations (~> 3.4)
+ thor (~> 1.0)
+ ast (2.4.2)
+ bcrypt (3.1.19)
+ better_errors (2.10.1)
erubi (>= 1.0.0)
rack (>= 0.9.0)
- binding_of_caller (0.8.0)
+ rouge (>= 1.0.0)
+ binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
- builder (3.2.3)
- bundler-audit (0.6.1)
+ bootsnap (1.16.0)
+ msgpack (~> 1.2)
+ builder (3.2.4)
+ bundler-audit (0.9.1)
bundler (>= 1.2.0, < 3)
- thor (~> 0.18)
- capybara (3.16.1)
+ thor (~> 1.0)
+ capybara (3.39.2)
addressable
+ matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
- regexp_parser (~> 1.2)
+ regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
- childprocess (1.0.1)
- rake (< 13.0)
- cliver (0.3.2)
- coderay (1.1.2)
- coffee-rails (4.2.2)
+ childprocess (4.1.0)
+ coderay (1.1.3)
+ coffee-rails (5.0.0)
coffee-script (>= 2.2.0)
- railties (>= 4.0.0)
+ railties (>= 5.2.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
- concurrent-ruby (1.1.5)
- contracts (0.16.0)
- crass (1.0.4)
- cucumber (3.1.2)
- builder (>= 2.1.2)
- cucumber-core (~> 3.2.0)
- cucumber-expressions (~> 6.0.1)
- cucumber-wire (~> 0.0.1)
- diff-lcs (~> 1.3)
- gherkin (~> 5.1.0)
- multi_json (>= 1.7.5, < 2.0)
- multi_test (>= 0.1.2)
- cucumber-core (3.2.1)
- backports (>= 3.8.0)
- cucumber-tag_expressions (~> 1.1.0)
- gherkin (~> 5.0)
- cucumber-expressions (6.0.1)
- cucumber-tag_expressions (1.1.1)
- cucumber-wire (0.0.1)
- database_cleaner (1.7.0)
- debug_inspector (0.0.3)
- diff-lcs (1.3)
- docile (1.3.1)
- em-websocket (0.5.1)
+ concurrent-ruby (1.2.2)
+ contracts (0.17)
+ contrast-agent (7.3.2)
+ contrast-agent-lib (= 1.1.1)
+ ffi (~> 1.0)
+ ougai (>= 1.8, < 3.0.0)
+ rack (~> 2.0)
+ contrast-agent-lib (1.1.1)
+ crass (1.0.6)
+ cucumber (8.0.0)
+ builder (~> 3.2, >= 3.2.4)
+ cucumber-ci-environment (~> 9.0, >= 9.0.4)
+ cucumber-core (~> 11.0, >= 11.0.0)
+ cucumber-cucumber-expressions (~> 15.1, >= 15.1.1)
+ cucumber-gherkin (~> 23.0, >= 23.0.1)
+ cucumber-html-formatter (~> 19.1, >= 19.1.0)
+ cucumber-messages (~> 18.0, >= 18.0.0)
+ diff-lcs (~> 1.5, >= 1.5.0)
+ mime-types (~> 3.4, >= 3.4.1)
+ multi_test (~> 1.1, >= 1.1.0)
+ sys-uname (~> 1.2, >= 1.2.2)
+ cucumber-ci-environment (9.2.0)
+ cucumber-core (11.0.0)
+ cucumber-gherkin (~> 23.0, >= 23.0.1)
+ cucumber-messages (~> 18.0, >= 18.0.0)
+ cucumber-tag-expressions (~> 4.1, >= 4.1.0)
+ cucumber-cucumber-expressions (15.2.0)
+ cucumber-gherkin (23.0.1)
+ cucumber-messages (~> 18.0, >= 18.0.0)
+ cucumber-html-formatter (19.2.0)
+ cucumber-messages (~> 18.0, >= 18.0.0)
+ cucumber-messages (18.0.0)
+ cucumber-tag-expressions (4.1.0)
+ cuprite (0.14.3)
+ capybara (~> 3.0)
+ ferrum (~> 0.13.0)
+ database_cleaner (2.0.2)
+ database_cleaner-active_record (>= 2, < 3)
+ database_cleaner-active_record (2.1.0)
+ activerecord (>= 5.a)
+ database_cleaner-core (~> 2.0.0)
+ database_cleaner-core (2.0.1)
+ date (3.3.3)
+ debug_inspector (1.1.0)
+ diff-lcs (1.5.0)
+ docile (1.4.0)
+ em-websocket (0.5.3)
eventmachine (>= 0.12.9)
- http_parser.rb (~> 0.6.0)
- erubi (1.8.0)
+ http_parser.rb (~> 0)
+ erubi (1.12.0)
eventmachine (1.2.7)
- execjs (2.7.0)
- ffi (1.10.0)
- foreman (0.85.0)
- thor (~> 0.19.1)
- formatador (0.2.5)
- gherkin (5.1.0)
- globalid (0.4.2)
- activesupport (>= 4.2.0)
- guard (2.15.0)
+ execjs (2.8.1)
+ ferrum (0.13)
+ addressable (~> 2.5)
+ concurrent-ruby (~> 1.1)
+ webrick (~> 1.7)
+ websocket-driver (>= 0.6, < 0.8)
+ ffi (1.15.5)
+ foreman (0.87.2)
+ formatador (1.1.0)
+ globalid (1.1.0)
+ activesupport (>= 5.0)
+ guard (2.18.0)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
lumberjack (>= 1.0.12, < 2.0)
nenv (~> 0.1)
notiffany (~> 0.0)
- pry (>= 0.9.12)
+ pry (>= 0.13.0)
shellany (~> 0.0)
thor (>= 0.18.1)
guard-compat (1.2.1)
@@ -135,196 +182,230 @@ GEM
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
- guard-shell (0.7.1)
+ guard-shell (0.7.2)
guard (>= 2.0.0)
guard-compat (~> 1.0)
- http_parser.rb (0.6.0)
- i18n (1.6.0)
+ http_parser.rb (0.8.0)
+ i18n (1.14.1)
concurrent-ruby (~> 1.0)
- jaro_winkler (1.5.2)
jquery-fileupload-rails (1.0.0)
actionpack (>= 3.1)
railties (>= 3.1)
sassc
- jquery-rails (4.3.3)
+ jquery-rails (4.6.0)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
- json (2.2.0)
- kgio (2.11.2)
- launchy (2.4.3)
- addressable (~> 2.3)
- libv8 (3.16.14.19)
- listen (3.1.5)
- rb-fsevent (~> 0.9, >= 0.9.4)
- rb-inotify (~> 0.9, >= 0.9.7)
- ruby_dep (~> 1.2)
- loofah (2.2.3)
+ json (2.6.3)
+ kgio (2.11.4)
+ language_server-protocol (3.17.0.3)
+ launchy (2.5.2)
+ addressable (~> 2.8)
+ listen (3.8.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ loofah (2.21.3)
crass (~> 1.0.2)
- nokogiri (>= 1.5.9)
- lumberjack (1.0.13)
- mail (2.7.1)
+ nokogiri (>= 1.12.0)
+ lumberjack (1.2.9)
+ mail (2.8.1)
mini_mime (>= 0.1.1)
- method_source (0.9.2)
- mini_mime (1.0.1)
- mini_portile2 (2.4.0)
- minitest (5.11.3)
- multi_json (1.13.1)
- multi_test (0.1.2)
- mysql2 (0.5.2)
+ net-imap
+ net-pop
+ net-smtp
+ marcel (1.0.2)
+ matrix (0.4.2)
+ method_source (1.0.0)
+ mime-types (3.4.1)
+ mime-types-data (~> 3.2015)
+ mime-types-data (3.2023.0218.1)
+ mini_mime (1.1.2)
+ mini_portile2 (2.8.4)
+ minitest (5.19.0)
+ msgpack (1.7.2)
+ multi_json (1.15.0)
+ multi_test (1.1.0)
+ mysql2 (0.5.5)
nenv (0.3.0)
- nio4r (2.3.1)
- nokogiri (1.10.2)
- mini_portile2 (~> 2.4.0)
- notiffany (0.1.1)
+ net-imap (0.3.7)
+ date
+ net-protocol
+ net-pop (0.1.2)
+ net-protocol
+ net-protocol (0.2.1)
+ timeout
+ net-smtp (0.3.3)
+ net-protocol
+ nio4r (2.5.9)
+ nokogiri (1.15.3)
+ mini_portile2 (~> 2.8.2)
+ racc (~> 1.4)
+ notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
- parallel (1.17.0)
- parser (2.6.2.1)
- ast (~> 2.4.0)
- poltergeist (1.18.1)
- capybara (>= 2.1, < 4)
- cliver (~> 0.3.1)
- websocket-driver (>= 0.2.0)
+ oj (3.16.0)
+ ougai (2.0.0)
+ oj (~> 3.10)
+ parallel (1.23.0)
+ parser (3.2.2.3)
+ ast (~> 2.4.1)
+ racc
powder (0.4.0)
thor (>= 0.11.5)
- power_assert (1.1.4)
- pry (0.12.2)
- coderay (~> 1.1.0)
- method_source (~> 0.9.0)
+ power_assert (2.0.3)
+ pry (0.14.2)
+ coderay (~> 1.1)
+ method_source (~> 1.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
- psych (3.1.0)
- public_suffix (3.0.3)
- puma (3.12.1)
- rack (2.0.7)
- rack-livereload (0.3.17)
+ public_suffix (5.0.3)
+ puma (6.3.0)
+ nio4r (~> 2.0)
+ racc (1.7.1)
+ rack (2.2.8)
+ rack-livereload (0.5.1)
rack
- rack-test (1.1.0)
- rack (>= 1.0, < 3)
- rails (5.1.7)
- actioncable (= 5.1.7)
- actionmailer (= 5.1.7)
- actionpack (= 5.1.7)
- actionview (= 5.1.7)
- activejob (= 5.1.7)
- activemodel (= 5.1.7)
- activerecord (= 5.1.7)
- activesupport (= 5.1.7)
- bundler (>= 1.3.0)
- railties (= 5.1.7)
+ rack-test (2.1.0)
+ rack (>= 1.3)
+ rails (6.1.7)
+ actioncable (= 6.1.7)
+ actionmailbox (= 6.1.7)
+ actionmailer (= 6.1.7)
+ actionpack (= 6.1.7)
+ actiontext (= 6.1.7)
+ actionview (= 6.1.7)
+ activejob (= 6.1.7)
+ activemodel (= 6.1.7)
+ activerecord (= 6.1.7)
+ activestorage (= 6.1.7)
+ activesupport (= 6.1.7)
+ bundler (>= 1.15.0)
+ railties (= 6.1.7)
sprockets-rails (>= 2.0.0)
- rails-dom-testing (2.0.3)
- activesupport (>= 4.2.0)
+ rails-dom-testing (2.1.1)
+ activesupport (>= 5.0.0)
+ minitest
nokogiri (>= 1.6)
- rails-html-sanitizer (1.0.4)
- loofah (~> 2.2, >= 2.2.2)
+ rails-html-sanitizer (1.6.0)
+ loofah (~> 2.21)
+ nokogiri (~> 1.14)
rails-perftest (0.0.7)
- railties (5.1.7)
- actionpack (= 5.1.7)
- activesupport (= 5.1.7)
+ railties (6.1.7)
+ actionpack (= 6.1.7)
+ activesupport (= 6.1.7)
method_source
- rake (>= 0.8.7)
- thor (>= 0.18.1, < 2.0)
- rainbow (3.0.0)
- raindrops (0.19.0)
- rake (12.3.2)
- rb-fsevent (0.10.3)
- rb-inotify (0.10.0)
+ rake (>= 12.2)
+ thor (~> 1.0)
+ rainbow (3.1.1)
+ raindrops (0.20.1)
+ rake (13.0.6)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.10.1)
ffi (~> 1.0)
- ref (2.0.0)
- regexp_parser (1.4.0)
- responders (2.4.1)
- actionpack (>= 4.2.0, < 6.0)
- railties (>= 4.2.0, < 6.0)
- rspec (3.8.0)
- rspec-core (~> 3.8.0)
- rspec-expectations (~> 3.8.0)
- rspec-mocks (~> 3.8.0)
- rspec-core (3.8.0)
- rspec-support (~> 3.8.0)
- rspec-expectations (3.8.2)
+ regexp_parser (2.8.1)
+ responders (3.1.0)
+ actionpack (>= 5.2)
+ railties (>= 5.2)
+ rexml (3.2.6)
+ rouge (4.1.3)
+ rspec (3.12.0)
+ rspec-core (~> 3.12.0)
+ rspec-expectations (~> 3.12.0)
+ rspec-mocks (~> 3.12.0)
+ rspec-core (3.12.2)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-mocks (3.8.0)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-rails (3.8.2)
- actionpack (>= 3.0)
- activesupport (>= 3.0)
- railties (>= 3.0)
- rspec-core (~> 3.8.0)
- rspec-expectations (~> 3.8.0)
- rspec-mocks (~> 3.8.0)
- rspec-support (~> 3.8.0)
- rspec-support (3.8.0)
- rubocop (0.67.2)
- jaro_winkler (~> 1.5.1)
+ rspec-support (~> 3.12.0)
+ rspec-rails (6.0.3)
+ actionpack (>= 6.1)
+ activesupport (>= 6.1)
+ railties (>= 6.1)
+ rspec-core (~> 3.12)
+ rspec-expectations (~> 3.12)
+ rspec-mocks (~> 3.12)
+ rspec-support (~> 3.12)
+ rspec-support (3.12.1)
+ rubocop (1.55.1)
+ json (~> 2.3)
+ language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
- parser (>= 2.5, != 2.5.1.1)
- psych (>= 3.1.0)
+ parser (>= 3.2.2.3)
rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 1.8, < 3.0)
+ rexml (>= 3.2.5, < 4.0)
+ rubocop-ast (>= 1.28.1, < 2.0)
ruby-progressbar (~> 1.7)
- unicode-display_width (>= 1.4.0, < 1.6)
- rubocop-github (0.12.0)
- rubocop (~> 0.59)
- ruby-prof (0.17.0)
- ruby-progressbar (1.10.0)
- ruby_dep (1.5.0)
- sass (3.7.4)
- sass-listen (~> 4.0.0)
- sass-listen (4.0.0)
- rb-fsevent (~> 0.9, >= 0.9.4)
- rb-inotify (~> 0.9, >= 0.9.7)
- sass-rails (5.0.7)
- railties (>= 4.0.0, < 6)
- sass (~> 3.1)
- sprockets (>= 2.8, < 4.0)
- sprockets-rails (>= 2.0, < 4.0)
- tilt (>= 1.1, < 3)
- sassc (2.0.1)
+ unicode-display_width (>= 2.4.0, < 3.0)
+ rubocop-ast (1.29.0)
+ parser (>= 3.2.1.0)
+ rubocop-github (0.20.0)
+ rubocop (>= 1.37)
+ rubocop-performance (>= 1.15)
+ rubocop-rails (>= 2.17)
+ rubocop-performance (1.18.0)
+ rubocop (>= 1.7.0, < 2.0)
+ rubocop-ast (>= 0.4.0)
+ rubocop-rails (2.20.2)
+ activesupport (>= 4.2.0)
+ rack (>= 1.1)
+ rubocop (>= 1.33.0, < 2.0)
+ ruby-prof (1.6.3)
+ ruby-progressbar (1.13.0)
+ sassc (2.4.0)
ffi (~> 1.9)
- rake
+ sassc-rails (2.1.2)
+ railties (>= 4.0.0)
+ sassc (>= 2.0)
+ sprockets (> 3.0)
+ sprockets-rails
+ tilt
shellany (0.0.1)
- simplecov (0.16.1)
+ simplecov (0.22.0)
docile (~> 1.1)
- json (>= 1.8, < 3)
- simplecov-html (~> 0.10.0)
- simplecov-html (0.10.2)
- sprockets (3.7.2)
+ simplecov-html (~> 0.11)
+ simplecov_json_formatter (~> 0.1)
+ simplecov-html (0.12.3)
+ simplecov_json_formatter (0.1.4)
+ sprockets (4.2.0)
concurrent-ruby (~> 1.0)
- rack (> 1, < 3)
- sprockets-rails (3.2.1)
- actionpack (>= 4.0)
- activesupport (>= 4.0)
+ rack (>= 2.2.4, < 4)
+ sprockets-rails (3.4.2)
+ actionpack (>= 5.2)
+ activesupport (>= 5.2)
sprockets (>= 3.0.0)
- sqlite3 (1.3.13)
- test-unit (3.3.1)
+ sqlite3 (1.6.3)
+ mini_portile2 (~> 2.8.0)
+ sys-uname (1.2.3)
+ ffi (~> 1.1)
+ test-unit (3.6.1)
power_assert
- therubyracer (0.12.3)
- libv8 (~> 3.16.14.15)
- ref
- thor (0.19.4)
- thread_safe (0.3.6)
- tilt (2.0.9)
+ thor (1.2.2)
+ tilt (2.2.0)
+ timeout (0.4.0)
travis-lint (2.0.0)
json
- turbolinks (5.2.0)
+ turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
- tzinfo (1.2.5)
- thread_safe (~> 0.1)
- uglifier (4.1.20)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
+ uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
- unicode-display_width (1.5.0)
- unicorn (5.5.0)
+ unicode-display_width (2.4.2)
+ unicorn (6.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
- websocket-driver (0.6.5)
+ webrick (1.8.1)
+ websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
- websocket-extensions (0.1.3)
+ websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
+ zeitwerk (2.6.10)
PLATFORMS
ruby
@@ -334,9 +415,12 @@ DEPENDENCIES
bcrypt
better_errors
binding_of_caller
+ bootsnap
bundler-audit
capybara
coffee-rails
+ contrast-agent
+ cuprite
database_cleaner
execjs
foreman
@@ -348,13 +432,12 @@ DEPENDENCIES
launchy
minitest
mysql2
- poltergeist
powder
pry
pry-rails
puma
rack-livereload
- rails (= 5.1.7)
+ rails (= 6.1.7)
rails-perftest
rake
rb-fsevent
@@ -362,18 +445,18 @@ DEPENDENCIES
rspec-rails
rubocop-github
ruby-prof
- sass-rails
+ sassc-rails
simplecov
- sqlite3 (= 1.3.13)
+ sqlite3
test-unit
- therubyracer
travis-lint
turbolinks
uglifier
unicorn
+ websocket-driver
RUBY VERSION
- ruby 2.6.2p47
+ ruby 3.1.4p223
BUNDLED WITH
- 1.17.2
+ 2.3.26
diff --git a/README.md b/README.md
index 51aa38d..1eb7055 100755
--- a/README.md
+++ b/README.md
@@ -1,62 +1,100 @@
-# RailsGoat: A deliberately insecure Ruby web application
+# Contrast Security Demo: RailsGoat
-This is a Ruby demo application, based on https://github.com/OWASP/railsgoat.
+**A deliberately vulnerable Ruby on Rails application with added Contrast Security Instrumentation.**
+
+This demo will give you hands on experience with Contrast Security's instrumentation and observability technology. You'll learn how to onboard an application to the Contrast platform, and can then get hands with Contrast Assess and Contrast Protect:
+* **Contrast Assess** combines Interactive Application Security Testing (IAST) and Software Composition Analysis (SCA) to provide visibility into vulnerabilities across your custom code and third party libraries.
+* **Contrast Protect** is Runtime Application Self Protection (RASP) that protects applications in production by blocking attacks and complex exploitation in real time.
+
+### About Contrast Security
+Contrast Security is the leader in modernized application security, embedding code analysis and attack prevention directly into software with patented security instrumentation technology. [Find out more about Contrast on our website.](https://www.contrastsecurity.com/contrast-assess)
+
+### About RailsGoat
+RailsGoat is a deliberately vulnerable Ruby on Rails application, based on [OWASP RailsGoat](https://github.com/OWASP/railsgoat). We've added some Contrast dependencies to this project to help you get started quickly.
+
+# Running the demo application
+## Run with Docker (Quick Start)
+To get started quickly and easily with RailsGoat and the Contrast Agent, you can pull our already-prepared docker image from Docker Hub.
+
+First, retrieve your agent keys from the Contrast Platform. To find your organization keys please follow this [documentation](https://docs.contrastsecurity.com/en/find-the-agent-keys.html). Then run the following command, adding in your agent keys in place of `XXXXXX`:
+
+```bash
+docker run -it --rm -p 3000:3000 \
+ -e CONTRAST__API__URL=https://eval.contrastsecurity.com/Contrast \
+ -e CONTRAST__API__API_KEY=XXXXXX \
+ -e CONTRAST__API__SERVICE_KEY=XXXXXX \
+ -e CONTRAST__API__USER_NAME=XXXXXX \
+ contrastsecuritydemo/railsgoat:6.1.7
+```
+
+## Build and run with Docker
+To build and run RailsGoat locally, first clone this repo to your local machine, and ensure you have [Docker](https://docs.docker.com/engine/installation/) and [Docker Compose](https://docs.docker.com/compose/install/) installed. You can then use the provided Dockerfile and Docker Compose configuration to build the container and start instances of RailsGoat with the Contrast agent installed.
+
+First, retrieve your agent keys from the Contrast Platform. To find your organization keys please follow this [documentation](https://docs.contrastsecurity.com/en/find-the-agent-keys.html).
+
+Set your agent keys either by adding them to the `contrast_security.yaml` file in the `config` directory, or by adding them to the `.env` file in the root directory (you can also find other agent configuration options in these files).
+
+You can now build and run the container using Docker Compose:
+```sh
+docker-compose up --build
+```
+
+By default, two RailsGoat instances will be started, one with Contrast Assess enabled, and one with Contrast Protect enabled. You can start only one service with this command:
+
+```sh
+docker-compose up railsgoat-dev
+docker-compose up railsgoat-prod
+```
+
+Open your favorite browser and navigate to http://localhost:3000 for Assess or http://localhost:3001 for Protect.
+
+
+## Running standalone
**Warning**: The computer running this application will be vulnerable to attacks, please take appropriate precautions.
-# Running standalone
+You can run RailGoat locally on any machine with Ruby, Rails, MySQL, Postgres installed.
-You can run RailGoat locally on any machine with Ruby and Rails 5.x installed.
+First, retrieve your agent keys from the Contrast Platform. To find your organization keys please follow this [documentation](https://docs.contrastsecurity.com/en/find-the-agent-keys.html).
-1. Place a `contrast_security.yaml` file into the application's root folder.
+Set your agent keys either by adding them to the `contrast_security.yaml` file in the `config` directory.
-1. Install the Contrast agent using:
+Install the dependencies using bundler:
```sh
- bundle add contrast-agent
bundle install
```
-3. Initialize the database:
-```sh
- rails db:setup
+
+If you receive an error, make sure you have `bundler` installed:
+
+```bash
+$ gem install bundler
```
-4. Start the Thin web server:
+
+Start the Thin web server:
```sh
rails server
```
-5. Browse the application at http://localhost:3000
-# Running in Docker
+Open your favorite browser and navigate to http://localhost:3000.
-You can run RailsGoat within a Docker container, tested on OSX. The agent is added automatically during the Docker build process.
-1. Place a `contrast_security.yaml` file into the application's root folder.
-1. Build the RailsGoat container image using `./1-Build-Docker-Image.sh`
-1. Run the container using
-```sh
-docker run \
- -v $PWD/contrast_security.yaml:/myapp/contrast_security.yaml \
- -e CONTRAST__APPLICATION__NAME=railsgoat \
- -p 3000:3000 railsgoat:latest
-```
-4. Browse the application at http://localhost:3000
+## Other Deployment Options
+There are other options for deploying RailsGoat. Please see the docs/ folder for more instructions:
+* [Deploying to Azure App Services](docs/DEPLOY_TO_AZURE.md)
+
+# Testing RailsGoat with Contrast Assess (IAST)
+Interactive Application Security Testing (IAST) works by observing application behavior at runtime to identify vulnerabilities as you interact with the application. To start analysis, all you need to do is start browsing around the application to exercise routes and the agent will analyse each request and how the application responds. Routes can also be exercised by automated functional testing such as integration and end-to-end tests.
-# Running in Azure (Azure App Service):
+### Test the application manually
-## Pre-Requisites
+Try logging in to the application using the supplied credentials, logging out again, creating a new user for yourself and browsing some of the other pages and functionality in the app.
-1. Place a `contrast_security.yaml` file into the application's root folder.
-1. Install Terraform from here: https://www.terraform.io/downloads.html.
-1. Install PyYAML using `pip install PyYAML`.
-1. Install the Azure cli tools using `brew update && brew install azure-cli`.
-1. Log into Azure to make sure you cache your credentials using `az login`.
-1. Edit the [variables.tf](variables.tf) file (or add a terraform.tfvars) to add your initials, preferred Azure location, app name, server name and environment.
-1. Run `terraform init` to download the required plugins.
-1. Run `terraform plan` and check the output for errors.
-1. Run `terraform apply` to build the infrastructure that you need in Azure, this will output the web address for the application.
-1. Run `terraform destroy` when you would like to stop the app service and release the resources.
+When you're done exploring the application, look at the Contrast Platform to see if any vulnerabilities were detected. You'll also see any vulnerable libraries that were detected, as well as the route coverage that you've achieved with your manual testing.
-## Running automated tests
+
+
+### Test the application with automated tests
RailsGoat 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) (version 2.1.1 has been tested in Dev and on Travis CI), which is required by the Poltergeist Capybara driver. Upon installation, simply run the following task:
@@ -67,6 +105,10 @@ rails training
For Docker run:
```sh
+docker compose exec railsgoat-dev bundle exec rails training
+
+# OR
+
docker run \
-v $PWD/contrast_security.yaml:/myapp/contrast_security.yaml \
-e CONTRAST__APPLICATION__NAME=railsgoat \
@@ -74,13 +116,6 @@ docker run \
-p 3000:3000 railsgoat:latest
```
-## Updating the Docker Image
-
-You can re-build the docker image (used by Terraform) by running two scripts in order:
-
-* 1-Build-Docker-Image.sh
-* 2-Deploy-Docker-Image-To-Docker-Hub.sh
-
# License
[The MIT License (MIT)](./LICENSE.md)
diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js
new file mode 100644
index 0000000..b16e53d
--- /dev/null
+++ b/app/assets/config/manifest.js
@@ -0,0 +1,3 @@
+//= link_tree ../images
+//= link_directory ../javascripts .js
+//= link_directory ../stylesheets .css
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index fd0a477..6b7dd0e 100755
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -12,7 +12,6 @@
//
//= require jquery
//= require jquery_ujs
-//= require turbolinks
//= require jquery.min.js
//= require jquery.scrollUp.js
//= require bootstrap.js
diff --git a/app/assets/stylesheets/main.css.erb b/app/assets/stylesheets/main.css.erb
index 2c1e9b6..cd11ffd 100755
--- a/app/assets/stylesheets/main.css.erb
+++ b/app/assets/stylesheets/main.css.erb
@@ -1967,31 +1967,31 @@ button.btn.btn-mini, input[type="submit"].btn.btn-mini {
*margin-right: .3em;
line-height: 14px;
vertical-align: text-top;
- background-image: url(<%=asset_path "glyphicons-halflings.png" %>);
+ background-image: url(glyphicons-halflings.png);
background-position: 14px 14px;
background-repeat: no-repeat;
margin-top: 1px; }
/* White icons with optional class, or on hover/active states of certain elements */
.icon-white {
- background-image: url(<%=asset_path "glyphicons-halflings-white.png" %>); }
+ background-image: url(glyphicons-halflings-white.png); }
.nav-pills > .active > a > [class^="icon-"], .nav-pills > .active > a > [class*=" icon-"] {
- background-image: url(<%=asset_path "glyphicons-halflings-white.png" %>); }
+ background-image: url(glyphicons-halflings-white.png); }
.nav-list > .active > a > [class^="icon-"], .nav-list > .active > a > [class*=" icon-"] {
- background-image: url(<%=asset_path "glyphicons-halflings-white.png" %>); }
+ background-image: url("glyphicons-halflings-white.png"); }
.navbar-inverse .nav > .active > a > [class^="icon-"], .navbar-inverse .nav > .active > a > [class*=" icon-"] {
- background-image: url(<%=asset_path "glyphicons-halflings-white.png" %>); }
+ background-image: url("glyphicons-halflings-white.png"); }
.dropdown-menu > li > a:hover > [class^="icon-"], .dropdown-menu > li > a:hover > [class*=" icon-"] {
- background-image: url(<%=asset_path "glyphicons-halflings-white.png" %>); }
+ background-image: url("glyphicons-halflings-white.png"); }
.dropdown-menu > .active > a > [class^="icon-"], .dropdown-menu > .active > a > [class*=" icon-"] {
- background-image: url(<%=asset_path "glyphicons-halflings-white.png" %>); }
+ background-image: url("glyphicons-halflings-white.png"); }
.dropdown-submenu:hover > a > [class^="icon-"], .dropdown-submenu:hover > a > [class*=" icon-"] {
- background-image: url(<%=asset_path "glyphicons-halflings-white.png" %>); }
+ background-image: url("glyphicons-halflings-white.png"); }
.icon-glass {
background-position: 0 0; }
@@ -4720,7 +4720,7 @@ button.close {
display: none; }
.modal-loading .modal-image {
- background: url(<%=asset_path "loading-orange.gif" %>) center no-repeat; }
+ background: url(loading-orange.gif) center no-repeat; }
.modal-gallery.fade .modal-image {
-webkit-transition: width 0.15s ease, height 0.15s ease;
@@ -4794,7 +4794,7 @@ button.close {
height: 40px;
margin: 0 2px;
outline: none;
- background: transparent url(<%=asset_path "social_icons.png" %>) no-repeat top left;
+ background: transparent url(social_icons.png) no-repeat top left;
text-indent: -9000px;
position: relative; }
.fancy-tooltip-wrapper li .tooltip-facebook, .fancy-tooltip-wrapper1 li .tooltip-facebook {
@@ -5049,7 +5049,7 @@ button.close {
.colorpicker-saturation {
width: 100px;
height: 100px;
- background-image: url(<%=asset_path "saturation.png" %>);
+ background-image: url(saturation.png);
cursor: crosshair;
float: left; }
.colorpicker-saturation i {
@@ -5093,10 +5093,10 @@ button.close {
margin-top: -1px; }
.colorpicker-hue {
- background-image: url(<%=asset_path "hue.png" %>); }
+ background-image: url(hue.png); }
.colorpicker-alpha {
- background-image: url(<%=asset_path "alpha.png" %>);
+ background-image: url(alpha.png);
display: none; }
.colorpicker {
@@ -6120,13 +6120,13 @@ header {
background: #f9f9f9; }
#dt_example .dataTable .sorting {
cursor: pointer;
- background: url(<%=asset_path "sorting.png" %>) no-repeat center right; }
+ background: url(sorting.png) no-repeat center right; }
#dt_example .dataTable .sorting_asc {
cursor: pointer;
- background: url(<%=asset_path "sorting_asc.png" %>) no-repeat center right; }
+ background: url(sorting_asc.png) no-repeat center right; }
#dt_example .dataTable .sorting_desc {
cursor: pointer;
- background: url(<%=asset_path "sorting_desc.png" %>) no-repeat center right; }
+ background: url(sorting_desc.png) no-repeat center right; }
/* Progress UI */
.progress-statistics li {
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index 53615f7..f2dbfc0 100755
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -34,7 +34,7 @@ def get_user
def update_user
user = User.find_by_id(params[:admin_id])
if user
- user.update_attributes(params[:user].reject { |k| k == ("password" || "password_confirmation") })
+ user.update(user_params.reject { |k| k == ("password" || "password_confirmation") })
pass = params[:user][:password]
user.password = pass if !(pass.blank?)
user.save!
@@ -68,4 +68,8 @@ def custom_fields
def admin_param
params[:admin_id] != "1"
end
+
+ def user_params
+ params.require(:user).permit!
+ end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index b99f51c..f2c1491 100755
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -8,6 +8,10 @@ class ApplicationController < ActionController::Base
# For APIs, you may want to use :null_session instead.
#protect_from_forgery with: :exception
+ # Update: this became default behaviour from Rails 5, so we need to
+ # disable it until we figure out how to implement properly:
+ skip_before_action :verify_authenticity_token
+
private
def mailer_options
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 203f116..3221cb4 100755
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -12,7 +12,7 @@ def create
path = params[:url].present? ? params[:url] : home_dashboard_index_path
begin
# Normalize the email address, why not
- user = User.authenticate(params[:email].to_s.downcase, params[:password])
+ user = User.authenticate(params[:email].to_s.strip.downcase, params[:password])
rescue RuntimeError => e
# don't do ANYTHING
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index cc04a07..e355ed6 100755
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -26,10 +26,11 @@ def account_settings
def update
message = false
- user = User.where("id = '#{params[:user][:id]}'")[0]
+ user = User.where("id = '#{user_params[:id]}'")[0]
+ # user = current_user
if user
- user.update_attributes(user_params_without_password)
+ user.update(user_params_without_password)
if params[:user][:password].present? && (params[:user][:password] == params[:user][:password_confirmation])
user.password = params[:user][:password]
end
diff --git a/app/views/dashboard/bar_graph.html.erb b/app/views/dashboard/bar_graph.html.erb
index ed8c550..b05cd8a 100644
--- a/app/views/dashboard/bar_graph.html.erb
+++ b/app/views/dashboard/bar_graph.html.erb
@@ -1,54 +1,46 @@
-
-
-
+
+
\ No newline at end of file
+ var chart = new google.visualization.ColumnChart(document.getElementById('column_chart'));
+ chart.draw(data, options);
+ }
+
diff --git a/app/views/dashboard/home.html.erb b/app/views/dashboard/home.html.erb
index 36e5d6b..e9d5a86 100644
--- a/app/views/dashboard/home.html.erb
+++ b/app/views/dashboard/home.html.erb
@@ -1,43 +1,38 @@
-
-
Need help using this portal? Check out the Readme
-
+
-
-
-
+
-
-
-
-
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 960c521..dc1d04c 100755
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -2,8 +2,8 @@
RailsGoat
- <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
- <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
+ <%= stylesheet_link_tag "application", media: "all" %>
+ <%= javascript_include_tag "application" %>
<%#= csrf_meta_tags %>
<%
diff --git a/app/views/paid_time_off/index.html.erb b/app/views/paid_time_off/index.html.erb
index 58b1e35..4cbb604 100644
--- a/app/views/paid_time_off/index.html.erb
+++ b/app/views/paid_time_off/index.html.erb
@@ -121,131 +121,124 @@
<%= javascript_include_tag "moment.min.js" %>
<%= javascript_include_tag "fullcalendar.min.js" %>
-
-$(document).ready(function() {
- $('#calendar').fullCalendar({
- events: <%= get_pto_schedule_schedule_index_path(:format => "json").inspect.html_safe %>,
+
diff --git a/app/views/performance/index.html.erb b/app/views/performance/index.html.erb
index 780b891..7eea4f0 100644
--- a/app/views/performance/index.html.erb
+++ b/app/views/performance/index.html.erb
@@ -48,79 +48,77 @@
-
+
\ No newline at end of file
+
diff --git a/bin/bundle b/bin/bundle
new file mode 100755
index 0000000..f19acf5
--- /dev/null
+++ b/bin/bundle
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
+load Gem.bin_path('bundler', 'bundle')
diff --git a/bin/rails b/bin/rails
new file mode 100755
index 0000000..6fb4e40
--- /dev/null
+++ b/bin/rails
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+APP_PATH = File.expand_path('../config/application', __dir__)
+require_relative "../config/boot"
+require "rails/commands"
diff --git a/bin/rake b/bin/rake
new file mode 100755
index 0000000..4fbf10b
--- /dev/null
+++ b/bin/rake
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+require_relative "../config/boot"
+require "rake"
+Rake.application.run
diff --git a/bin/setup b/bin/setup
new file mode 100755
index 0000000..8bfa480
--- /dev/null
+++ b/bin/setup
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+require "fileutils"
+
+# path to your application root.
+APP_ROOT = File.expand_path('..', __dir__)
+
+def system!(*args)
+ system(*args) || abort("\n== Command #{args} failed ==")
+end
+
+FileUtils.chdir APP_ROOT do
+ # This script is a way to set up or update your development environment automatically.
+ # This script is idempotent, so that you can run it at any time and get an expectable outcome.
+ # Add necessary setup steps to this file.
+
+ puts '== Installing dependencies =='
+ system! 'gem install bundler --conservative'
+ system('bundle check') || system!('bundle install')
+
+ # Install JavaScript dependencies
+ # system! 'bin/yarn'
+
+ # puts "\n== Copying sample files =="
+ # unless File.exist?('config/database.yml')
+ # FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
+ # end
+
+ puts "\n== Preparing database =="
+ system! 'bin/rails db:reset'
+
+ puts "\n== Removing old logs and tempfiles =="
+ system! 'bin/rails log:clear tmp:clear'
+
+ puts "\n== Restarting application server =="
+ system! 'bin/rails restart'
+end
diff --git a/bin/update b/bin/update
new file mode 100755
index 0000000..58bfaed
--- /dev/null
+++ b/bin/update
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+require 'fileutils'
+include FileUtils
+
+# path to your application root.
+APP_ROOT = File.expand_path('..', __dir__)
+
+def system!(*args)
+ system(*args) || abort("\n== Command #{args} failed ==")
+end
+
+chdir APP_ROOT do
+ # This script is a way to update your development environment automatically.
+ # Add necessary update steps to this file.
+
+ puts '== Installing dependencies =='
+ system! 'gem install bundler --conservative'
+ system('bundle check') || system!('bundle install')
+
+ # Install JavaScript dependencies if using Yarn
+ # system('bin/yarn')
+
+ puts "\n== Updating database =="
+ system! 'bin/rails db:migrate'
+
+ puts "\n== Removing old logs and tempfiles =="
+ system! 'bin/rails log:clear tmp:clear'
+
+ puts "\n== Restarting application server =="
+ system! 'bin/rails restart'
+end
diff --git a/bin/yarn b/bin/yarn
new file mode 100755
index 0000000..9fab2c3
--- /dev/null
+++ b/bin/yarn
@@ -0,0 +1,17 @@
+#!/usr/bin/env ruby
+APP_ROOT = File.expand_path('..', __dir__)
+Dir.chdir(APP_ROOT) do
+ yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
+ select { |dir| File.expand_path(dir) != __dir__ }.
+ product(["yarn", "yarn.cmd", "yarn.ps1"]).
+ map { |dir, file| File.expand_path(file, dir) }.
+ find { |file| File.executable?(file) }
+
+ if yarn
+ exec yarn, *ARGV
+ else
+ $stderr.puts "Yarn executable was not detected in the system."
+ $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
+ exit 1
+ end
+end
diff --git a/config.ru b/config.ru
index d10ffdd..4a3c09a 100755
--- a/config.ru
+++ b/config.ru
@@ -1,5 +1,6 @@
-# frozen_string_literal: true
# This file is used by Rack-based servers to start the application.
-require ::File.expand_path("../config/environment", __FILE__)
+require_relative "config/environment"
+
run Rails.application
+Rails.application.load_server
diff --git a/config/application.rb b/config/application.rb
index b27f634..d6135d6 100755
--- a/config/application.rb
+++ b/config/application.rb
@@ -1,59 +1,31 @@
-# frozen_string_literal: true
-require File.expand_path("../boot", __FILE__)
+require_relative "boot"
require "rails/all"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
-Bundler.require(:default, Rails.env)
+Bundler.require(*Rails.groups)
module Railsgoat
class Application < Rails::Application
- # Settings in config/environments/* take precedence over those specified here.
- # Application configuration should go into files in config/initializers
- # -- all .rb files in that directory are automatically loaded.
- # Custom directories with classes and modules you want to be autoloadable.
- # config.autoload_paths += %W(#{config.root}/extras)
+ # Initialize configuration defaults for originally generated Rails version.
+ config.load_defaults 5.2
- # Only load the plugins named here, in the order given (default is alphabetical).
- # :all can be used as a placeholder for all plugins not explicitly named.
- # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
+ # Configuration for the application, engines, and railties goes here.
+ # These settings can be overridden in specific environments using the files
+ # in config/environments, which are processed later.
- # Activate observers that should always be running.
- # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
+ #Â RAILSGOAT SPECIFC CONFIGURATION
+ # Disable changes to actve_record belongs_to which breaks associations in RailsGoat from 5 onwards
+ config.active_record.belongs_to_required_by_default = false
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
- # Run "rails -D time" for a list of tasks for finding time zone names. Default is UTC.
- # config.time_zone = 'Central Time (US & Canada)'
+ # Disable CSRF protection for RailsGoat
+ config.action_controller.per_form_csrf_tokens = false
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
- # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
- # config.i18n.default_locale = :de
+ config.action_dispatch.return_only_media_type_on_content_type = false
- # Configure the default encoding used in templates for Ruby 1.9.
- config.encoding = "utf-8"
-
- # Configure sensitive parameters which will be filtered from the log file.
- config.filter_parameters += [:password]
-
- # Enable escaping HTML in JSON.
- #config.active_support.escape_html_entities_in_json = true
-
- # 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,
- # like if you have constraints or database-specific column types
- # config.active_record.schema_format = :sql
-
- # Enable the asset pipeline
- config.assets.enabled = true
-
- # add app/assets/fonts to the asset path
- config.assets.paths << Rails.root.join("app", "assets", "fonts")
-
- # 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
+ # config.time_zone = "Central Time (US & Canada)"
+ # config.eager_load_paths << Rails.root.join("extras")
end
end
diff --git a/config/boot.rb b/config/boot.rb
index 5e28a74..3cda23b 100755
--- a/config/boot.rb
+++ b/config/boot.rb
@@ -1,5 +1,4 @@
-# frozen_string_literal: true
-# Set up gems listed in the Gemfile.
-ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
-require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
+require "bundler/setup" # Set up gems listed in the Gemfile.
+require "bootsnap/setup" # Speed up boot time by caching expensive operations.
diff --git a/config/cable.yml b/config/cable.yml
new file mode 100644
index 0000000..6879b93
--- /dev/null
+++ b/config/cable.yml
@@ -0,0 +1,10 @@
+development:
+ adapter: async
+
+test:
+ adapter: test
+
+production:
+ adapter: redis
+ url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
+ channel_prefix: railsgoat_production
diff --git a/config/contrast_security.yml b/config/contrast_security.yml
new file mode 100644
index 0000000..e5ad988
--- /dev/null
+++ b/config/contrast_security.yml
@@ -0,0 +1,44 @@
+# +-------------------------------------------------------------------------+
+# This Contrast Security configuration is Auto-generated by rake task.
+# To List all available rake task use 'rake -T'.
+#
+# Please enter valid api information, for the Ruby Agent to be able to
+# connect to Contrast UI. You can validate your config file by running:
+# 'bundle exec rake contrast:config:validate'
+#
+# To find your organization keys please follow this documentation:
+# https://docs.contrastsecurity.com/en/find-the-agent-keys.html
+# +-------------------------------------------------------------------------+
+
+# This contrast_security.yml file is intended to contain sensible defaults
+# for the application and can be overwritten by environment variables.
+
+# Contrast Security agent authentication keys
+# Either set the keys here or use environment variables
+# api:
+# url: https://eval.contrastsecurity.com
+# api_key: contrast_user
+# service_key: demo
+# user_name: demo
+
+# Application configuration including name
+application:
+ name: OWASP RailsGoat
+ code: demo-railsgoat
+
+# Server configuration including name and environment
+server:
+ name: railsgoat-docker
+ environment: development
+
+# Configure agent to log to rails log directory
+agent:
+ logger:
+ path: log/contrast_agent.log
+ level: WARN
+ security_logger:
+ path: log/security.log
+ level: WARN
+
+# For more information visit the full Ruby agent configuration guide:
+# https://docs.contrastsecurity.com/en/ruby-configuration.html
diff --git a/config/environment.rb b/config/environment.rb
index 0effbcf..cac5315 100755
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -1,6 +1,5 @@
-# frozen_string_literal: true
# Load the Rails application.
-require File.expand_path("../application", __FILE__)
+require_relative "application"
# Initialize the Rails application.
-Railsgoat::Application.initialize!
+Rails.application.initialize!
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 5196727..7a9f6c3 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -1,51 +1,76 @@
-# frozen_string_literal: true
-Railsgoat::Application.configure do
- # Settings specified here will take precedence over those in config/application.rb
+require "active_support/core_ext/integer/time"
- # In the development environment your application's code is reloaded on
- # every request. This slows down response time but is perfect for development
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # In the development environment your application's code is reloaded any time
+ # it changes. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
- # Show full error reports and disable caching
- config.consider_all_requests_local = true
- config.action_controller.perform_caching = false
+ # Do not eager load code on boot.
+ config.eager_load = false
+
+ # Show full error reports.
+ config.consider_all_requests_local = true
+
+ # Enable/disable caching. By default caching is disabled.
+ # Run rails dev:cache to toggle caching.
+ if Rails.root.join('tmp', 'caching-dev.txt').exist?
+ config.action_controller.perform_caching = true
+ config.action_controller.enable_fragment_cache_logging = true
+
+ config.cache_store = :memory_store
+ config.public_file_server.headers = {
+ 'Cache-Control' => "public, max-age=#{2.days.to_i}"
+ }
+ else
+ config.action_controller.perform_caching = false
+
+ config.cache_store = :null_store
+ end
+
+ # Store uploaded files on the local file system (see config/storage.yml for options).
+ config.active_storage.service = :local
- # Don't care if the mailer can't send
+ # Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
- # Print deprecation notices to the Rails logger
+ config.action_mailer.perform_caching = false
+
+ # Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
- # Only use best-standards-support built into browsers
- config.action_dispatch.best_standards_support = :builtin
+ # Raise exceptions for disallowed deprecations.
+ config.active_support.disallowed_deprecation = :raise
+
+ # Tell Active Support which deprecation messages to disallow.
+ config.active_support.disallowed_deprecation_warnings = []
- # Tired of caching causing issues
- config.middleware.delete Rack::ETag
+ # Raise an error on page load if there are pending migrations.
+ config.active_record.migration_error = :page_load
- # Do not compress assets
- config.assets.compress = false
+ # Highlight code that triggered database queries in logs.
+ config.active_record.verbose_query_logs = true
- # Expands the lines which load the assets
+ # Debug mode disables concatenation and preprocessing of assets.
+ # This option may cause significant delays in view rendering with a large
+ # number of complex assets.
config.assets.debug = true
- # ActionMailer settings for email support
- config.action_mailer.delivery_method = :smtp
- config.action_mailer.smtp_settings = { address: "127.0.0.1", port: 1025 }
- config.action_mailer.default_url_options = { host: "127.0.0.1:3000" }
-
- # config.middleware.insert_before(
- # Rack::Lock, Rack::LiveReload,
- # :min_delay => 500,
- # :max_delay => 1000,
- # :port => 35727,
- # :host => 'railsgoat.dev',
- # :ignore => [ %r{dont/modify\.html$} ]
- # )
-
- # For Rails 4.0+
- # Do not eager load code on boot. This avoids loading your whole application
- # just for the purpose of running a single test. If you are using a tool that
- # preloads Rails for running tests, you may have to set it to true.
- config.eager_load = false
+ # Suppress logger output for asset requests.
+ config.assets.quiet = true
+
+ # Raises error for missing translations.
+ # config.i18n.raise_on_missing_translations = true
+
+ # Annotate rendered view with file names.
+ # config.action_view.annotate_rendered_view_with_filenames = true
+
+ # Use an evented file watcher to asynchronously detect changes in source code,
+ # routes, locales, etc. This feature depends on the listen gem.
+ config.file_watcher = ActiveSupport::EventedFileUpdateChecker
+
+ # Uncomment if you wish to allow Action Cable access from any origin.
+ # config.action_cable.disable_request_forgery_protection = true
end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index d61091e..2336e27 100755
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -1,109 +1,120 @@
-# frozen_string_literal: true
-Railsgoat::Application.configure do
- # Settings specified here will take precedence over those in config/application.rb
+require "active_support/core_ext/integer/time"
+
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
+ # Eager load code on boot. This eager loads most of Rails and
+ # your application in memory, allowing both threaded web servers
+ # and those relying on copy on write to perform better.
+ # Rake tasks automatically ignore this option for performance.
+ config.eager_load = true
+
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
- # Enable Rack::Cache to put a simple HTTP cache in front of your application
- # Add `rack-cache` to your Gemfile before enabling this.
- # For large-scale production use, consider using a caching
- # reverse proxy like nginx, varnish or squid.
- # config.action_dispatch.rack_cache = true
+ # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
+ # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
+ # config.require_master_key = true
- # Disable Rails's static asset server (Apache or nginx will already do this).
- config.public_file_server.enabled = false
+ # Disable serving static files from the `/public` folder by default since
+ # Apache or NGINX already handles this.
+ config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
- # Compress JavaScripts and CSS
- config.assets.compress = true
-
- # Compress JavaScripts and CSS.
- config.assets.js_compressor = :uglifier
+ # Compress CSS using a preprocessor.
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
- config.assets.compile = true # default is false
+ config.assets.compile = false
- # Generate digests for assets URLs.
- config.assets.digest = true
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server.
+ # config.asset_host = 'http://assets.example.com'
- # For Rails 4.0+: Version of your assets, change this if you want to expire all your assets.
- config.assets.version = "1.0"
+ # Specifies the header that your server uses for sending files.
+ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
- # Defaults to nil and saved in location specified by config.assets.prefix
- # config.assets.manifest = YOUR_PATH
+ # Store uploaded files on the local file system (see config/storage.yml for options).
+ config.active_storage.service = :local
- # Specifies the header that your server uses for sending files.
- # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
- # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
+ # Mount Action Cable outside main process or domain.
+ # config.action_cable.mount_path = nil
+ # config.action_cable.url = 'wss://example.com/cable'
+ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
- # Set to :debug to see everything in the log.
+ # Include generic and useful information about system operation, but avoid logging too much
+ # information to avoid inadvertent exposure of personally identifiable information (PII).
config.log_level = :info
- # Prepend all log lines with the following tags
- # config.log_tags = [ :subdomain, :uuid ]
-
- # Use a different logger for distributed setups
- # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
+ # Prepend all log lines with the following tags.
+ config.log_tags = [ :request_id ]
- # Use a different cache store in production
+ # Use a different cache store in production.
# config.cache_store = :mem_cache_store
- # Enable serving of images, stylesheets, and JavaScripts from an asset server
- # config.action_controller.asset_host = "http://assets.example.com"
+ # Use a real queuing backend for Active Job (and separate queues per environment).
+ # config.active_job.queue_adapter = :resque
+ # config.active_job.queue_name_prefix = "railsgoat_production"
- # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
- # config.assets.precompile += %w( search.js )
+ config.action_mailer.perform_caching = false
- # Disable delivery errors, bad email addresses will be ignored
+ # Ignore bad email addresses and do not raise email delivery errors.
+ # Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
- # Enable threaded mode
- # config.threadsafe!
-
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
- # the I18n.default_locale when a translation can not be found).
- config.i18n.fallbacks = [I18n.default_locale]
+ # the I18n.default_locale when a translation cannot be found).
+ config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
- # For Rails 4.0+: Eager load code on boot. This eager loads most of
- # Rails and your application in memory, allowing both thread web
- # servers and those relying on copy on write to perform better.
- # Rake tasks automatically ignore this option for performance.
- config.eager_load = true
-
- # For Rails 4.0+: Use default logging formatter so that PID and timestamp are not suppressed.
- config.log_formatter = ::Logger::Formatter.new
+ # Log disallowed deprecations.
+ config.active_support.disallowed_deprecation = :log
- # For Rails 4.0+: Disable automatic flushing of the log to improve performance.
- # config.autoflush_log = false
+ # Tell Active Support which deprecation messages to disallow.
+ config.active_support.disallowed_deprecation_warnings = []
- # Prepend all log lines with the following tags.
- # config.log_tags = [ :subdomain, :uuid ]
+ # Use default logging formatter so that PID and timestamp are not suppressed.
+ config.log_formatter = ::Logger::Formatter.new
# Use a different logger for distributed setups.
- # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
-
- # Use a different cache store in production.
- # config.cache_store = :mem_cache_store
-
- # Enable serving of images, stylesheets, and JavaScripts from an asset server.
- # config.action_controller.asset_host = "http://assets.example.com"
-
- # Precompile additional assets.
- # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
- # config.assets.precompile += %w( search.js )
-
- # Ignore bad email addresses and do not raise email delivery errors.
- # Set this to true and configure the email server for immediate delivery to raise delivery errors.
- # config.action_mailer.raise_delivery_errors = false
+ # require "syslog/logger"
+ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
+
+ if ENV["RAILS_LOG_TO_STDOUT"].present?
+ logger = ActiveSupport::Logger.new(STDOUT)
+ logger.formatter = config.log_formatter
+ config.logger = ActiveSupport::TaggedLogging.new(logger)
+ end
+
+ # Do not dump schema after migrations.
+ config.active_record.dump_schema_after_migration = false
+
+ # Inserts middleware to perform automatic connection switching.
+ # The `database_selector` hash is used to pass options to the DatabaseSelector
+ # middleware. The `delay` is used to determine how long to wait after a write
+ # to send a subsequent read to the primary.
+ #
+ # The `database_resolver` class is used by the middleware to determine which
+ # database is appropriate to use based on the time delay.
+ #
+ # The `database_resolver_context` class is used by the middleware to set
+ # timestamps for the last write to the primary. The resolver uses the context
+ # class timestamps to determine how long to wait before reading from the
+ # replica.
+ #
+ # By default Rails will store a last write timestamp in the session. The
+ # DatabaseSelector middleware is designed as such you can define your own
+ # strategy for connection switching and pass that into the middleware through
+ # these configuration options.
+ # config.active_record.database_selector = { delay: 2.seconds }
+ # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
+ # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end
diff --git a/config/environments/test.rb b/config/environments/test.rb
index efc1521..17ce39c 100755
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -1,26 +1,41 @@
-# frozen_string_literal: true
-Railsgoat::Application.configure do
- # Settings specified here will take precedence over those in config/application.rb
-
- # The test environment is used exclusively to run your application's
- # test suite. You never need to work with it otherwise. Remember that
- # your test database is "scratch space" for the test suite and is wiped
- # and recreated between test runs. Don't rely on the data there!
+require "active_support/core_ext/integer/time"
+
+# The test environment is used exclusively to run your application's
+# test suite. You never need to work with it otherwise. Remember that
+# your test database is "scratch space" for the test suite and is wiped
+# and recreated between test runs. Don't rely on the data there!
+
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
config.cache_classes = true
- # Configure static asset server for tests with Cache-Control for performance.
+ # Do not eager load code on boot. This avoids loading your whole application
+ # just for the purpose of running a single test. If you are using a tool that
+ # preloads Rails for running tests, you may have to set it to true.
+ config.eager_load = false
+
+ # Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
- config.public_file_server.headers = { "Cache-Control" => "public, max-age=3600" }
+ config.public_file_server.headers = {
+ 'Cache-Control' => "public, max-age=#{1.hour.to_i}"
+ }
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
+ config.cache_store = :null_store
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
- # Disable request forgery protection in test environment
- config.action_controller.allow_forgery_protection = true
+ # Disable request forgery protection in test environment.
+ config.action_controller.allow_forgery_protection = false
+
+ # Store uploaded files on the local file system in a temporary directory.
+ config.active_storage.service = :test
+
+ config.action_mailer.perform_caching = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
@@ -30,9 +45,15 @@
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
- # For Rails 4.0+
- # Do not eager load code on boot. This avoids loading your whole application
- # just for the purpose of running a single test. If you are using a tool that
- # preloads Rails for running tests, you may have to set it to true.
- config.eager_load = false
+ # Raise exceptions for disallowed deprecations.
+ config.active_support.disallowed_deprecation = :raise
+
+ # Tell Active Support which deprecation messages to disallow.
+ config.active_support.disallowed_deprecation_warnings = []
+
+ # Raises error for missing translations.
+ # config.i18n.raise_on_missing_translations = true
+
+ # Annotate rendered view with file names.
+ # config.action_view.annotate_rendered_view_with_filenames = true
end
diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb
new file mode 100644
index 0000000..89d2efa
--- /dev/null
+++ b/config/initializers/application_controller_renderer.rb
@@ -0,0 +1,8 @@
+# Be sure to restart your server when you modify this file.
+
+# ActiveSupport::Reloader.to_prepare do
+# ApplicationController.renderer.defaults.merge!(
+# http_host: 'example.org',
+# https: false
+# )
+# end
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index 891ade3..6bd831d 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -1,2 +1,14 @@
-# frozen_string_literal: true
-Rails.application.config.assets.precompile += %w( validation.js jquery.dataTables.min.js fullcalendar.min.js moment.min.js )
+# Be sure to restart your server when you modify this file.
+
+# Version of your assets, change this if you want to expire all your assets.
+Rails.application.config.assets.version = '1.0'
+
+# Add additional assets to the asset load path.
+# Rails.application.config.assets.paths << Emoji.images_path
+# Add Yarn node_modules folder to the asset load path.
+Rails.application.config.assets.paths << Rails.root.join("app", "assets", "fonts", "node_modules")
+
+# Precompile additional assets.
+# application.js, application.css, and all non-JS/CSS in the app/assets
+# folder are already added.
+Rails.application.config.assets.precompile += %w( fullcalendar.min.js )
diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb
index d0f0d3b..33699c3 100755
--- a/config/initializers/backtrace_silencers.rb
+++ b/config/initializers/backtrace_silencers.rb
@@ -1,8 +1,8 @@
-# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
-# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) }
-# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
-# Rails.backtrace_cleaner.remove_silencers!
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
+# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
+Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"]
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
new file mode 100644
index 0000000..35d0f26
--- /dev/null
+++ b/config/initializers/content_security_policy.rb
@@ -0,0 +1,30 @@
+# Be sure to restart your server when you modify this file.
+
+# Define an application-wide content security policy
+# For further information see the following documentation
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
+
+# Rails.application.config.content_security_policy do |policy|
+# policy.default_src :self, :https
+# policy.font_src :self, :https, :data
+# policy.img_src :self, :https, :data
+# policy.object_src :none
+# policy.script_src :self, :https
+# policy.style_src :self, :https
+# # If you are using webpack-dev-server then specify webpack-dev-server host
+# policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
+
+# # Specify URI for violation reports
+# # policy.report_uri "/csp-violation-report-endpoint"
+# end
+
+# If you are using UJS then enable automatic nonce generation
+# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
+
+# Set the nonce only to specific directives
+# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
+
+# Report CSP violations to a specified URI
+# For further information see the following documentation:
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
+# Rails.application.config.content_security_policy_report_only = true
diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb
new file mode 100644
index 0000000..f51a497
--- /dev/null
+++ b/config/initializers/cookies_serializer.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file.
+
+# Specify a serializer for the signed and encrypted cookie jars.
+# Valid options are :json, :marshal, and :hybrid.
+Rails.application.config.action_dispatch.cookies_serializer = :hybrid
diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb
index b7fe123..4b34a03 100644
--- a/config/initializers/filter_parameter_logging.rb
+++ b/config/initializers/filter_parameter_logging.rb
@@ -1,5 +1,6 @@
-# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Configure sensitive parameters which will be filtered from the log file.
-Rails.application.config.filter_parameters += [:password]
+Rails.application.config.filter_parameters += [
+ :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
+]
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
index aa7435f..ac033bf 100755
--- a/config/initializers/inflections.rb
+++ b/config/initializers/inflections.rb
@@ -1,4 +1,3 @@
-# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format. Inflections
diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb
index f75864f..dc18996 100755
--- a/config/initializers/mime_types.rb
+++ b/config/initializers/mime_types.rb
@@ -1,6 +1,4 @@
-# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
-# Mime::Type.register_alias "text/html", :iphone
diff --git a/config/initializers/new_framework_defaults_5_2.rb b/config/initializers/new_framework_defaults_5_2.rb
new file mode 100644
index 0000000..c383d07
--- /dev/null
+++ b/config/initializers/new_framework_defaults_5_2.rb
@@ -0,0 +1,38 @@
+# Be sure to restart your server when you modify this file.
+#
+# This file contains migration options to ease your Rails 5.2 upgrade.
+#
+# Once upgraded flip defaults one by one to migrate to the new default.
+#
+# Read the Guide for Upgrading Ruby on Rails for more info on each option.
+
+# Make Active Record use stable #cache_key alongside new #cache_version method.
+# This is needed for recyclable cache keys.
+# Rails.application.config.active_record.cache_versioning = true
+
+# Use AES-256-GCM authenticated encryption for encrypted cookies.
+# Also, embed cookie expiry in signed or encrypted cookies for increased security.
+#
+# This option is not backwards compatible with earlier Rails versions.
+# It's best enabled when your entire app is migrated and stable on 5.2.
+#
+# Existing cookies will be converted on read then written with the new scheme.
+# Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = true
+
+# Use AES-256-GCM authenticated encryption as default cipher for encrypting messages
+# instead of AES-256-CBC, when use_authenticated_message_encryption is set to true.
+# Rails.application.config.active_support.use_authenticated_message_encryption = true
+
+# Add default protection from forgery to ActionController::Base instead of in
+# ApplicationController.
+# Rails.application.config.action_controller.default_protect_from_forgery = true
+
+# Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and
+# 'f' after migrating old data.
+# Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
+
+# Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header.
+# Rails.application.config.active_support.use_sha1_digests = true
+
+# Make `form_with` generate id attributes for any generated HTML tags.
+# Rails.application.config.action_view.form_with_generates_ids = true
diff --git a/config/initializers/new_framework_defaults_6_1.rb b/config/initializers/new_framework_defaults_6_1.rb
new file mode 100644
index 0000000..9526b83
--- /dev/null
+++ b/config/initializers/new_framework_defaults_6_1.rb
@@ -0,0 +1,67 @@
+# Be sure to restart your server when you modify this file.
+#
+# This file contains migration options to ease your Rails 6.1 upgrade.
+#
+# Once upgraded flip defaults one by one to migrate to the new default.
+#
+# Read the Guide for Upgrading Ruby on Rails for more info on each option.
+
+# Support for inversing belongs_to -> has_many Active Record associations.
+# Rails.application.config.active_record.has_many_inversing = true
+
+# Track Active Storage variants in the database.
+# Rails.application.config.active_storage.track_variants = true
+
+# Apply random variation to the delay when retrying failed jobs.
+# Rails.application.config.active_job.retry_jitter = 0.15
+
+# Stop executing `after_enqueue`/`after_perform` callbacks if
+# `before_enqueue`/`before_perform` respectively halts with `throw :abort`.
+# Rails.application.config.active_job.skip_after_callbacks_if_terminated = true
+
+# Specify cookies SameSite protection level: either :none, :lax, or :strict.
+#
+# This change is not backwards compatible with earlier Rails versions.
+# It's best enabled when your entire app is migrated and stable on 6.1.
+# Rails.application.config.action_dispatch.cookies_same_site_protection = :lax
+
+# Generate CSRF tokens that are encoded in URL-safe Base64.
+#
+# This change is not backwards compatible with earlier Rails versions.
+# It's best enabled when your entire app is migrated and stable on 6.1.
+# Rails.application.config.action_controller.urlsafe_csrf_tokens = true
+
+# Specify whether `ActiveSupport::TimeZone.utc_to_local` returns a time with an
+# UTC offset or a UTC time.
+# ActiveSupport.utc_to_local_returns_utc_offset_times = true
+
+# Change the default HTTP status code to `308` when redirecting non-GET/HEAD
+# requests to HTTPS in `ActionDispatch::SSL` middleware.
+# Rails.application.config.action_dispatch.ssl_default_redirect_status = 308
+
+# Use new connection handling API. For most applications this won't have any
+# effect. For applications using multiple databases, this new API provides
+# support for granular connection swapping.
+# Rails.application.config.active_record.legacy_connection_handling = false
+
+# Make `form_with` generate non-remote forms by default.
+# Rails.application.config.action_view.form_with_generates_remote_forms = false
+
+# Set the default queue name for the analysis job to the queue adapter default.
+# Rails.application.config.active_storage.queues.analysis = nil
+
+# Set the default queue name for the purge job to the queue adapter default.
+# Rails.application.config.active_storage.queues.purge = nil
+
+# Set the default queue name for the incineration job to the queue adapter default.
+# Rails.application.config.action_mailbox.queues.incineration = nil
+
+# Set the default queue name for the routing job to the queue adapter default.
+# Rails.application.config.action_mailbox.queues.routing = nil
+
+# Set the default queue name for the mail deliver job to the queue adapter default.
+# Rails.application.config.action_mailer.deliver_later_queue_name = nil
+
+# Generate a `Link` header that gives a hint to modern browsers about
+# preloading assets when using `javascript_include_tag` and `stylesheet_link_tag`.
+# Rails.application.config.action_view.preload_links_header = true
diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb
new file mode 100644
index 0000000..00f64d7
--- /dev/null
+++ b/config/initializers/permissions_policy.rb
@@ -0,0 +1,11 @@
+# Define an application-wide HTTP permissions policy. For further
+# information see https://developers.google.com/web/updates/2018/06/feature-policy
+#
+# Rails.application.config.permissions_policy do |f|
+# f.camera :none
+# f.gyroscope :none
+# f.microphone :none
+# f.usb :none
+# f.fullscreen :self
+# f.payment :self, "https://secure.example.com"
+# end
diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb
index 6780279..bbfc396 100755
--- a/config/initializers/wrap_parameters.rb
+++ b/config/initializers/wrap_parameters.rb
@@ -1,15 +1,14 @@
-# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
-#
+
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
- wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
+ wrap_parameters format: [:json]
end
-# Disable root element in JSON by default.
-ActiveSupport.on_load(:active_record) do
- self.include_root_in_json = false
-end
+# To enable root element in JSON for ActiveRecord objects.
+# ActiveSupport.on_load(:active_record) do
+# self.include_root_in_json = true
+# end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0653957..cf9b342 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -16,8 +16,18 @@
#
# This would use the information in config/locales/es.yml.
#
+# The following keys must be escaped otherwise they will not be retrieved by
+# the default I18n backend:
+#
+# true, false, on, off, yes, no
+#
+# Instead, surround them with single quotes.
+#
+# en:
+# 'true': 'foo'
+#
# To learn more, please read the Rails Internationalization guide
-# available at http://guides.rubyonrails.org/i18n.html.
+# available at https://guides.rubyonrails.org/i18n.html.
en:
hello: "Hello world"
diff --git a/config/puma.rb b/config/puma.rb
new file mode 100644
index 0000000..d9b3e83
--- /dev/null
+++ b/config/puma.rb
@@ -0,0 +1,43 @@
+# Puma can serve each request in a thread from an internal thread pool.
+# The `threads` method setting takes two numbers: a minimum and maximum.
+# Any libraries that use thread pools should be configured to match
+# the maximum value specified for Puma. Default is set to 5 threads for minimum
+# and maximum; this matches the default thread size of Active Record.
+#
+max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
+min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
+threads min_threads_count, max_threads_count
+
+# Specifies the `worker_timeout` threshold that Puma will use to wait before
+# terminating a worker in development environments.
+#
+worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
+
+# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
+#
+port ENV.fetch("PORT") { 3000 }
+
+# Specifies the `environment` that Puma will run in.
+#
+environment ENV.fetch("RAILS_ENV") { "development" }
+
+# Specifies the `pidfile` that Puma will use.
+pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
+
+# Specifies the number of `workers` to boot in clustered mode.
+# Workers are forked web server processes. If using threads and workers together
+# the concurrency of the application would be max `threads` * `workers`.
+# Workers do not work on JRuby or Windows (both of which do not support
+# processes).
+#
+# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
+
+# Use the `preload_app!` method when specifying a `workers` number.
+# This directive tells Puma to first boot the application and load code
+# before forking the application. This takes advantage of Copy On Write
+# process behavior so workers use less memory.
+#
+# preload_app!
+
+# Allow puma to be restarted by `rails restart` command.
+plugin :tmp_restart
diff --git a/config/secrets.yml b/config/secrets.yml
new file mode 100644
index 0000000..4d1e3c3
--- /dev/null
+++ b/config/secrets.yml
@@ -0,0 +1,32 @@
+# Be sure to restart your server when you modify this file.
+
+# Your secret key is used for verifying the integrity of signed cookies.
+# If you change this key, all old signed cookies will become invalid!
+
+# Make sure the secret is at least 30 characters and all random,
+# no regular words or you'll be exposed to dictionary attacks.
+# You can use `rails secret` to generate a secure secret key.
+
+# Make sure the secrets in this file are kept private
+# if you're sharing your code publicly.
+
+# Shared secrets are available across all environments.
+
+# shared:
+# api_key: a1B2c3D4e5F6
+
+# Environmental secrets are only available for that specific environment.
+
+development:
+ secret_key_base: 04c89de21cba0e495aa6dbef4b65fb217438966206fdd7f6f81ce745bc61cc70cb72553a7e3be2c7d8ad550cf664bdfde571ec04e06ce7396750f79e38216e04
+
+test:
+ secret_key_base: da8b0abe0daef4b2b62bf2eb0900cc0241286a4dc92fac4eca1a46eb8156da7cd78bf4155435f23f4e7d477fc6714f4d9b1d449c05f5890bee1ca4f7d0fad069
+
+# Do not keep production secrets in the unencrypted secrets file.
+# Instead, either read values from the environment.
+# Or, use `bin/rails secrets:setup` to configure encrypted secrets
+# and move the `production:` environment over there.
+
+production:
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
diff --git a/config/spring.rb b/config/spring.rb
new file mode 100644
index 0000000..c9119b4
--- /dev/null
+++ b/config/spring.rb
@@ -0,0 +1,6 @@
+%w(
+ .ruby-version
+ .rbenv-vars
+ tmp/restart.txt
+ tmp/caching-dev.txt
+).each { |path| Spring.watch(path) }
diff --git a/config/storage.yml b/config/storage.yml
new file mode 100644
index 0000000..d32f76e
--- /dev/null
+++ b/config/storage.yml
@@ -0,0 +1,34 @@
+test:
+ service: Disk
+ root: <%= Rails.root.join("tmp/storage") %>
+
+local:
+ service: Disk
+ root: <%= Rails.root.join("storage") %>
+
+# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
+# amazon:
+# service: S3
+# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
+# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
+# region: us-east-1
+# bucket: your_own_bucket
+
+# Remember not to checkin your GCS keyfile to a repository
+# google:
+# service: GCS
+# project: your_project
+# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
+# bucket: your_own_bucket
+
+# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
+# microsoft:
+# service: AzureStorage
+# storage_account_name: your_account_name
+# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
+# container: your_container_name
+
+# mirror:
+# service: Mirror
+# primary: local
+# mirrors: [ amazon, google, microsoft ]
diff --git a/db/migrate/20230801225421_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20230801225421_add_service_name_to_active_storage_blobs.active_storage.rb
new file mode 100644
index 0000000..a15c6ce
--- /dev/null
+++ b/db/migrate/20230801225421_add_service_name_to_active_storage_blobs.active_storage.rb
@@ -0,0 +1,22 @@
+# This migration comes from active_storage (originally 20190112182829)
+class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]
+ def up
+ return unless table_exists?(:active_storage_blobs)
+
+ unless column_exists?(:active_storage_blobs, :service_name)
+ add_column :active_storage_blobs, :service_name, :string
+
+ if configured_service = ActiveStorage::Blob.service.name
+ ActiveStorage::Blob.unscoped.update_all(service_name: configured_service)
+ end
+
+ change_column :active_storage_blobs, :service_name, :string, null: false
+ end
+ end
+
+ def down
+ return unless table_exists?(:active_storage_blobs)
+
+ remove_column :active_storage_blobs, :service_name
+ end
+end
diff --git a/db/migrate/20230801225422_create_active_storage_variant_records.active_storage.rb b/db/migrate/20230801225422_create_active_storage_variant_records.active_storage.rb
new file mode 100644
index 0000000..94ac83a
--- /dev/null
+++ b/db/migrate/20230801225422_create_active_storage_variant_records.active_storage.rb
@@ -0,0 +1,27 @@
+# This migration comes from active_storage (originally 20191206030411)
+class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
+ def change
+ return unless table_exists?(:active_storage_blobs)
+
+ # Use Active Record's configured type for primary key
+ create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t|
+ t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type
+ t.string :variation_digest, null: false
+
+ t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true
+ t.foreign_key :active_storage_blobs, column: :blob_id
+ end
+ end
+
+ private
+ def primary_key_type
+ config = Rails.configuration.generators
+ config.options[config.orm][:primary_key_type] || :primary_key
+ end
+
+ def blobs_primary_key_type
+ pkey_name = connection.primary_key(:active_storage_blobs)
+ pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name }
+ pkey_column.bigint? ? :bigint : pkey_column.type
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index e9d5e1e..7e82135 100755
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1,17 +1,16 @@
-# frozen_string_literal: true
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
-# Note that this schema.rb definition is the authoritative source for your
-# database schema. If you need to create the application database on another
-# system, you should be using db:schema:load, not running all the migrations
-# from scratch. The latter is a flawed and unsustainable approach (the more migrations
-# you'll amass, the slower it'll run and the greater likelihood for issues).
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20171007010129) do
+ActiveRecord::Schema.define(version: 2023_08_01_225422) do
create_table "analytics", force: :cascade do |t|
t.string "ip_address"
diff --git a/db/seeds.rb b/db/seeds.rb
index 338f956..24cd8fa 100755
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -162,6 +162,14 @@
]
work_info = [
+ {
+ user: "admin@metacorp.com",
+ income: "$200,000",
+ bonuses: "$50,000",
+ years_worked: 9,
+ SSN: "111-11-111",
+ DoB: "02-02-1990"
+ },
{
user: "jack@metacorp.com",
income: "$50,000",
diff --git a/doc/README_FOR_APP b/doc/README_FOR_APP
deleted file mode 100755
index 2c9ee3e..0000000
--- a/doc/README_FOR_APP
+++ /dev/null
@@ -1,2 +0,0 @@
-Use this README file to introduce your application and point to useful places in the API for learning more.
-Run "rails doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..c0927b0
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,30 @@
+services:
+ railsgoat-dev:
+ image: contrastsecuritydemo/railsgoat:6.1.7
+ build:
+ context: .
+ dockerfile: Dockerfile
+ target: runner
+ container_name: railsgoat-dev
+ ports:
+ - "3000:3000"
+ env_file:
+ - .env
+ volumes:
+ - .:/app
+
+ railsgoat-prod:
+ image: contrastsecuritydemo/railsgoat:6.1.7
+ build:
+ context: .
+ dockerfile: Dockerfile
+ target: runner
+ container_name: railsgoat-prod
+ ports:
+ - 3001:3000
+ env_file:
+ - .env
+ environment:
+ CONTRAST__SERVER__NAME: RailsGoat-Prod-TM
+ CONTRAST__SERVER__ENVIRONMENT: production
+ # TEST: True
diff --git a/docs/CONTRAST.md b/docs/CONTRAST.md
new file mode 100644
index 0000000..bf8ec95
--- /dev/null
+++ b/docs/CONTRAST.md
@@ -0,0 +1,14 @@
+# Contrast specific changes
+Documentation of the changes made to RailsGoat to add Contrast Security to the project.
+
+## Changelog to add Contrast to this project
+* `contrast_security.yaml` configuration file added to the `config/` directory
+* `.env` configuration file added to the root directory
+* `gem 'contrast-agent'` added to the `Gemfile`
+
+## Other changes to RailsGoat (Not required for Contrast)
+* Upgraded to Ruby `3.1.4`
+* Upgraded to Rails `6.1.7`
+* Improved the `Dockerfile` to use a multi-stage build and Alpine Linux
+* Updated the `docker-compose` file to start two services: `dev` and `prod`
+* Fixed issues with loading javascript and rendering graphs on multiple pages
diff --git a/docs/DEPLOY_TO_AZURE.md b/docs/DEPLOY_TO_AZURE.md
new file mode 100644
index 0000000..bae11c1
--- /dev/null
+++ b/docs/DEPLOY_TO_AZURE.md
@@ -0,0 +1,14 @@
+# Running in Azure (Azure App Service):
+
+## Pre-Requisites
+
+1. Place a `contrast_security.yaml` file into the application's root folder.
+1. Install Terraform from here: https://www.terraform.io/downloads.html.
+1. Install PyYAML using `pip install PyYAML`.
+1. Install the Azure cli tools using `brew update && brew install azure-cli`.
+1. Log into Azure to make sure you cache your credentials using `az login`.
+1. Edit the [variables.tf](variables.tf) file (or add a terraform.tfvars) to add your initials, preferred Azure location, app name, server name and environment.
+1. Run `terraform init` to download the required plugins.
+1. Run `terraform plan` and check the output for errors.
+1. Run `terraform apply` to build the infrastructure that you need in Azure, this will output the web address for the application.
+1. Run `terraform destroy` when you would like to stop the app service and release the resources.
diff --git a/docs/UPGRADE_RAILSGOAT.md b/docs/UPGRADE_RAILSGOAT.md
new file mode 100644
index 0000000..ed53a59
--- /dev/null
+++ b/docs/UPGRADE_RAILSGOAT.md
@@ -0,0 +1,94 @@
+# Upgrading Rails and Ruby versions for RailsGoat
+This guide is intended for Contrast maintainers who are upgrading the version of Ruby and/or Rails used by RailsGoat.
+
+## Why Upgrade?
+We will need to keep the version of RailsGoat within the versions supported by Ruby on Rails **and** the Contrast Ruby Agent for this demo app to remain operational. We may also want to take advantage of new features and performance enhancements offered by the latest versions of the Contrast Ruby Agent.
+
+* See the [Ruby Maintenance Branches](https://www.ruby-lang.org/en/downloads/branches/) schedule for specific release dates.
+* See the [Contrast Ruby Agent Supported Technologies](https://docs.contrastsecurity.com/en/ruby-supported-technologies.html) for the currently supported versions of Ruby and Rails.
+
+## How to upgrade RailsGoat
+Upgrading the version of Ruby, Rails or Bundler that this app uses should be done using the provided Dockerfile, as this will provide the most repeatable results.
+
+Follow the [Upgrading Ruby on Rails](https://guides.rubyonrails.org/upgrading_ruby_on_rails.html) guide from the official documentation. Read through this guide first if you are not familiar.
+
+**General tips for a successful upgrade:**
+* Upgrade Ruby and Rails separately, building the Dockerfile and dealing with any issues, bugs, or deprecation warnings as you go.
+* Run the rspec tests in between each build to ensure that no functionality is broken.
+* Ruby can be upgraded one major version at a time (first jump to the last minor version of your current version, test, and then continue the upgrade to the next major version)
+* Don't upgrade Ruby past the [last ruby version supported by your current version of rails](https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html).
+* Rails needs to be updated **one minor version at a time** (version format: `major.minor.patch`). This is to make running `rails app:update` command easier, which will attempt to apply the changes required to your codebase.
+* When running `rails app:update`, you will be prompted to overwrite files. Please view the diffs of these changes and test the changes before committing.
+
+### Upgrading Ruby
+First upgrade the Ruby version to your target Ruby version in the Dockerfile, the Gemfile and the .ruby-version files.
+
+Dockerfile:
+```Dockerfile
+...
+# Default Ruby version for this project.
+ARG RUBY_VERSION=3.1.4 <---
+
+# Base Alpine Ruby image for common setup
+FROM ruby:$RUBY_VERSION-alpine as base
+...
+```
+
+Gemfile:
+```Gemfile
+...
+# frozen_string_literal: true
+source "https://rubygems.org"
+
+gem "rails", "5.2.8"
+
+ruby "2.7.7" <---
+...
+```
+
+Now rebuild the container,test the app and make sure the gems are fully up to date:
+```bash
+docker compose up --build
+docker compose exec web sh
+> bundle update
+> bundle install
+```
+
+### Upgrading Rails
+Now that you have upgraded Ruby, you can upgrade Rails. Change the version number for rails in the Gemfile:
+
+```Gemfile
+# frozen_string_literal: true
+source "https://rubygems.org"
+
+gem "rails", "6.1.7" <---
+
+ruby "3.1.4"
+```
+
+Rerun the step above to rebuild the container, attach to it and then update gems again.
+```bash
+docker compose up --build
+docker compose exec web sh
+> bundle update
+> bundle install
+```
+
+You can also use the rails update command to implement any of the changes required by the new version of Rails. This will prompt you to overwrite files, so make sure you view the diffs and test the changes before committing.
+
+```bash
+docker compose exec web sh
+> bin/bash app:update
+```
+
+Now test the app for any errors or deprecation warnings, fix them, run tests, and commit your changes.
+
+#### Upgrade bundler
+It's unlikely, but you may also need to upgrade bundler if you are getting errors. You can do this by running `bundle update --bundler`. The default version of bundler from the ruby container should be preferred.
+
+#### Migrating and seeding the database
+If database migrations were created by the update process, you will need to run them and then seed the database.
+
+```bash
+docker compose exec web bin/rails db:migrate
+```
diff --git a/docs/img/application-details.png b/docs/img/application-details.png
new file mode 100644
index 0000000..9d6a37c
Binary files /dev/null and b/docs/img/application-details.png differ
diff --git a/entrypoint.sh b/entrypoint.sh
index 48410b9..671a8df 100755
--- a/entrypoint.sh
+++ b/entrypoint.sh
@@ -1,7 +1,35 @@
+#!/bin/sh
+set -e
+echo -e "$0: => Running the docker entrypoint script"
+
+function check_agent_connectivity {
+ echo -e "$0: => Checking Contrast Agent configuration"
+ bundle exec rails contrast:config:validate
+}
+
+if check_agent_connectivity; then
+ echo -e "$0: => Contrast agent connectivity check: SUCCESS"
+ echo -e "$0: => Starting RailsGoat with Contrast..."
+else
+ echo -e "$0: => Contrast agent connectivity check: FAILED"
+ echo -e "It's likely that you haven't set your Contrast Agent authentication keys correctly."
+ echo -e "\nSet the following environment variables by passing them in your docker run command with the -e flag"
+ echo -e "\t -e CONTRAST__API__URL="
+ echo -e "\t -e CONTRAST__API__API_KEY="
+ echo -e "\t -e CONTRAST__API__SERVICE_KEY="
+ echo -e "\t -e CONTRAST__API__USER_NAME="
+ echo -e "\n OR add these values to the .env file and pass this in your docker command."
+ echo -e "\n OR add these values to the contrast_security.yaml file in the config directory."
+ echo -e "\nTo find your organization keys please follow this documentation:"
+ echo -e "https://docs.contrastsecurity.com/en/find-the-agent-keys.html"
+ exit 1
+fi
+
rm -f tmp/pids/server.pid
-if [[ $TEST = true ]]
-then
+if [ $TEST ]; then
+ echo -e "== Running RailsGoat in training mode with Contrast enabled =="
bundle exec rails training
else
- bundle exec rails s -p 3000 -b '0.0.0.0'
-fi
\ No newline at end of file
+ echo -e "== Running RailsGoat with Contrast enabled =="
+ bundle exec rails server -p 3000 -b '0.0.0.0'
+fi
diff --git a/log/.gitkeep b/log/.keep
similarity index 100%
rename from log/.gitkeep
rename to log/.keep
diff --git a/parseyaml.py b/parseyaml.py
deleted file mode 100644
index 2f50efb..0000000
--- a/parseyaml.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import yaml, json
-with open('./contrast_security.yaml') as f:
- config = yaml.load(f)
- print(json.dumps(config['api']))
\ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 3e79dbf..543daaf 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -9,7 +9,7 @@
require File.expand_path("../../config/environment", __FILE__)
require "rspec/rails"
require "capybara/rails"
-require "capybara/poltergeist"
+require "capybara/cuprite"
require "database_cleaner"
# Requires supporting ruby files with custom matchers and macros, etc,
@@ -28,7 +28,7 @@
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
- config.use_transactional_fixtures = false # Capybara Poltergeist driver requires this
+ config.use_transactional_fixtures = false
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
@@ -61,6 +61,6 @@
config.infer_spec_type_from_file_location!
end
-Capybara.javascript_driver = :poltergeist
+Capybara.javascript_driver = :cuprite
DatabaseCleaner.strategy = :truncation
diff --git a/spec/support/capybara_shared.rb b/spec/support/capybara_shared.rb
index 7216b16..4b5490e 100644
--- a/spec/support/capybara_shared.rb
+++ b/spec/support/capybara_shared.rb
@@ -46,8 +46,7 @@ def login(user)
end
end
-##Hack to fix PhantomJS errors on Mavericks - https://gist.github.com/ericboehs/7125105
-module Capybara::Poltergeist
+module Capybara::Cuprite
class Client
private
def redirect_stdout
@@ -93,8 +92,14 @@ def ignore?(message)
end
end
-Capybara.register_driver :poltergeist do |app|
- Capybara::Poltergeist::Driver.new(app, phantomjs_logger: WarningSuppressor.new, timeout: 60)
+Capybara.register_driver :cuprite do |app|
+ Capybara::Cuprite::Driver.new(
+ app,
+ js_errors: true,
+ window_size: [1200, 900],
+ browser_options: { 'no-sandbox': nil },
+ timeout: 60
+ )
end
-Capybara.javascript_driver = :poltergeist
+Capybara.javascript_driver = :cuprite
diff --git a/spec/vulnerabilities/sql_injection_spec.rb b/spec/vulnerabilities/sql_injection_spec.rb
index dd22d32..3196975 100644
--- a/spec/vulnerabilities/sql_injection_spec.rb
+++ b/spec/vulnerabilities/sql_injection_spec.rb
@@ -22,7 +22,7 @@
fill_in "user_password_confirmation", with: "hacketyhack"
# this is a hidden field, so cannot use fill_in to access it.
- find(:xpath, "//input[@id='user_id']", visible: false).set "8' OR admin='t') --"
+ find(:xpath, "//input[@id='user_id']", visible: false).set "8' OR 1 == 1) --"
end
click_on "Submit"