From 423d20dbefd59078c5808fbccbc478b933a127d3 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Thu, 6 Jun 2024 17:44:08 -0400 Subject: [PATCH 01/34] app security doc and items 1-6 --- docs/app-rails/application-security.md | 72 ++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/app-rails/application-security.md diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md new file mode 100644 index 0000000..5d1737f --- /dev/null +++ b/docs/app-rails/application-security.md @@ -0,0 +1,72 @@ +# Application Security + +Application security is a top priority for government technology application development, which is why the Rails framework's security helper methods and countermeasures help speed up secure application delivery. However, the framework isn't useful by itself; its helper methods and configurations only work if they are used properly. This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit the template's use of Rails security best practices. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. + +Areas for improvement are marked with `TODO` that describe a security implementation. They should be accompanied by a comment in the codebase referencing the action needed, like `# TODO: sanitize input to protect against SQL injection`. + +## Conforms to best practices +As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/security.html) + +### 1 Introduction + +### 2 Sessions +#### 2.1 What are sessions +### 2.2 Session hijacking: +1. `config.force_ssl = true` is set for production environments +1. Provided the user with a logout button +#### 2.3 Session storage +1. Using Devise's Session Controller to manage session storage +1. Cookies stored client side do not contain sensitive information +1. Cookies time out in 15 minutes of inactivity with devise config.timeout_in +1. Cookies are encrypted client side +1. Devise uses BCrypt and the secret_key_base by default for secret hashing +1. TODO: Cognito, the auth service, is also managing sessions and if wanted to expire sessions after a certain time, regardless of activity, we’d have to do it there +#### 2.4 Rotating Encrypted and Signed Cookies Configurations +1. TODO: We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito +#### 2.5 Replay Attacks for CookieStore Sessions +1. TODO: We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in `/app-rails/config/initializers/generate_security_policy.rb` This however ties users to a particular server/session as we don’t want to save nonces in the database. +#### 2.6 Session Fixation +#### 2.7 Session Fixation - Countermeasures +1. Devise will automatically expire sessions on sign in and sign out with config.expire_all_remember_me_on_sign_out = true +#### 2.8 Session Expiry + +### 3 Cross-Site Request Forgery (CSRF) +#### 3.1 CSRF Countermeasures +1. get, post, delete, and rails’ resources are used appropriately in the routes.rb file +1. TODO: We’re not setting forgery protection on in production however https://guides.rubyonrails.org/v7.1/security.html#:~:text=3.1.2%20Required%20Security%20Token +1. TODO: If I change my csrf token manually in my browser, I’m not prevented from taking any actions (get or post requests) as a signed in user + +### 4 Redirection and Files +#### 4.1 Redirection +1. link_tos do not route to user inputs, which is XSS vulnerable +1. redirect_to does not use params or user inputs in the routes +4.2 File Uploads +1. TODO: App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications + +### 5. User Management +1. When using devise we don’t need to set has_secure_password on password fields +#### 5.1 brute forcing accounts +1. Username error is generic and does not indicate whether it was an error with the username or password +1. Forgot password confirms the email was sent, and not whether the username exists +#### 5.2 Account Hijacking +1. Change password includes email 6 digit code +1. TODO: Require entering the password when changing email +#### 5.3 CAPTCHA +1. TODO: Include Captcha on account creation, login, change password, and change email +1. TODO: Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html +#### 5.4 Logging +1. We’re filtering the following parameter partials (if all or any part matches) in the config/initialization/filter_paramater_logging.rb file: :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn +#### 5.5 Regex +1. Two places where regex is used (mailto.rb and devise) use the correct ruby \A and \z and not the more common: /^ and $/ +1. TODO: Add multiline: true to our regex format: in validations +5.6 Privilege Escalation +1. TODO: By manually changing a parameter, a hacker may get access to information they should not be able to access. Instead of doing things like: @task = Task.find(params[:id]), instead do @user.tasks.find(params[:id]). This is not in the template, but it is in the app the template is based on. + + +### 6 Injection +#### 6.1 Permitted Lists Versus Restricted Lists +1. TODO: Use except: […] instead of only:[…] for security related actions so when adding actions, they are behind the security by default. Ex. app-rails/app/controllers/application_controller.rb line: 8. after_action :verify_policy_scoped, only: :index +#### 6.2 SQL Injection +1. Not generally an issue with rails applications. We aren’t interpolating params into SQL fragments, which would also be against ruby and rails best practices, ie. .where(“name = `#{params[:name]}`” +#### 6.3.2.1 Cookie Theft +1. While we’re not setting secure: true on the cookies themselves, the config.force_ssl = true option in production ensures all cookies are httponly From 5691c7887652f6b931c9a23dfcded5b3c1647375 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Fri, 7 Jun 2024 11:16:34 -0400 Subject: [PATCH 02/34] completed injection section --- docs/app-rails/application-security.md | 107 ++++++++++++++++--------- 1 file changed, 68 insertions(+), 39 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 5d1737f..702bfc2 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -2,71 +2,100 @@ Application security is a top priority for government technology application development, which is why the Rails framework's security helper methods and countermeasures help speed up secure application delivery. However, the framework isn't useful by itself; its helper methods and configurations only work if they are used properly. This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit the template's use of Rails security best practices. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. -Areas for improvement are marked with `TODO` that describe a security implementation. They should be accompanied by a comment in the codebase referencing the action needed, like `# TODO: sanitize input to protect against SQL injection`. +Areas for improvement are marked with `TODO` that describe a security implementation. They should be accompanied by a comment in the codebase referencing the action needed, like `# **TODO:** sanitize input to protect against SQL injection`. -## Conforms to best practices +## Conforms to Best Practices As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/security.html) ### 1 Introduction ### 2 Sessions -#### 2.1 What are sessions -### 2.2 Session hijacking: -1. `config.force_ssl = true` is set for production environments -1. Provided the user with a logout button -#### 2.3 Session storage -1. Using Devise's Session Controller to manage session storage -1. Cookies stored client side do not contain sensitive information -1. Cookies time out in 15 minutes of inactivity with devise config.timeout_in -1. Cookies are encrypted client side -1. Devise uses BCrypt and the secret_key_base by default for secret hashing -1. TODO: Cognito, the auth service, is also managing sessions and if wanted to expire sessions after a certain time, regardless of activity, we’d have to do it there +#### 2.1 What Are Sessions +#### 2.2 Session Hijacking: +1. `config.force_ssl = true` is set for production environments. +1. Provided the user with a logout button. +#### 2.3 Session Storage +1. Using Devise's Session Controller to manage session storage. +1. Cookies stored client side do not contain sensitive information. +1. Cookies time out in 15 minutes of inactivity with devise `config.timeout_in`. +1. Cookies are encrypted client side. +1. Devise uses BCrypt and the secret_key_base by default for secret hashing. +1. **TODO:** Cognito, the auth service, is also managing sessions and if wanted to expire sessions after a certain time, regardless of activity, we’d have to do it there. #### 2.4 Rotating Encrypted and Signed Cookies Configurations -1. TODO: We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito +1. **TODO:** We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito. #### 2.5 Replay Attacks for CookieStore Sessions -1. TODO: We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in `/app-rails/config/initializers/generate_security_policy.rb` This however ties users to a particular server/session as we don’t want to save nonces in the database. +1. **TODO:** We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in `/app-rails/config/initializers/generate_security_policy.rb` This however ties users to a particular server/session as we don’t want to save nonces in the database. #### 2.6 Session Fixation #### 2.7 Session Fixation - Countermeasures -1. Devise will automatically expire sessions on sign in and sign out with config.expire_all_remember_me_on_sign_out = true +1. Devise will automatically expire sessions on sign in and sign out with `config.expire_all_remember_me_on_sign_out = true`. #### 2.8 Session Expiry ### 3 Cross-Site Request Forgery (CSRF) #### 3.1 CSRF Countermeasures -1. get, post, delete, and rails’ resources are used appropriately in the routes.rb file -1. TODO: We’re not setting forgery protection on in production however https://guides.rubyonrails.org/v7.1/security.html#:~:text=3.1.2%20Required%20Security%20Token -1. TODO: If I change my csrf token manually in my browser, I’m not prevented from taking any actions (get or post requests) as a signed in user +1. GET, POST, DELETE, and rails’ resources are used appropriately in the `routes.rb` file. +1. **TODO:** We’re not setting forgery protection in production despite passing a CSRF token to the client, therefore If I change my CSRF token manually in my browser, I’m not prevented from taking any actions (GET or POST requests) as a signed in user. ### 4 Redirection and Files #### 4.1 Redirection -1. link_tos do not route to user inputs, which is XSS vulnerable -1. redirect_to does not use params or user inputs in the routes +1. link_tos do not route to user inputs, which is XSS vulnerable. +1. redirect_to does not use params or user inputs in the routes. 4.2 File Uploads -1. TODO: App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications +1. **TODO:** App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications. ### 5. User Management -1. When using devise we don’t need to set has_secure_password on password fields -#### 5.1 brute forcing accounts -1. Username error is generic and does not indicate whether it was an error with the username or password -1. Forgot password confirms the email was sent, and not whether the username exists +1. When using devise we don’t need to set has_secure_password on password fields. +#### 5.1 Brute Forcing Accounts +1. Username error is generic and does not indicate whether it was an error with the username or password. +1. Forgot password confirms the email was sent, and not whether the username exists. #### 5.2 Account Hijacking -1. Change password includes email 6 digit code -1. TODO: Require entering the password when changing email +1. Change password includes email 6 digit code. +1. **TODO:** Require entering the password when changing email. #### 5.3 CAPTCHA -1. TODO: Include Captcha on account creation, login, change password, and change email -1. TODO: Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html +1. **TODO:** Include Captcha on account creation, login, change password, and change email. +1. **TODO:** Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html). #### 5.4 Logging -1. We’re filtering the following parameter partials (if all or any part matches) in the config/initialization/filter_paramater_logging.rb file: :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn +1. We’re filtering the following parameter partials (if all or any part matches) in the `config/initialization/filter_paramater_logging.rb` file: `:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn`. #### 5.5 Regex -1. Two places where regex is used (mailto.rb and devise) use the correct ruby \A and \z and not the more common: /^ and $/ -1. TODO: Add multiline: true to our regex format: in validations -5.6 Privilege Escalation -1. TODO: By manually changing a parameter, a hacker may get access to information they should not be able to access. Instead of doing things like: @task = Task.find(params[:id]), instead do @user.tasks.find(params[:id]). This is not in the template, but it is in the app the template is based on. - +1. Two places where regex is used (`mailto.rb` and devise) use the correct ruby `\A` and `\z` and not the more common: `/^` and `$/`. +1. **TODO:** Add multiline: true to our regex format: in validations. +#### 5.6 Privilege Escalation +1. **TODO:** By manually changing a parameter, a hacker may get access to information they should not be able to access. Instead of doing things like: `@task = Task.find(params[:id])`, instead do `@user.tasks.find(params[:id])`. This is not in the template, but it is in the app the template is based on. ### 6 Injection #### 6.1 Permitted Lists Versus Restricted Lists -1. TODO: Use except: […] instead of only:[…] for security related actions so when adding actions, they are behind the security by default. Ex. app-rails/app/controllers/application_controller.rb line: 8. after_action :verify_policy_scoped, only: :index +1. **TODO:** Use `except: […]` instead of `only:[…]` for security related actions so when adding actions, they are behind the security by default. Ex. `app-rails/app/controllers/application_controller.rb line: 8`. `after_action :verify_policy_scoped, only: :index`. #### 6.2 SQL Injection -1. Not generally an issue with rails applications. We aren’t interpolating params into SQL fragments, which would also be against ruby and rails best practices, ie. .where(“name = `#{params[:name]}`” +1. Not generally an issue with rails applications. We aren’t interpolating params into SQL fragments, which would also be against ruby and rails best practices, ie. .where(“name = `#{params[:name]}`”. #### 6.3.2.1 Cookie Theft -1. While we’re not setting secure: true on the cookies themselves, the config.force_ssl = true option in production ensures all cookies are httponly +1. While we’re not setting secure: true on the cookies themselves, the `config.force_ssl = true` option in production ensures all cookies are `httponly`. +#### 6.3.2.3 Defacement Countermeasures +1. The template application doesn't have any inputs that are then displayed to the user, aside from the user email, which prevents scripting. However, when those inputs are created, it will be important to sanitize the outputs in the erb files, using `<%=h =>` to protect against defacement. +1. An additional step can be taken to sanitize inputs, but those should use a permitted list of tags, instead of restricted lists, using: +``` +tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) +s = sanitize(user_input, tags: tags, attributes: %w(href title)) +``` +#### 6.3.2.4 Obfuscation and Encoding Injection +1. While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection, and the Rails sanitize() method should be used on inputs that will be presented to the UI at any point. +#### 6.4 CSS Injection +1. This is rarely needed as applications, especially government applications, rarely if ever offer the user the ability to input custom colors or input css filters. +#### 6.5 Textile Injection +1. This template application doesn't allow users to enter text to be converted into html, that's more common in content management system applications. If that feature set is added, it is important to do so with a permitted input filter similar to 6.3.2.3 Defacement Countermeasures. The most common Rails tool for text to html conversion is RedCloth, which is being mentioned in case folks search the repo for RedCloth, they should find this recommendation. +#### 6.6 Ajax Injection +1. The output has to be escaped in the controller already, if the action doesn't render a view. However, we have no case of outputting strings rather than views in our template application. However, rendering data from the controller seems like a Rails anti-pattern. +#### 6.7 Command Line Injection +1. Only relevant if the application takes a user input and executes a command on the underlying operating system. Applicable methods include: + 1. `system()` + 1. `exec()` + 1. `spawn()` + 1. `command` +#### 6.7.1 Kernel#open's Vulnerability +1. Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. Using `open()` method seems like a Rails anti-pattern so this shouldn't be an issue. +#### 6.8 Header Injection +1. This applies to adding user input to the `` tags in erb files, using the `content_for :head` method in erb files, and adding user input to a response with `head :some_header` in controllers. The template doesn't use any of those features, but this may come up in the future. +#### 6.8.1 DNS Rebinding and Host Header Attacks +1. **TODO:** Configure [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) in production to prevent DNS rebinding attacks. +#### 6.8.2 Response Splitting +1. This template uses rails verstion > 2.1.2, therefore this is not a concern. + +### 7 Unsafe Query Generation From a1e7bacca259089e6eb77d4fcdc47b8d6e6b29db Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Fri, 7 Jun 2024 11:20:50 -0400 Subject: [PATCH 03/34] item 7 --- docs/app-rails/application-security.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 702bfc2..819c875 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -96,6 +96,10 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title)) #### 6.8.1 DNS Rebinding and Host Header Attacks 1. **TODO:** Configure [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) in production to prevent DNS rebinding attacks. #### 6.8.2 Response Splitting -1. This template uses rails verstion > 2.1.2, therefore this is not a concern. +1. This template uses rails version > 2.1.2, therefore this is not a concern. ### 7 Unsafe Query Generation +1. Unless you know what you're doing, don't disable `deep_munge` with `config.action_dispatch.perform_deep_munge = false` + +### 8 HTTP Security Headers +#### 8.1 Default Security Headers From cf679e31ef914862c28aff84549dd75e32db7c9a Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Fri, 7 Jun 2024 11:57:01 -0400 Subject: [PATCH 04/34] section 8 --- docs/app-rails/application-security.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 819c875..0a95c0b 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -103,3 +103,20 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title)) ### 8 HTTP Security Headers #### 8.1 Default Security Headers +1. Rails locks down the headers by default, and we have no need to open these up. However, the defaults can be overridden in `config/application.rb` with `config.action_dispatch.default_headers`. +1. X-Frame-Options is set to allow iframes from the same origin, set this to deny if not using any iframes to embed. If you need to permit an iframe from another origin, a controller can then use an `after_action :allow_some_service`. +#### 8.2 Strict-Transport-Security Header +1. This is set in production with `config.force_ssl = true` +#### 8.3 Content-Security-Policy Header +1. **TODO:** To help protect against XSS and injection attacks, define a Content-Security-Policy in the provided file: `app-rails/config/initializers/content_security_policy.rb`. The policy can be more restrictive, and controllers can override defaults when necessary. +#### 8.3.1 Reporting Violations +1. **TODO:** In addition to preventing attacks, it's important to log them to continuously improve security. Set the report_uri config on the content security policy and configure a controller to log the reports. Note that `report_uri` is being deprecated, and will eventually become `report_to` +#### 8.3.2 Adding a Nonce +1. **TODO:** We're already adding the `csp_meta_tag` to the application.html.erb, but we're not taking advantage of it with nonce generation in the content security policy. +#### 8.4 Feature-Policy Header +1. **TODO:** Configure which browser features are allowed in `app-rails/config/initializers/permissions_policy.rb`. This policy can be more restrictive than necessary because features can be allowed on specific controllers. +#### 8.5 Cross-Origin Resource Sharing +1. As of now, this application envisioned as a full-stack application template. However, if there is a need to open up endpoints as APIs, we need to configure CORS, by installing and configuring the `rack-cors` gem. + +### 9 Intranet and Admin Security + From 9cbec945910824a0a8bdac4bcfa16b1c7423ba27 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Fri, 7 Jun 2024 13:01:32 -0400 Subject: [PATCH 05/34] complete audit --- docs/app-rails/application-security.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 0a95c0b..ccc85d4 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -119,4 +119,18 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title)) 1. As of now, this application envisioned as a full-stack application template. However, if there is a need to open up endpoints as APIs, we need to configure CORS, by installing and configuring the `rack-cors` gem. ### 9 Intranet and Admin Security +#### 9.1 Cross-Site Scripting +1. The template doesn't include a admin view, but if that is added, be sure to sanitize all user inputs as they may be viewed here even if they aren't visible anywhere else in the application. +#### 9.2 Cross-Site Request Forgery +1. Same as CSRF countermeasures discussed above. +#### 9.3 Additional Precautions +1. Some effective admin protection strategies includes: + * Limit admin role privileges using the principle of least privilege + * Geofence admin login IP to the USA. + * Consider putting the admin app at a subdomain so the cookie for application can't be used for the admin console and vice-versa. +### 10 Environmental Security +1. Secret management is covered in the template infrastructure repo and is out of scope of this template application. + +### 11 Dependency Management and CVEs' +1. We're using dependabot to notify us if we have outdated gems. From 5a6c0500b52c433125b7c6f20f14a52f22053a65 Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 10 Jun 2024 09:20:23 -0400 Subject: [PATCH 06/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index ccc85d4..584d3d1 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -1,8 +1,10 @@ # Application Security -Application security is a top priority for government technology application development, which is why the Rails framework's security helper methods and countermeasures help speed up secure application delivery. However, the framework isn't useful by itself; its helper methods and configurations only work if they are used properly. This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit the template's use of Rails security best practices. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. +Application security is a top priority for technology application development, which is why the Rails framework's security helper methods and countermeasures help speed up secure application delivery. However, the framework isn't useful by itself; its helper methods and configurations only work if they are used properly. -Areas for improvement are marked with `TODO` that describe a security implementation. They should be accompanied by a comment in the codebase referencing the action needed, like `# **TODO:** sanitize input to protect against SQL injection`. +Areas that require improvement are marked with `@TODO` and describe a security implementation. They should be accompanied by a comment in the codebase referencing the action needed, like `# **@TODO:** sanitize input to protect against SQL injection`. + +This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit this project's Rails security best practices. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. ## Conforms to Best Practices As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/security.html) From cdbc42302c7fa98bf0233eaef612d9953ba04e0d Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 10 Jun 2024 09:20:37 -0400 Subject: [PATCH 07/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 584d3d1..75090ad 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -22,7 +22,7 @@ As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/secu 1. Cookies time out in 15 minutes of inactivity with devise `config.timeout_in`. 1. Cookies are encrypted client side. 1. Devise uses BCrypt and the secret_key_base by default for secret hashing. -1. **TODO:** Cognito, the auth service, is also managing sessions and if wanted to expire sessions after a certain time, regardless of activity, we’d have to do it there. +1. **@TODO:** If we want to expire sessions after a set amount of time, regardless of activity, those changes would need to be enforced by the auth service, such as in AWS Cognito. #### 2.4 Rotating Encrypted and Signed Cookies Configurations 1. **TODO:** We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito. #### 2.5 Replay Attacks for CookieStore Sessions From 2b317e83a6c174117f44ce561a9d5867a940d94d Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 10 Jun 2024 09:20:53 -0400 Subject: [PATCH 08/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 75090ad..3d6dc90 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -26,7 +26,7 @@ As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/secu #### 2.4 Rotating Encrypted and Signed Cookies Configurations 1. **TODO:** We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito. #### 2.5 Replay Attacks for CookieStore Sessions -1. **TODO:** We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in `/app-rails/config/initializers/generate_security_policy.rb` This however ties users to a particular server/session as we don’t want to save nonces in the database. +1. **TODO:** We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) This however ties users to a particular server/session as we don’t want to save nonces in the database. #### 2.6 Session Fixation #### 2.7 Session Fixation - Countermeasures 1. Devise will automatically expire sessions on sign in and sign out with `config.expire_all_remember_me_on_sign_out = true`. From 37ea49b57f7315ce0afc4b9fdb8f51af5151f2eb Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 10 Jun 2024 09:21:01 -0400 Subject: [PATCH 09/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 3d6dc90..1413ab6 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -45,7 +45,7 @@ As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/secu 1. **TODO:** App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications. ### 5. User Management -1. When using devise we don’t need to set has_secure_password on password fields. +1. When using Devise we don’t need to set `has_secure_password` on password fields. #### 5.1 Brute Forcing Accounts 1. Username error is generic and does not indicate whether it was an error with the username or password. 1. Forgot password confirms the email was sent, and not whether the username exists. From 1e509b73ec9cd7e49f9b7e670e3fd8d88df8cdb1 Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 10 Jun 2024 09:21:33 -0400 Subject: [PATCH 10/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 1413ab6..7d5b82f 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -51,7 +51,7 @@ As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/secu 1. Forgot password confirms the email was sent, and not whether the username exists. #### 5.2 Account Hijacking 1. Change password includes email 6 digit code. -1. **TODO:** Require entering the password when changing email. +1. **@TODO:** We currently do not require entering the password when changing email, but we should. #### 5.3 CAPTCHA 1. **TODO:** Include Captcha on account creation, login, change password, and change email. 1. **TODO:** Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html). From 41451e3e767b3fc229ce21aecabbfb6b713d896e Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Fri, 7 Jun 2024 13:06:00 -0400 Subject: [PATCH 11/34] remove suggestion to add todos to the codebase --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 7d5b82f..16f7504 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -2,7 +2,7 @@ Application security is a top priority for technology application development, which is why the Rails framework's security helper methods and countermeasures help speed up secure application delivery. However, the framework isn't useful by itself; its helper methods and configurations only work if they are used properly. -Areas that require improvement are marked with `@TODO` and describe a security implementation. They should be accompanied by a comment in the codebase referencing the action needed, like `# **@TODO:** sanitize input to protect against SQL injection`. +Areas that require improvement are marked with `@TODO` and describe a security implementation. This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit this project's Rails security best practices. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. From 703b7bb0f1cef8c231de07b601815d1d48877f32 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 09:32:22 -0400 Subject: [PATCH 12/34] Remove unnecessary headings --- docs/app-rails/application-security.md | 43 -------------------------- 1 file changed, 43 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 16f7504..83ec7f1 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -6,126 +6,83 @@ Areas that require improvement are marked with `@TODO` and describe a security i This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit this project's Rails security best practices. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. -## Conforms to Best Practices -As outlined in [Securing Rails Applications](https://guides.rubyonrails.org/security.html) - ### 1 Introduction ### 2 Sessions -#### 2.1 What Are Sessions -#### 2.2 Session Hijacking: 1. `config.force_ssl = true` is set for production environments. 1. Provided the user with a logout button. -#### 2.3 Session Storage 1. Using Devise's Session Controller to manage session storage. 1. Cookies stored client side do not contain sensitive information. 1. Cookies time out in 15 minutes of inactivity with devise `config.timeout_in`. 1. Cookies are encrypted client side. 1. Devise uses BCrypt and the secret_key_base by default for secret hashing. 1. **@TODO:** If we want to expire sessions after a set amount of time, regardless of activity, those changes would need to be enforced by the auth service, such as in AWS Cognito. -#### 2.4 Rotating Encrypted and Signed Cookies Configurations 1. **TODO:** We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito. -#### 2.5 Replay Attacks for CookieStore Sessions 1. **TODO:** We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) This however ties users to a particular server/session as we don’t want to save nonces in the database. -#### 2.6 Session Fixation -#### 2.7 Session Fixation - Countermeasures 1. Devise will automatically expire sessions on sign in and sign out with `config.expire_all_remember_me_on_sign_out = true`. -#### 2.8 Session Expiry ### 3 Cross-Site Request Forgery (CSRF) -#### 3.1 CSRF Countermeasures 1. GET, POST, DELETE, and rails’ resources are used appropriately in the `routes.rb` file. 1. **TODO:** We’re not setting forgery protection in production despite passing a CSRF token to the client, therefore If I change my CSRF token manually in my browser, I’m not prevented from taking any actions (GET or POST requests) as a signed in user. ### 4 Redirection and Files -#### 4.1 Redirection 1. link_tos do not route to user inputs, which is XSS vulnerable. 1. redirect_to does not use params or user inputs in the routes. -4.2 File Uploads 1. **TODO:** App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications. ### 5. User Management 1. When using Devise we don’t need to set `has_secure_password` on password fields. -#### 5.1 Brute Forcing Accounts 1. Username error is generic and does not indicate whether it was an error with the username or password. 1. Forgot password confirms the email was sent, and not whether the username exists. -#### 5.2 Account Hijacking 1. Change password includes email 6 digit code. 1. **@TODO:** We currently do not require entering the password when changing email, but we should. -#### 5.3 CAPTCHA 1. **TODO:** Include Captcha on account creation, login, change password, and change email. 1. **TODO:** Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html). -#### 5.4 Logging 1. We’re filtering the following parameter partials (if all or any part matches) in the `config/initialization/filter_paramater_logging.rb` file: `:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn`. -#### 5.5 Regex 1. Two places where regex is used (`mailto.rb` and devise) use the correct ruby `\A` and `\z` and not the more common: `/^` and `$/`. 1. **TODO:** Add multiline: true to our regex format: in validations. -#### 5.6 Privilege Escalation 1. **TODO:** By manually changing a parameter, a hacker may get access to information they should not be able to access. Instead of doing things like: `@task = Task.find(params[:id])`, instead do `@user.tasks.find(params[:id])`. This is not in the template, but it is in the app the template is based on. ### 6 Injection -#### 6.1 Permitted Lists Versus Restricted Lists 1. **TODO:** Use `except: […]` instead of `only:[…]` for security related actions so when adding actions, they are behind the security by default. Ex. `app-rails/app/controllers/application_controller.rb line: 8`. `after_action :verify_policy_scoped, only: :index`. -#### 6.2 SQL Injection 1. Not generally an issue with rails applications. We aren’t interpolating params into SQL fragments, which would also be against ruby and rails best practices, ie. .where(“name = `#{params[:name]}`”. -#### 6.3.2.1 Cookie Theft 1. While we’re not setting secure: true on the cookies themselves, the `config.force_ssl = true` option in production ensures all cookies are `httponly`. -#### 6.3.2.3 Defacement Countermeasures 1. The template application doesn't have any inputs that are then displayed to the user, aside from the user email, which prevents scripting. However, when those inputs are created, it will be important to sanitize the outputs in the erb files, using `<%=h =>` to protect against defacement. 1. An additional step can be taken to sanitize inputs, but those should use a permitted list of tags, instead of restricted lists, using: ``` tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) s = sanitize(user_input, tags: tags, attributes: %w(href title)) ``` -#### 6.3.2.4 Obfuscation and Encoding Injection 1. While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection, and the Rails sanitize() method should be used on inputs that will be presented to the UI at any point. -#### 6.4 CSS Injection 1. This is rarely needed as applications, especially government applications, rarely if ever offer the user the ability to input custom colors or input css filters. -#### 6.5 Textile Injection 1. This template application doesn't allow users to enter text to be converted into html, that's more common in content management system applications. If that feature set is added, it is important to do so with a permitted input filter similar to 6.3.2.3 Defacement Countermeasures. The most common Rails tool for text to html conversion is RedCloth, which is being mentioned in case folks search the repo for RedCloth, they should find this recommendation. -#### 6.6 Ajax Injection 1. The output has to be escaped in the controller already, if the action doesn't render a view. However, we have no case of outputting strings rather than views in our template application. However, rendering data from the controller seems like a Rails anti-pattern. -#### 6.7 Command Line Injection 1. Only relevant if the application takes a user input and executes a command on the underlying operating system. Applicable methods include: 1. `system()` 1. `exec()` 1. `spawn()` 1. `command` -#### 6.7.1 Kernel#open's Vulnerability 1. Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. Using `open()` method seems like a Rails anti-pattern so this shouldn't be an issue. -#### 6.8 Header Injection 1. This applies to adding user input to the `` tags in erb files, using the `content_for :head` method in erb files, and adding user input to a response with `head :some_header` in controllers. The template doesn't use any of those features, but this may come up in the future. -#### 6.8.1 DNS Rebinding and Host Header Attacks 1. **TODO:** Configure [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) in production to prevent DNS rebinding attacks. -#### 6.8.2 Response Splitting 1. This template uses rails version > 2.1.2, therefore this is not a concern. ### 7 Unsafe Query Generation 1. Unless you know what you're doing, don't disable `deep_munge` with `config.action_dispatch.perform_deep_munge = false` ### 8 HTTP Security Headers -#### 8.1 Default Security Headers 1. Rails locks down the headers by default, and we have no need to open these up. However, the defaults can be overridden in `config/application.rb` with `config.action_dispatch.default_headers`. 1. X-Frame-Options is set to allow iframes from the same origin, set this to deny if not using any iframes to embed. If you need to permit an iframe from another origin, a controller can then use an `after_action :allow_some_service`. -#### 8.2 Strict-Transport-Security Header 1. This is set in production with `config.force_ssl = true` -#### 8.3 Content-Security-Policy Header 1. **TODO:** To help protect against XSS and injection attacks, define a Content-Security-Policy in the provided file: `app-rails/config/initializers/content_security_policy.rb`. The policy can be more restrictive, and controllers can override defaults when necessary. -#### 8.3.1 Reporting Violations 1. **TODO:** In addition to preventing attacks, it's important to log them to continuously improve security. Set the report_uri config on the content security policy and configure a controller to log the reports. Note that `report_uri` is being deprecated, and will eventually become `report_to` -#### 8.3.2 Adding a Nonce 1. **TODO:** We're already adding the `csp_meta_tag` to the application.html.erb, but we're not taking advantage of it with nonce generation in the content security policy. -#### 8.4 Feature-Policy Header 1. **TODO:** Configure which browser features are allowed in `app-rails/config/initializers/permissions_policy.rb`. This policy can be more restrictive than necessary because features can be allowed on specific controllers. -#### 8.5 Cross-Origin Resource Sharing 1. As of now, this application envisioned as a full-stack application template. However, if there is a need to open up endpoints as APIs, we need to configure CORS, by installing and configuring the `rack-cors` gem. ### 9 Intranet and Admin Security -#### 9.1 Cross-Site Scripting 1. The template doesn't include a admin view, but if that is added, be sure to sanitize all user inputs as they may be viewed here even if they aren't visible anywhere else in the application. -#### 9.2 Cross-Site Request Forgery 1. Same as CSRF countermeasures discussed above. -#### 9.3 Additional Precautions 1. Some effective admin protection strategies includes: * Limit admin role privileges using the principle of least privilege * Geofence admin login IP to the USA. From ade9852ebc8b4b0bf302718c933e17b8b0b0c8e1 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 14:56:41 -0400 Subject: [PATCH 13/34] checkboxes --- docs/app-rails/application-security.md | 147 +++++++++++++------------ 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 83ec7f1..c0ec1b6 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -2,94 +2,95 @@ Application security is a top priority for technology application development, which is why the Rails framework's security helper methods and countermeasures help speed up secure application delivery. However, the framework isn't useful by itself; its helper methods and configurations only work if they are used properly. -Areas that require improvement are marked with `@TODO` and describe a security implementation. +Each item below will be checked if it is already implemented by default, or unchecked if it is not implemented by default. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. -This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit this project's Rails security best practices. This is meant to be a living document and should be updated as additional security tools and configurations are implemented, as well as when new vulnerabilities are discovered or introduced. +This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit this project's Rails security best practices. -### 1 Introduction +## Sessions +- [x] `config.force_ssl = true` is set for production environments. +- [x] Provided the user with a logout button. +- [x] Using Devise's Session Controller to manage session storage. +- [x] Cookies stored client side do not contain sensitive information. +- [x] Cookies time out in 15 minutes of inactivity with devise `config.timeout_in`. +- [x] Cookies are encrypted client side. +- [x] Devise uses BCrypt and the secret_key_base by default for secret hashing. +- [ ] If we want to expire sessions after a set amount of time, regardless of activity, those changes would need to be enforced by the auth service, such as in AWS Cognito. +- [ ] We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito. +- [ ] We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) This however ties users to a particular server/session as we don’t want to save nonces in the database. +- [x] Devise will automatically expire sessions on sign in and sign out with `config.expire_all_remember_me_on_sign_out = true`. -### 2 Sessions -1. `config.force_ssl = true` is set for production environments. -1. Provided the user with a logout button. -1. Using Devise's Session Controller to manage session storage. -1. Cookies stored client side do not contain sensitive information. -1. Cookies time out in 15 minutes of inactivity with devise `config.timeout_in`. -1. Cookies are encrypted client side. -1. Devise uses BCrypt and the secret_key_base by default for secret hashing. -1. **@TODO:** If we want to expire sessions after a set amount of time, regardless of activity, those changes would need to be enforced by the auth service, such as in AWS Cognito. -1. **TODO:** We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito. -1. **TODO:** We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) This however ties users to a particular server/session as we don’t want to save nonces in the database. -1. Devise will automatically expire sessions on sign in and sign out with `config.expire_all_remember_me_on_sign_out = true`. +## Cross-Site Request Forgery (CSRF) +- [x] GET, POST, DELETE, and rails’ resources are used appropriately in the `routes.rb` file. +- [ ] We’re not setting forgery protection in production despite passing a CSRF token to the client, therefore If I change my CSRF token manually in my browser, I’m not prevented from taking any actions (GET or POST requests) as a signed in user. -### 3 Cross-Site Request Forgery (CSRF) -1. GET, POST, DELETE, and rails’ resources are used appropriately in the `routes.rb` file. -1. **TODO:** We’re not setting forgery protection in production despite passing a CSRF token to the client, therefore If I change my CSRF token manually in my browser, I’m not prevented from taking any actions (GET or POST requests) as a signed in user. +## Redirection and Files +- [x] link_tos do not route to user inputs, which is XSS vulnerable. +- [x] redirect_to does not use params or user inputs in the routes. +- [ ] App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications. -### 4 Redirection and Files -1. link_tos do not route to user inputs, which is XSS vulnerable. -1. redirect_to does not use params or user inputs in the routes. -1. **TODO:** App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications. +## User Management +- [x] When using Devise we don’t need to set `has_secure_password` on password fields. +- [x] Username error is generic and does not indicate whether it was an error with the username or password. +- [x] Forgot password confirms the email was sent, and not whether the username exists. +- [x] Change password includes email 6 digit code. +- [ ] We currently do not require entering the password when changing email, but we should. +- [ ] Include Captcha on account creation, login, change password, and change email. +- [ ] Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html). +- [x] We’re filtering the following parameter partials (if all or any part matches) in the `config/initialization/filter_paramater_logging.rb` file: `:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn`. +- [x] Two places where regex is used (`mailto.rb` and devise) use the correct ruby `\A` and `\z` and not the more common: `/^` and `$/`. +- [ ] Add multiline: true to our regex format: in validations. +- [ ] By manually changing a parameter, a hacker may get access to information they should not be able to access. Instead of doing things like: `@task = Task.find(params[:id])`, instead do `@user.tasks.find(params[:id])`. This is not in the template, but it is in the app the template is based on. -### 5. User Management -1. When using Devise we don’t need to set `has_secure_password` on password fields. -1. Username error is generic and does not indicate whether it was an error with the username or password. -1. Forgot password confirms the email was sent, and not whether the username exists. -1. Change password includes email 6 digit code. -1. **@TODO:** We currently do not require entering the password when changing email, but we should. -1. **TODO:** Include Captcha on account creation, login, change password, and change email. -1. **TODO:** Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html). -1. We’re filtering the following parameter partials (if all or any part matches) in the `config/initialization/filter_paramater_logging.rb` file: `:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn`. -1. Two places where regex is used (`mailto.rb` and devise) use the correct ruby `\A` and `\z` and not the more common: `/^` and `$/`. -1. **TODO:** Add multiline: true to our regex format: in validations. -1. **TODO:** By manually changing a parameter, a hacker may get access to information they should not be able to access. Instead of doing things like: `@task = Task.find(params[:id])`, instead do `@user.tasks.find(params[:id])`. This is not in the template, but it is in the app the template is based on. - -### 6 Injection -1. **TODO:** Use `except: […]` instead of `only:[…]` for security related actions so when adding actions, they are behind the security by default. Ex. `app-rails/app/controllers/application_controller.rb line: 8`. `after_action :verify_policy_scoped, only: :index`. -1. Not generally an issue with rails applications. We aren’t interpolating params into SQL fragments, which would also be against ruby and rails best practices, ie. .where(“name = `#{params[:name]}`”. -1. While we’re not setting secure: true on the cookies themselves, the `config.force_ssl = true` option in production ensures all cookies are `httponly`. -1. The template application doesn't have any inputs that are then displayed to the user, aside from the user email, which prevents scripting. However, when those inputs are created, it will be important to sanitize the outputs in the erb files, using `<%=h =>` to protect against defacement. -1. An additional step can be taken to sanitize inputs, but those should use a permitted list of tags, instead of restricted lists, using: +## Injection +- [ ] Use `except: […]` instead of `only:[…]` for security related actions so when adding actions, they are behind the security by default. Ex. `app-rails/app/controllers/application_controller.rb line: 8`. `after_action :verify_policy_scoped, only: :index`. +- [x] Not generally an issue with rails applications. We aren’t interpolating params into SQL fragments, which would also be against ruby and rails best practices, ie. .where(“name = `#{params[:name]}`”. +- [x] While we’re not setting secure: true on the cookies themselves, the `config.force_ssl = true` option in production ensures all cookies are `httponly`. +- [x] The template application doesn't have any inputs that are then displayed to the user, aside from the user email, which prevents scripting. However, when those inputs are created, it will be important to sanitize the outputs in the erb files, using `<%=h =>` to protect against defacement. +- [x] An additional step can be taken to sanitize inputs, but those should use a permitted list of tags, instead of restricted lists, using: ``` tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) s = sanitize(user_input, tags: tags, attributes: %w(href title)) ``` -1. While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection, and the Rails sanitize() method should be used on inputs that will be presented to the UI at any point. -1. This is rarely needed as applications, especially government applications, rarely if ever offer the user the ability to input custom colors or input css filters. -1. This template application doesn't allow users to enter text to be converted into html, that's more common in content management system applications. If that feature set is added, it is important to do so with a permitted input filter similar to 6.3.2.3 Defacement Countermeasures. The most common Rails tool for text to html conversion is RedCloth, which is being mentioned in case folks search the repo for RedCloth, they should find this recommendation. -1. The output has to be escaped in the controller already, if the action doesn't render a view. However, we have no case of outputting strings rather than views in our template application. However, rendering data from the controller seems like a Rails anti-pattern. -1. Only relevant if the application takes a user input and executes a command on the underlying operating system. Applicable methods include: - 1. `system()` - 1. `exec()` - 1. `spawn()` - 1. `command` -1. Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. Using `open()` method seems like a Rails anti-pattern so this shouldn't be an issue. -1. This applies to adding user input to the `` tags in erb files, using the `content_for :head` method in erb files, and adding user input to a response with `head :some_header` in controllers. The template doesn't use any of those features, but this may come up in the future. -1. **TODO:** Configure [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) in production to prevent DNS rebinding attacks. -1. This template uses rails version > 2.1.2, therefore this is not a concern. +- [x] While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection, and the Rails sanitize() method should be used on inputs that will be presented to the UI at any point. +- [x] This is rarely needed as applications, especially government applications, rarely if ever offer the user the ability to input custom colors or input css filters. +- [x] This template application doesn't allow users to enter text to be converted into html, that's more common in content management system applications. If that feature set is added, it is important to do so with a permitted input filter similar to 6.3.2.3 Defacement Countermeasures. The most common Rails tool for text to html conversion is RedCloth, which is being mentioned in case folks search the repo for RedCloth, they should find this recommendation. +- [x] The output has to be escaped in the controller already, if the action doesn't render a view. However, we have no case of outputting strings rather than views in our template application. However, rendering data from the controller seems like a Rails anti-pattern. +- [x] Only relevant if the application takes a user input and executes a command on the underlying operating system. Applicable methods include: + * `system()` + * `exec()` + * `spawn()` + * `command` +- [x] Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. Using `open()` method seems like a Rails anti-pattern so this shouldn't be an issue. +- [x] This applies to adding user input to the `` tags in erb files, using the `content_for :head` method in erb files, and adding user input to a response with `head :some_header` in controllers. The template doesn't use any of those features, but this may come up in the future. +- [ ] Configure [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) in production to prevent DNS rebinding attacks. +- [x] This template uses rails version > 2.- [x]2, therefore this is not a concern. -### 7 Unsafe Query Generation -1. Unless you know what you're doing, don't disable `deep_munge` with `config.action_dispatch.perform_deep_munge = false` +## Unsafe Query Generation +- [x] Unless you know what you're doing, don't disable `deep_munge` with `config.action_dispatch.perform_deep_munge = false` -### 8 HTTP Security Headers -1. Rails locks down the headers by default, and we have no need to open these up. However, the defaults can be overridden in `config/application.rb` with `config.action_dispatch.default_headers`. -1. X-Frame-Options is set to allow iframes from the same origin, set this to deny if not using any iframes to embed. If you need to permit an iframe from another origin, a controller can then use an `after_action :allow_some_service`. -1. This is set in production with `config.force_ssl = true` -1. **TODO:** To help protect against XSS and injection attacks, define a Content-Security-Policy in the provided file: `app-rails/config/initializers/content_security_policy.rb`. The policy can be more restrictive, and controllers can override defaults when necessary. -1. **TODO:** In addition to preventing attacks, it's important to log them to continuously improve security. Set the report_uri config on the content security policy and configure a controller to log the reports. Note that `report_uri` is being deprecated, and will eventually become `report_to` -1. **TODO:** We're already adding the `csp_meta_tag` to the application.html.erb, but we're not taking advantage of it with nonce generation in the content security policy. -1. **TODO:** Configure which browser features are allowed in `app-rails/config/initializers/permissions_policy.rb`. This policy can be more restrictive than necessary because features can be allowed on specific controllers. -1. As of now, this application envisioned as a full-stack application template. However, if there is a need to open up endpoints as APIs, we need to configure CORS, by installing and configuring the `rack-cors` gem. +## HTTP Security Headers +- [x] Rails locks down the headers by default, and we have no need to open these up. However, the defaults can be overridden in `config/application.rb` with `config.action_dispatch.default_headers`. +- [x] X-Frame-Options is set to allow iframes from the same origin, set this to deny if not using any iframes to embed. If you need to permit an iframe from another origin, a controller can then use an `after_action :allow_some_service`. +- [x] This is set in production with `config.force_ssl = true` +- [ ] To help protect against XSS and injection attacks, define a Content-Security-Policy in the provided file: `app-rails/config/initializers/content_security_policy.rb`. The policy can be more restrictive, and controllers can override defaults when necessary. +- [ ] In addition to preventing attacks, it's important to log them to continuously improve security. Set the report_uri config on the content security policy and configure a controller to log the reports. Note that `report_uri` is being deprecated, and will eventually become `report_to` +- [ ] We're already adding the `csp_meta_tag` to the application.html.erb, but we're not taking advantage of it with nonce generation in the content security policy. +- [ ] Configure which browser features are allowed in `app-rails/config/initializers/permissions_policy.rb`. This policy can be more restrictive than necessary because features can be allowed on specific controllers. +- [x] As of now, this application envisioned as a full-stack application template. However, if there is a need to open up endpoints as APIs, we need to configure CORS, by installing and configuring the `rack-cors` gem. -### 9 Intranet and Admin Security -1. The template doesn't include a admin view, but if that is added, be sure to sanitize all user inputs as they may be viewed here even if they aren't visible anywhere else in the application. -1. Same as CSRF countermeasures discussed above. -1. Some effective admin protection strategies includes: +## Intranet and Admin Security +- [x] The template doesn't include a admin view, but if that is added, be sure to sanitize all user inputs as they may be viewed here even if they aren't visible anywhere else in the application. +- [x] Same as CSRF countermeasures discussed above. +- [x] Some effective admin protection strategies includes: * Limit admin role privileges using the principle of least privilege * Geofence admin login IP to the USA. * Consider putting the admin app at a subdomain so the cookie for application can't be used for the admin console and vice-versa. -### 10 Environmental Security -1. Secret management is covered in the template infrastructure repo and is out of scope of this template application. +## Environmental Security +- [x] Secret management is covered in the template infrastructure repo and is out of scope of this template application. + +## Dependency Management and CVEs' +- [x] We're using dependabot to notify us if we have outdated gems. -### 11 Dependency Management and CVEs' -1. We're using dependabot to notify us if we have outdated gems. +## Additional Reading +* [Securing Rails Applications](https://guides.rubyonrails.org/security.html) From 11073985591446dce6686d02aef590c8cf1ff754 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 17:16:59 -0400 Subject: [PATCH 14/34] CSRF section --- docs/app-rails/application-security.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index c0ec1b6..148ebfa 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -7,21 +7,26 @@ Each item below will be checked if it is already implemented by default, or unch This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit this project's Rails security best practices. ## Sessions -- [x] `config.force_ssl = true` is set for production environments. -- [x] Provided the user with a logout button. -- [x] Using Devise's Session Controller to manage session storage. +This template application uses Devise to manage sessions and cookies. You can manage the Devise configuration in the [`devise.rb`](app-rails/config/initializers/devise.rb) file, and for more detailed information you can read the [Devise documentation](https://rubydoc.info/github/heartcombo/devise). +- [x] SSL (`config.force_ssl = true`) is enforced in production environments. +- [x] Provide the user with a prominent logout button to make it easy to clear the session on public computers. - [x] Cookies stored client side do not contain sensitive information. -- [x] Cookies time out in 15 minutes of inactivity with devise `config.timeout_in`. +- [x] Cookies time out in 15 minutes of inactivity + - Note: That is set with `config.timeout_in` in the Devise configuration file. - [x] Cookies are encrypted client side. -- [x] Devise uses BCrypt and the secret_key_base by default for secret hashing. -- [ ] If we want to expire sessions after a set amount of time, regardless of activity, those changes would need to be enforced by the auth service, such as in AWS Cognito. -- [ ] We are not rotating secrets for hashing nor the hashing algorithm, could do with cognito. -- [ ] We’re not using a nonce generator that would protect against cookie replay attacks. The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) This however ties users to a particular server/session as we don’t want to save nonces in the database. -- [x] Devise will automatically expire sessions on sign in and sign out with `config.expire_all_remember_me_on_sign_out = true`. + - Note: Devise uses BCrypt and the secret_key_base by default for secret hashing. +- [ ] Expire sessions after a set amount of time, regardless of activity, + - Note: Automated session expiration can be easily set by the auth service, such as in AWS Cognito. +- [ ] Use a nonce generator to protect against cookie replay attacks. + - Note: The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) Review the impact this may have on your application if you have several application servers. +- [x] Automatically expire sessions on sign in and sign out. + - Note. This is set in the Devise configuration file with `config.expire_all_remember_me_on_sign_out = true`. ## Cross-Site Request Forgery (CSRF) - [x] GET, POST, DELETE, and rails’ resources are used appropriately in the `routes.rb` file. -- [ ] We’re not setting forgery protection in production despite passing a CSRF token to the client, therefore If I change my CSRF token manually in my browser, I’m not prevented from taking any actions (GET or POST requests) as a signed in user. +- [x] Pass a CSRF token to the client. + - Note: This is accomplished with `<%= csrf_meta_tags %>` in [application.html.erb](app-rails/app/views/layouts/application.html.erb) +- [ ] Set forgery protection in production ## Redirection and Files - [x] link_tos do not route to user inputs, which is XSS vulnerable. From 61b79235fd03f4363942745fabcd082a981e5999 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 17:29:12 -0400 Subject: [PATCH 15/34] Redirection and Files section --- docs/app-rails/application-security.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 148ebfa..7ffd4db 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -12,7 +12,7 @@ This template application uses Devise to manage sessions and cookies. You can ma - [x] Provide the user with a prominent logout button to make it easy to clear the session on public computers. - [x] Cookies stored client side do not contain sensitive information. - [x] Cookies time out in 15 minutes of inactivity - - Note: That is set with `config.timeout_in` in the Devise configuration file. + - Note: That is set with `config.timeout_in` in the [Devise configuration file](app-rails/config/initializers/devise.rb). - [x] Cookies are encrypted client side. - Note: Devise uses BCrypt and the secret_key_base by default for secret hashing. - [ ] Expire sessions after a set amount of time, regardless of activity, @@ -20,7 +20,7 @@ This template application uses Devise to manage sessions and cookies. You can ma - [ ] Use a nonce generator to protect against cookie replay attacks. - Note: The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) Review the impact this may have on your application if you have several application servers. - [x] Automatically expire sessions on sign in and sign out. - - Note. This is set in the Devise configuration file with `config.expire_all_remember_me_on_sign_out = true`. + - Note. This is set in the [Devise configuration file](app-rails/config/initializers/devise.rb) with `config.expire_all_remember_me_on_sign_out = true`. ## Cross-Site Request Forgery (CSRF) - [x] GET, POST, DELETE, and rails’ resources are used appropriately in the `routes.rb` file. @@ -29,9 +29,16 @@ This template application uses Devise to manage sessions and cookies. You can ma - [ ] Set forgery protection in production ## Redirection and Files -- [x] link_tos do not route to user inputs, which is XSS vulnerable. -- [x] redirect_to does not use params or user inputs in the routes. -- [ ] App doesn’t currently handle file imports but that should be documented as it is a common need in Government Applications. +The template application doesn't have any file upload or download functionality at this time, so please review these items when adding file management functionality. +- [x] Do not use user inputs to generate routes (ie. creating a route with the username), which is vulnerable to XSS attacks. + - [x] `link_to` methods do not interpolate to user inputs. + - [x] `redirect_to` methods do not interpolate to user inputs. +- [ ] Check filename for file imports against a set of permitted characters. + - Note: filtering filename imports alone can still leave an application vulnerable to XSS attacks. +- [ ] Do not allow file uploads to place files in the public directory as code in those files may be executed by the browser. +- [ ] Prevent users from downloading files to which they shouldn't have access. + - [ ] Check filename for download against a set of permitted characters. + - [ ] Check the file returned from the search is from the appropriate directory. ## User Management - [x] When using Devise we don’t need to set `has_secure_password` on password fields. From c25f99c8b9b31b4daabc6821d2a9c490b04cb97d Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 18:37:06 -0400 Subject: [PATCH 16/34] User Management section --- docs/app-rails/application-security.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 7ffd4db..0204cf4 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -41,17 +41,22 @@ The template application doesn't have any file upload or download functionality - [ ] Check the file returned from the search is from the appropriate directory. ## User Management -- [x] When using Devise we don’t need to set `has_secure_password` on password fields. +- [x] Store only cryptographically hashed passwords, not plain-text passwords. +- [x] Consider Rails' built-in `has_secure_password` method which supports secure password hashing, confirmation, and recovery mechanisms. + - Note: When using Devise there's no need to use `has_secure_password`. - [x] Username error is generic and does not indicate whether it was an error with the username or password. - [x] Forgot password confirms the email was sent, and not whether the username exists. -- [x] Change password includes email 6 digit code. -- [ ] We currently do not require entering the password when changing email, but we should. -- [ ] Include Captcha on account creation, login, change password, and change email. +- [x] Use a secondary verification when users change their password + - Note: Change password requires 6 digit code from email sent to user's email address. +- [ ] Require user's password when changing email. - [ ] Include honeypot fields and logic on Non logged in forms to catch bots that spam all fields (good resource: https://nedbatchelder.com/text/stopbots.html). -- [x] We’re filtering the following parameter partials (if all or any part matches) in the `config/initialization/filter_paramater_logging.rb` file: `:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn`. -- [x] Two places where regex is used (`mailto.rb` and devise) use the correct ruby `\A` and `\z` and not the more common: `/^` and `$/`. +- [ ] Consider using Captcha on account creation, login, change password, and change email forms. + - Note: Captchas are often not accessible to screen readers and their use should be part of a UX discussion. +- [x] Filter log entries so they do not include passwords or secrets + - Note: Log filtering is set in [filter_parameter_logging.rb](app-rails/config/initializers/filter_parameter_logging.rb): `:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn`. +- [x] Use the correct Ruby REGEX: `\A` and `\z` and not the more common: `/^` and `$/`. - [ ] Add multiline: true to our regex format: in validations. -- [ ] By manually changing a parameter, a hacker may get access to information they should not be able to access. Instead of doing things like: `@task = Task.find(params[:id])`, instead do `@user.tasks.find(params[:id])`. This is not in the template, but it is in the app the template is based on. +- [x] When searching for data belonging to the user, search using Active Record from the user and not from the target data object. ie. Instead of doing: `@task = Task.find(params[:id])`, instead do: `@user.tasks.find(params[:id])`. ## Injection - [ ] Use `except: […]` instead of `only:[…]` for security related actions so when adding actions, they are behind the security by default. Ex. `app-rails/app/controllers/application_controller.rb line: 8`. `after_action :verify_policy_scoped, only: :index`. From eecc240a49ab1d4ed96cbae76693bba8a9204e98 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 18:38:32 -0400 Subject: [PATCH 17/34] Unsafe Query Generation --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 0204cf4..f8b95fe 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -83,7 +83,7 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title)) - [x] This template uses rails version > 2.- [x]2, therefore this is not a concern. ## Unsafe Query Generation -- [x] Unless you know what you're doing, don't disable `deep_munge` with `config.action_dispatch.perform_deep_munge = false` +- [x] Enable `deep_munge` with `config.action_dispatch.perform_deep_munge = true` ## HTTP Security Headers - [x] Rails locks down the headers by default, and we have no need to open these up. However, the defaults can be overridden in `config/application.rb` with `config.action_dispatch.default_headers`. From 24acba2ebc541cc4e1b5d946acd9e3a4c7fc9ec9 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 18:53:01 -0400 Subject: [PATCH 18/34] HTTP Security Headers section --- docs/app-rails/application-security.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index f8b95fe..29fe862 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -83,17 +83,24 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title)) - [x] This template uses rails version > 2.- [x]2, therefore this is not a concern. ## Unsafe Query Generation -- [x] Enable `deep_munge` with `config.action_dispatch.perform_deep_munge = true` +- [x] Confirm `deep_munge` hasn't been disabled. + - Note: `config.action_dispatch.perform_deep_munge` is `true` by default. ## HTTP Security Headers -- [x] Rails locks down the headers by default, and we have no need to open these up. However, the defaults can be overridden in `config/application.rb` with `config.action_dispatch.default_headers`. -- [x] X-Frame-Options is set to allow iframes from the same origin, set this to deny if not using any iframes to embed. If you need to permit an iframe from another origin, a controller can then use an `after_action :allow_some_service`. -- [x] This is set in production with `config.force_ssl = true` -- [ ] To help protect against XSS and injection attacks, define a Content-Security-Policy in the provided file: `app-rails/config/initializers/content_security_policy.rb`. The policy can be more restrictive, and controllers can override defaults when necessary. -- [ ] In addition to preventing attacks, it's important to log them to continuously improve security. Set the report_uri config on the content security policy and configure a controller to log the reports. Note that `report_uri` is being deprecated, and will eventually become `report_to` -- [ ] We're already adding the `csp_meta_tag` to the application.html.erb, but we're not taking advantage of it with nonce generation in the content security policy. -- [ ] Configure which browser features are allowed in `app-rails/config/initializers/permissions_policy.rb`. This policy can be more restrictive than necessary because features can be allowed on specific controllers. -- [x] As of now, this application envisioned as a full-stack application template. However, if there is a need to open up endpoints as APIs, we need to configure CORS, by installing and configuring the `rack-cors` gem. +Default security headers can be overridden in [application.rb](app-rails/config/application.rb) with `config.action_dispatch.default_headers`. +- [x] Lock down X-Frame-Options to be as restrictive as possible. + - Note: By default this is set to allow iframes from the same origin. + - Note: Set this to deny if not using any iframes to embed. + - Note: If you need to permit an iframe from another origin, a controller can then use an `after_action :allow_some_service`. +- [ ] To help protect against XSS and injection attacks, define a Content-Security-Policy in the provided [content security policy file](app-rails/config/initializers/content_security_policy.rb). + - Note: Set the policy to be more restrictive than you need and you can override defaults when necessary in the controllers. +- [ ] Log content security policy violations to continuously improve security by setting the report_uri config on the content security policy and configure a controller to log the reports. + - Note: `report_uri` is being deprecated, and will eventually become `report_to`. +- [x] Set `csp_meta_tag` in [application.rb](app-rails/config/application.rb). +- [ ] Use the `csp_meta_tag` tag with nonce generation in the content security policy. +- [ ] Configure which browser features are allowed in [permissions_policy.rb](app-rails/config/initializers/permissions_policy.rb). + - Note: This policy can be more restrictive than necessary because features can be allowed on specific controllers. +- [ ] If opening up endpoints as APIs, configure CORS, by installing and configuring the `rack-cors` gem. ## Intranet and Admin Security - [x] The template doesn't include a admin view, but if that is added, be sure to sanitize all user inputs as they may be viewed here even if they aren't visible anywhere else in the application. From ad4bf1520b2fd94b93e5d1fb03ca6efa4fd271a9 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Mon, 10 Jun 2024 18:56:25 -0400 Subject: [PATCH 19/34] Admin section --- docs/app-rails/application-security.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 29fe862..45d6915 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -103,18 +103,19 @@ Default security headers can be overridden in [application.rb](app-rails/config/ - [ ] If opening up endpoints as APIs, configure CORS, by installing and configuring the `rack-cors` gem. ## Intranet and Admin Security -- [x] The template doesn't include a admin view, but if that is added, be sure to sanitize all user inputs as they may be viewed here even if they aren't visible anywhere else in the application. -- [x] Same as CSRF countermeasures discussed above. -- [x] Some effective admin protection strategies includes: - * Limit admin role privileges using the principle of least privilege - * Geofence admin login IP to the USA. - * Consider putting the admin app at a subdomain so the cookie for application can't be used for the admin console and vice-versa. +If adding an Admin view, consider adding the following: +- [ ] Sanitize all user inputs as they may be viewed here even if they aren't visible anywhere else in the application. +Some effective admin protection strategies include: + - [ ] Limit admin role privileges using the principle of least privilege + - [ ] Geofence admin login IP to the USA. + - [ ] Consider putting the admin app at a subdomain so the cookie for application can't be used for the admin console and vice-versa. ## Environmental Security -- [x] Secret management is covered in the template infrastructure repo and is out of scope of this template application. +- [x] Secrets are not stored in the application repository. ## Dependency Management and CVEs' -- [x] We're using dependabot to notify us if we have outdated gems. +- [x] Use a service to be notified when libraries are outdated + - Note: We're using dependabot to notify us if we have outdated gems. ## Additional Reading * [Securing Rails Applications](https://guides.rubyonrails.org/security.html) From 00f2c78b34c1591f22d1184631e1b3cff30e1f50 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Tue, 11 Jun 2024 09:09:57 -0400 Subject: [PATCH 20/34] Injection section --- docs/app-rails/application-security.md | 31 ++++++++++++++------------ 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 45d6915..923ab5f 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -59,28 +59,31 @@ The template application doesn't have any file upload or download functionality - [x] When searching for data belonging to the user, search using Active Record from the user and not from the target data object. ie. Instead of doing: `@task = Task.find(params[:id])`, instead do: `@user.tasks.find(params[:id])`. ## Injection -- [ ] Use `except: […]` instead of `only:[…]` for security related actions so when adding actions, they are behind the security by default. Ex. `app-rails/app/controllers/application_controller.rb line: 8`. `after_action :verify_policy_scoped, only: :index`. -- [x] Not generally an issue with rails applications. We aren’t interpolating params into SQL fragments, which would also be against ruby and rails best practices, ie. .where(“name = `#{params[:name]}`”. -- [x] While we’re not setting secure: true on the cookies themselves, the `config.force_ssl = true` option in production ensures all cookies are `httponly`. -- [x] The template application doesn't have any inputs that are then displayed to the user, aside from the user email, which prevents scripting. However, when those inputs are created, it will be important to sanitize the outputs in the erb files, using `<%=h =>` to protect against defacement. -- [x] An additional step can be taken to sanitize inputs, but those should use a permitted list of tags, instead of restricted lists, using: +- [ ] When defining security related `before_action` and `after_action` on controllers, use `except: […]` instead of `only:[…]` Ie. Instead of `after_action :verify_policy_scoped, only: :index` use `after_action :verify_policy_scoped, except:[ :rails_health_check, :users, :dev, ...]`. This ensures that when new views are added, they're behind the security actions by default. +- [x] Don't interpolate params into SQL fragments. Ie. `.where(“name ='#{params[:name]}'”`. +- [x] Ensures all cookies are `httponly`. + - Note: While we’re not setting `secure: true` on the cookies themselves, the `config.force_ssl = true` option in production sets them as `httponly`. +- [x] Sanitize content in the erb files that come from user inputs, using `<%=h =>` to protect against defacement. +- [x] Use a permitted list of tags in inputs that allow html or when allowing a text input that will be converted into html, using: + - Note: The most common Rails tool for text to html conversion is RedCloth. ``` tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) s = sanitize(user_input, tags: tags, attributes: %w(href title)) ``` -- [x] While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection, and the Rails sanitize() method should be used on inputs that will be presented to the UI at any point. -- [x] This is rarely needed as applications, especially government applications, rarely if ever offer the user the ability to input custom colors or input css filters. -- [x] This template application doesn't allow users to enter text to be converted into html, that's more common in content management system applications. If that feature set is added, it is important to do so with a permitted input filter similar to 6.3.2.3 Defacement Countermeasures. The most common Rails tool for text to html conversion is RedCloth, which is being mentioned in case folks search the repo for RedCloth, they should find this recommendation. -- [x] The output has to be escaped in the controller already, if the action doesn't render a view. However, we have no case of outputting strings rather than views in our template application. However, rendering data from the controller seems like a Rails anti-pattern. -- [x] Only relevant if the application takes a user input and executes a command on the underlying operating system. Applicable methods include: +- [x] Rails sanitize() method is used on inputs that will be presented to the UI, including the Admin UI if there is one. + - Note: While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection. +- [ ] Inputs for custom colors or CSS filters are sanitized with Rail's `sanitize()` method, and the application builds the CSS in the web application first and ensures it is valid CSS before sanitizing. + - Note: This application currently doesn't have that functionality, but this is a common attack vector in application that do have this functionality. +- [x] Controllers that output strings, rather than views, are escaped. +- [x] All methods called by the application to execute commands on the underlying operating system include the `parameters` parameter, ie. `system(command, parameters)`. Applicable methods include: * `system()` * `exec()` * `spawn()` * `command` -- [x] Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. Using `open()` method seems like a Rails anti-pattern so this shouldn't be an issue. -- [x] This applies to adding user input to the `` tags in erb files, using the `content_for :head` method in erb files, and adding user input to a response with `head :some_header` in controllers. The template doesn't use any of those features, but this may come up in the future. -- [ ] Configure [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) in production to prevent DNS rebinding attacks. -- [x] This template uses rails version > 2.- [x]2, therefore this is not a concern. +- [x] Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. +- [ ] User inputs that are added to the document header and appear in the `` tags in erb files, use the `content_for :head` method in erb files, and adding user input to a response with `head :some_header` in controllers. + - Note: The template doesn't use any of those features, but this may come up in the future. +- [ ] [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) is configured in production to prevent DNS rebinding attacks. ## Unsafe Query Generation - [x] Confirm `deep_munge` hasn't been disabled. From 11be9c541b0c9a247c02888cf1e0a44805cf4c9c Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Tue, 11 Jun 2024 11:25:51 -0400 Subject: [PATCH 21/34] authorization library --- docs/app-rails/application-security.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 923ab5f..27f0296 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -57,6 +57,7 @@ The template application doesn't have any file upload or download functionality - [x] Use the correct Ruby REGEX: `\A` and `\z` and not the more common: `/^` and `$/`. - [ ] Add multiline: true to our regex format: in validations. - [x] When searching for data belonging to the user, search using Active Record from the user and not from the target data object. ie. Instead of doing: `@task = Task.find(params[:id])`, instead do: `@user.tasks.find(params[:id])`. + - Note: This application is also using [pundit](https://github.com/varvet/pundit) to support resource authorization. ## Injection - [ ] When defining security related `before_action` and `after_action` on controllers, use `except: […]` instead of `only:[…]` Ie. Instead of `after_action :verify_policy_scoped, only: :index` use `after_action :verify_policy_scoped, except:[ :rails_health_check, :users, :dev, ...]`. This ensures that when new views are added, they're behind the security actions by default. From 5cad12f180f7b84e5422c17601affcb837dbbc64 Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:25:21 -0400 Subject: [PATCH 22/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 27f0296..7213559 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -33,7 +33,7 @@ The template application doesn't have any file upload or download functionality - [x] Do not use user inputs to generate routes (ie. creating a route with the username), which is vulnerable to XSS attacks. - [x] `link_to` methods do not interpolate to user inputs. - [x] `redirect_to` methods do not interpolate to user inputs. -- [ ] Check filename for file imports against a set of permitted characters. +- [ ] Prevent files from being uploaded if the filename do not match a set of permitted characters. - Note: filtering filename imports alone can still leave an application vulnerable to XSS attacks. - [ ] Do not allow file uploads to place files in the public directory as code in those files may be executed by the browser. - [ ] Prevent users from downloading files to which they shouldn't have access. From ac26ad0a738f8b905929f699bb2a7f0e717c1dee Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:25:40 -0400 Subject: [PATCH 23/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 7213559..889edc0 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -7,7 +7,7 @@ Each item below will be checked if it is already implemented by default, or unch This document uses the Rails Guide to [Securing Rails Applications](https://guides.rubyonrails.org/security.html) to audit this project's Rails security best practices. ## Sessions -This template application uses Devise to manage sessions and cookies. You can manage the Devise configuration in the [`devise.rb`](app-rails/config/initializers/devise.rb) file, and for more detailed information you can read the [Devise documentation](https://rubydoc.info/github/heartcombo/devise). +We use Devise to manage sessions and cookies. Devise configuration is managed in the [`devise.rb`](app-rails/config/initializers/devise.rb) file. For more detailed information, see the [Devise documentation](https://rubydoc.info/github/heartcombo/devise). - [x] SSL (`config.force_ssl = true`) is enforced in production environments. - [x] Provide the user with a prominent logout button to make it easy to clear the session on public computers. - [x] Cookies stored client side do not contain sensitive information. From eb76cc25f185860a27e57adb0c9d9218c00e8148 Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:25:51 -0400 Subject: [PATCH 24/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 889edc0..5db2086 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -18,7 +18,7 @@ We use Devise to manage sessions and cookies. Devise configuration is managed in - [ ] Expire sessions after a set amount of time, regardless of activity, - Note: Automated session expiration can be easily set by the auth service, such as in AWS Cognito. - [ ] Use a nonce generator to protect against cookie replay attacks. - - Note: The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) Review the impact this may have on your application if you have several application servers. + - Note: The commented out code for this is located in [`/app-rails/config/initializers/content_security_policy.rb`](/app-rails/config/initializers/content_security_policy.rb) Review the impact this may have if there are several application servers. - [x] Automatically expire sessions on sign in and sign out. - Note. This is set in the [Devise configuration file](app-rails/config/initializers/devise.rb) with `config.expire_all_remember_me_on_sign_out = true`. From fc9fd5aac0df0e56a4970688e2dc5658f1e2e010 Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:26:02 -0400 Subject: [PATCH 25/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 5db2086..1c4269d 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -29,7 +29,7 @@ We use Devise to manage sessions and cookies. Devise configuration is managed in - [ ] Set forgery protection in production ## Redirection and Files -The template application doesn't have any file upload or download functionality at this time, so please review these items when adding file management functionality. +There is currently no file upload or download functionality at this time, so please review these items when adding file management functionality. - [x] Do not use user inputs to generate routes (ie. creating a route with the username), which is vulnerable to XSS attacks. - [x] `link_to` methods do not interpolate to user inputs. - [x] `redirect_to` methods do not interpolate to user inputs. From bcf247201226d67e31e6a1ab26a11e365dc712f2 Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:26:23 -0400 Subject: [PATCH 26/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 1c4269d..9dfc299 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -34,7 +34,7 @@ There is currently no file upload or download functionality at this time, so ple - [x] `link_to` methods do not interpolate to user inputs. - [x] `redirect_to` methods do not interpolate to user inputs. - [ ] Prevent files from being uploaded if the filename do not match a set of permitted characters. - - Note: filtering filename imports alone can still leave an application vulnerable to XSS attacks. + - Note: Filtering on filename on its own can still leave an application vulnerable to XSS attacks. - [ ] Do not allow file uploads to place files in the public directory as code in those files may be executed by the browser. - [ ] Prevent users from downloading files to which they shouldn't have access. - [ ] Check filename for download against a set of permitted characters. From 44fb76b4be34fdd066258fe0f31a725b066df96b Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:26:42 -0400 Subject: [PATCH 27/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 9dfc299..6c006dd 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -71,7 +71,7 @@ There is currently no file upload or download functionality at this time, so ple tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) s = sanitize(user_input, tags: tags, attributes: %w(href title)) ``` -- [x] Rails sanitize() method is used on inputs that will be presented to the UI, including the Admin UI if there is one. +- [x] Rails `sanitize()` method is used on inputs that will be presented to the UI, including the Admin UI if there is one. - Note: While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection. - [ ] Inputs for custom colors or CSS filters are sanitized with Rail's `sanitize()` method, and the application builds the CSS in the web application first and ensures it is valid CSS before sanitizing. - Note: This application currently doesn't have that functionality, but this is a common attack vector in application that do have this functionality. From 6502eabcca0385c7ed1e916b387b28a8a329b5f2 Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:26:55 -0400 Subject: [PATCH 28/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 6c006dd..afaaf33 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -74,7 +74,7 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title)) - [x] Rails `sanitize()` method is used on inputs that will be presented to the UI, including the Admin UI if there is one. - Note: While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection. - [ ] Inputs for custom colors or CSS filters are sanitized with Rail's `sanitize()` method, and the application builds the CSS in the web application first and ensures it is valid CSS before sanitizing. - - Note: This application currently doesn't have that functionality, but this is a common attack vector in application that do have this functionality. + - Note: We don't include that functionality, but this is a common attack vector in applications that do. - [x] Controllers that output strings, rather than views, are escaped. - [x] All methods called by the application to execute commands on the underlying operating system include the `parameters` parameter, ie. `system(command, parameters)`. Applicable methods include: * `system()` From 37a847e79bd6a638d04042e369903b95c8814f1c Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:27:21 -0400 Subject: [PATCH 29/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index afaaf33..eaa4c1d 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -37,7 +37,7 @@ There is currently no file upload or download functionality at this time, so ple - Note: Filtering on filename on its own can still leave an application vulnerable to XSS attacks. - [ ] Do not allow file uploads to place files in the public directory as code in those files may be executed by the browser. - [ ] Prevent users from downloading files to which they shouldn't have access. - - [ ] Check filename for download against a set of permitted characters. + - [ ] Prevent files from being downloaded if the filename do not match a set of permitted characters. - [ ] Check the file returned from the search is from the appropriate directory. ## User Management From 5e9644a5840761fa9d6db58ed2be9e0403d2c55f Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:27:39 -0400 Subject: [PATCH 30/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index eaa4c1d..e230941 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -38,7 +38,7 @@ There is currently no file upload or download functionality at this time, so ple - [ ] Do not allow file uploads to place files in the public directory as code in those files may be executed by the browser. - [ ] Prevent users from downloading files to which they shouldn't have access. - [ ] Prevent files from being downloaded if the filename do not match a set of permitted characters. - - [ ] Check the file returned from the search is from the appropriate directory. + - [ ] For website search, prevent including files in the search results if the file is not from an appropriate directory. ## User Management - [x] Store only cryptographically hashed passwords, not plain-text passwords. From e342374e3c32d2a40d34a2de13ae4f7f4c233b17 Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 15:28:13 -0400 Subject: [PATCH 31/34] Update docs/app-rails/application-security.md Co-authored-by: Rocket --- docs/app-rails/application-security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index e230941..5239a69 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -55,7 +55,7 @@ There is currently no file upload or download functionality at this time, so ple - [x] Filter log entries so they do not include passwords or secrets - Note: Log filtering is set in [filter_parameter_logging.rb](app-rails/config/initializers/filter_parameter_logging.rb): `:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn`. - [x] Use the correct Ruby REGEX: `\A` and `\z` and not the more common: `/^` and `$/`. -- [ ] Add multiline: true to our regex format: in validations. +- [ ] Add `multiline: true` to regex `format:` in validations. - [x] When searching for data belonging to the user, search using Active Record from the user and not from the target data object. ie. Instead of doing: `@task = Task.find(params[:id])`, instead do: `@user.tasks.find(params[:id])`. - Note: This application is also using [pundit](https://github.com/varvet/pundit) to support resource authorization. From 5087f3816dffb1cfa5e5e559b7b7ff243d9bc3c6 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Tue, 18 Jun 2024 15:42:02 -0400 Subject: [PATCH 32/34] indent code block --- docs/app-rails/application-security.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 5239a69..241b763 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -67,10 +67,10 @@ There is currently no file upload or download functionality at this time, so ple - [x] Sanitize content in the erb files that come from user inputs, using `<%=h =>` to protect against defacement. - [x] Use a permitted list of tags in inputs that allow html or when allowing a text input that will be converted into html, using: - Note: The most common Rails tool for text to html conversion is RedCloth. -``` -tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) -s = sanitize(user_input, tags: tags, attributes: %w(href title)) -``` + ``` + tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) + s = sanitize(user_input, tags: tags, attributes: %w(href title)) + ``` - [x] Rails `sanitize()` method is used on inputs that will be presented to the UI, including the Admin UI if there is one. - Note: While consensus seems mixed about the necessity to sanitize Rails input fields for defacement, sanitizing inputs is very useful to protect against encoding injection. - [ ] Inputs for custom colors or CSS filters are sanitized with Rail's `sanitize()` method, and the application builds the CSS in the web application first and ensures it is valid CSS before sanitizing. From a92c34cba10ecb642c29a0dddafc5b2408abf6be Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Tue, 18 Jun 2024 15:58:39 -0400 Subject: [PATCH 33/34] header injection solution clarification --- docs/app-rails/application-security.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 241b763..4327a64 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -82,7 +82,9 @@ There is currently no file upload or download functionality at this time, so ple * `spawn()` * `command` - [x] Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. -- [ ] User inputs that are added to the document header and appear in the `` tags in erb files, use the `content_for :head` method in erb files, and adding user input to a response with `head :some_header` in controllers. +- [ ] User inputs that are interpolated to the HTML header element or are included in the response header set in a controller should: + - Use the `content_for :head` method in `.erb` files. + - Use `head :some_header` in controller where that user input is passed into the controller method. - Note: The template doesn't use any of those features, but this may come up in the future. - [ ] [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) is configured in production to prevent DNS rebinding attacks. From 7364aa169b7e490f2dca31364937fb21a8241e52 Mon Sep 17 00:00:00 2001 From: Sammy Steiner Date: Tue, 25 Jun 2024 09:44:59 -0400 Subject: [PATCH 34/34] Remove header interpolation guidance --- docs/app-rails/application-security.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/app-rails/application-security.md b/docs/app-rails/application-security.md index 4327a64..c274fc7 100644 --- a/docs/app-rails/application-security.md +++ b/docs/app-rails/application-security.md @@ -82,10 +82,6 @@ There is currently no file upload or download functionality at this time, so ple * `spawn()` * `command` - [x] Don't use the `open()` method to access files, instead use `File.open()` or `IO.open()` that will not execute commands. -- [ ] User inputs that are interpolated to the HTML header element or are included in the response header set in a controller should: - - Use the `content_for :head` method in `.erb` files. - - Use `head :some_header` in controller where that user input is passed into the controller method. - - Note: The template doesn't use any of those features, but this may come up in the future. - [ ] [`ActionDispatch::HostAuthorization`](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization) is configured in production to prevent DNS rebinding attacks. ## Unsafe Query Generation