diff --git a/.github/workflows/owasp-scan.yml b/.github/workflows/owasp-scan.yml
index f499cc06c..77572bd56 100644
--- a/.github/workflows/owasp-scan.yml
+++ b/.github/workflows/owasp-scan.yml
@@ -45,4 +45,4 @@ jobs:
with:
target: 'http://localhost:3000/'
fail_action: true
- cmd_options: -c app/zap.conf -z "-configfile /zap/wrk/zap_options.conf"
+ cmd_options: -c app/zap.conf
diff --git a/app/.rubocop.yml b/app/.rubocop.yml
index 0c9fe0568..e74571f9a 100644
--- a/app/.rubocop.yml
+++ b/app/.rubocop.yml
@@ -21,3 +21,5 @@ Layout/IndentationWidth:
Layout/IndentationConsistency:
Enabled: true
EnforcedStyle: normal
+Layout/EndAlignment:
+ EnforcedStyleAlignWith: keyword
diff --git a/app/app/controllers/pages_controller.rb b/app/app/controllers/pages_controller.rb
index 45f463e4c..d2b235676 100644
--- a/app/app/controllers/pages_controller.rb
+++ b/app/app/controllers/pages_controller.rb
@@ -1,4 +1,23 @@
class PagesController < ApplicationController
def home
end
+
+ def error_404
+ # When in development environment, you'll need to set
+ # config.consider_all_requests_local = false
+ # in config/development.rb for these pages to actually show up.
+ @cbv_flow = if session[:cbv_flow_id]
+ CbvFlow.find(session[:cbv_flow_id])
+ end
+
+ render status: :not_found, formats: %i[html]
+ end
+
+ def error_500
+ # When in development environment, you'll need to set
+ # config.consider_all_requests_local = false
+ # in config/development.rb for these pages to actually show up.
+
+ render status: :internal_server_error, formats: %i[html]
+ end
end
diff --git a/app/app/views/pages/error_404.html.erb b/app/app/views/pages/error_404.html.erb
new file mode 100644
index 000000000..cc21c9cce
--- /dev/null
+++ b/app/app/views/pages/error_404.html.erb
@@ -0,0 +1,13 @@
+<% header = t(".header") %>
+<% content_for :title, header %>
+
<%= header %>
+
+
+
<%= t(".error_code_html") %>
+
+ <% if @cbv_flow && @cbv_flow.cbv_flow_invitation %>
+ <%= link_to t(".return_to_entry"), @cbv_flow.cbv_flow_invitation.to_url %>
+ <% else %>
+ <%= link_to t(".return_to_welcome"), root_url %>
+ <% end %>
+
diff --git a/app/app/views/pages/error_500.html.erb b/app/app/views/pages/error_500.html.erb
new file mode 100644
index 000000000..31842f8a3
--- /dev/null
+++ b/app/app/views/pages/error_500.html.erb
@@ -0,0 +1,13 @@
+<% header = t(".header") %>
+<% content_for :title, header %>
+<%= header %>
+
+
+
<%= t(".error_code_html") %>
+
+
<%= t(".description") %>
+
+
+ <%= link_to t(".refresh"), "javascript:window.location.reload()" %>
+
+
diff --git a/app/config/application.rb b/app/config/application.rb
index c1af76417..79311d5f3 100644
--- a/app/config/application.rb
+++ b/app/config/application.rb
@@ -35,6 +35,9 @@ class Application < Rails::Application
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
+ # Allow specifying /404 and /500 routes for error pages
+ config.exceptions_app = self.routes
+
# Don't generate system test files.
config.generators.system_tests = nil
config.autoload_paths += %W[#{config.root}/lib]
diff --git a/app/config/i18n-tasks.yml b/app/config/i18n-tasks.yml
index 2125a508e..f1cb2d12f 100644
--- a/app/config/i18n-tasks.yml
+++ b/app/config/i18n-tasks.yml
@@ -138,6 +138,7 @@ ignore_missing:
- "cbv.expired_invitations.show.body_2"
- "help.*"
- "shared.header.help"
+ - "pages.{error_404,error_500}.*"
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
# - '{devise,simple_form}.*'
diff --git a/app/config/locales/en.yml b/app/config/locales/en.yml
index 2d7f464e3..b2659df16 100644
--- a/app/config/locales/en.yml
+++ b/app/config/locales/en.yml
@@ -517,6 +517,16 @@ en:
title: Contact your employer's Human Resource Team
title: I don't know my username
pages:
+ error_404:
+ error_code_html: 'Error code: 404'
+ header: We can't find the page you're looking for
+ return_to_entry: Return to entry page
+ return_to_welcome: Return to welcome page
+ error_500:
+ description: This is a problem on our end. There was an error with the server and our team has been notified. Please refresh your page, or try again later.
+ error_code_html: 'Error code: 500'
+ header: It looks like something went wrong
+ refresh: Refresh page
home:
description_1: The SNAP Income Pilot is a new tool designed to help you connect your income details from your employer or payroll provider directly to your SNAP agency.
description_2: Please note this pilot is not currently available.
diff --git a/app/config/routes.rb b/app/config/routes.rb
index b877cddcf..9d6838c9b 100644
--- a/app/config/routes.rb
+++ b/app/config/routes.rb
@@ -70,4 +70,7 @@
post :user_action, to: "user_events#user_action"
end
end
+
+ match "/404", to: "pages#error_404", via: :all
+ match "/500", to: "pages#error_500", via: :all
end
diff --git a/app/public/404.html b/app/public/404.html
deleted file mode 100644
index 2be3af26f..000000000
--- a/app/public/404.html
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
- The page you were looking for doesn't exist (404)
-
-
-
-
-
-
-
-
-
The page you were looking for doesn't exist.
-
You may have mistyped the address or the page may have moved.
-
-
If you are the application owner check the logs for more information.
-
-
-
diff --git a/app/public/422.html b/app/public/422.html
deleted file mode 100644
index c08eac0d1..000000000
--- a/app/public/422.html
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
- The change you wanted was rejected (422)
-
-
-
-
-
-
-
-
-
The change you wanted was rejected.
-
Maybe you tried to change something you didn't have access to.
-
-
If you are the application owner check the logs for more information.
-
-
-
diff --git a/app/public/500.html b/app/public/500.html
deleted file mode 100644
index 78a030af2..000000000
--- a/app/public/500.html
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
- We're sorry, but something went wrong (500)
-
-
-
-
-
-
-
-
-
We're sorry, but something went wrong.
-
-
If you are the application owner check the logs for more information.
-
-
-
diff --git a/app/spec/controllers/pages_controller_spec.rb b/app/spec/controllers/pages_controller_spec.rb
new file mode 100644
index 000000000..d3b4450c5
--- /dev/null
+++ b/app/spec/controllers/pages_controller_spec.rb
@@ -0,0 +1,40 @@
+require "rails_helper"
+
+RSpec.describe PagesController do
+ render_views
+
+ describe "#home" do
+ it "renders" do
+ get :home
+ expect(response).to be_successful
+ expect(response.body).to include("Welcome")
+ end
+ end
+
+ describe "#error_404" do
+ it "renders with a link to the homepage" do
+ get :error_404
+ expect(response.status).to eq(404)
+ expect(response.body).to include("We can't find the page")
+ expect(response.body).to include("Return to welcome")
+ end
+
+ describe "when a cbv_flow_id is in the session" do
+ let(:cbv_flow) { create(:cbv_flow) }
+
+ it "renders with a link to restart that CBV flow" do
+ get :error_404, session: { cbv_flow_id: cbv_flow.id }
+ expect(response.status).to eq(404)
+ expect(response.body).to include("Return to entry page")
+ end
+ end
+ end
+
+ describe "#error_500" do
+ it "renders" do
+ get :error_500
+ expect(response.status).to eq(500)
+ expect(response.body).to include("It looks like something went wrong")
+ end
+ end
+end
diff --git a/app/zap.conf b/app/zap.conf
index 8248449fb..f8db33358 100644
--- a/app/zap.conf
+++ b/app/zap.conf
@@ -1,6 +1,10 @@
# zap-full-scan rule configuration file
+#
# Change WARN to IGNORE to ignore rule or FAIL to fail if rule matches
# Active scan rules set to IGNORE will not be run which will speed up the scan
+# Use OUTOFSCOPE with a regular expression to exclude URLs from triggering rules
+# (see https://github.com/zaproxy/zaproxy/blob/d67299a/docker/zap_common.py#L162)
+#
# Only the rule identifiers are used - the names are just for info
# You can add your own messages to each rule by appending them after a tab on each line.
0 WARN (Directory Browsing - Active/release)
@@ -37,6 +41,7 @@
10036 WARN (HTTP Server Response Header - Passive/beta)
10037 WARN (Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) - Passive/release)
10038 FAIL (Content Security Policy (CSP) Header Not Set - Passive/beta)
+10038 OUTOFSCOPE .*/sitemap\.xml
10039 WARN (X-Backend-Server Header Information Leak - Passive/beta)
10040 FAIL (Secure Pages Include Mixed Content - Passive/release)
10041 WARN (HTTP to HTTPS Insecure Transition in Form Post - Passive/beta)
diff --git a/zap_options.conf b/zap_options.conf
deleted file mode 100644
index 74ae025eb..000000000
--- a/zap_options.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-network.globalExclusions.exclusions(0).exclusion.name=Search
-network.globalExclusions.exclusions(0).exclusion.enabled=true
-network.globalExclusions.exclusions(0).exclusion.value=/.*\/(?:.{2}\/)?cbv\/employer_search\?authenticity\_token.*/gm