From 5c2678056ac5d7af1a2f82a6e1e98401467cb5eb Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Sun, 12 Mar 2017 12:06:48 +0200 Subject: Fix typo in the security guide [ci skip] --- guides/source/security.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index a81a782cf2..a57c6ea247 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -615,7 +615,7 @@ The two dashes start a comment ignoring everything after it. So the query return Usually a web application includes access control. The user enters their login credentials and the web application tries to find the matching record in the users table. The application grants access when it finds a record. However, an attacker may possibly bypass this check with SQL injection. The following shows a typical database query in Rails to find the first record in the users table which matches the login credentials parameters supplied by the user. ```ruby -User.first("login = '#{params[:name]}' AND password = '#{params[:password]}'") +User.find_by("login = '#{params[:name]}' AND password = '#{params[:password]}'") ``` If an attacker enters ' OR '1'='1 as the name, and ' OR '2'>'1 as the password, the resulting SQL query will be: @@ -762,7 +762,7 @@ s = sanitize(user_input, tags: tags, attributes: %w(href title)) This allows only the given tags and does a good job, even against all kinds of tricks and malformed tags. -As a second step, _it is good practice to escape all output of the application_, especially when re-displaying user input, which hasn't been input-filtered (as in the search form example earlier on). _Use `escapeHTML()` (or its alias `h()`) method_ to replace the HTML input characters &, ", <, and > by their uninterpreted representations in HTML (`&`, `"`, `<`, and `>`). +As a second step, _it is good practice to escape all output of the application_, especially when re-displaying user input, which hasn't been input-filtered (as in the search form example earlier on). _Use `escapeHTML()` (or its alias `h()`) method_ to replace the HTML input characters &, ", <, and > by their uninterpreted representations in HTML (`&`, `"`, `<`, and `>`). ##### Obfuscation and Encoding Injection -- cgit v1.2.3 From 9cc2f50f9cc3191fd796af68d09826c67c02a572 Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Sat, 18 Mar 2017 22:41:15 -0400 Subject: Update some jquery-ujs references to rails-ujs [ci skip] --- guides/source/security.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index a57c6ea247..a14134f8c1 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -257,13 +257,12 @@ protect_from_forgery with: :exception This will automatically include a security token in all forms and Ajax requests generated by Rails. If the security token doesn't match what was expected, an exception will be thrown. -NOTE: By default, Rails includes jQuery and an [unobtrusive scripting adapter for -jQuery](https://github.com/rails/jquery-ujs), which adds a header called -`X-CSRF-Token` on every non-GET Ajax call made by jQuery with the security token. -Without this header, non-GET Ajax requests won't be accepted by Rails. When using -another library to make Ajax calls, it is necessary to add the security token as -a default header for Ajax calls in your library. To get the token, have a look at -`` tag printed by +NOTE: By default, Rails includes an [unobtrusive scripting adapter](https://github.com/rails/rails-ujs), +which adds a header called `X-CSRF-Token` with the security token on every non-GET +Ajax call. Without this header, non-GET Ajax requests won't be accepted by Rails. +When using another library to make Ajax calls, it is necessary to add the security +token as a default header for Ajax calls in your library. To get the token, have +a look at `` tag printed by `<%= csrf_meta_tags %>` in your application view. It is common to use persistent cookies to store user information, with `cookies.permanent` for example. In this case, the cookies will not be cleared and the out of the box CSRF protection will not be effective. If you are using a different cookie store than the session for this information, you must handle what to do with it yourself: -- cgit v1.2.3 From aed7bb67485b1e4d4c7eeb40971ac4057d48999c Mon Sep 17 00:00:00 2001 From: Rachel Carvalho Date: Thu, 23 Mar 2017 16:21:11 -0400 Subject: update guide to reflect browser compatibility for HTTP verbs [ci skip] --- guides/source/security.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index a14134f8c1..7e27e6f37d 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -212,7 +212,7 @@ CSRF appears very rarely in CVE (Common Vulnerabilities and Exposures) - less th NOTE: _First, as is required by the W3C, use GET and POST appropriately. Secondly, a security token in non-GET requests will protect your application from CSRF._ -The HTTP protocol basically provides two main types of requests - GET and POST (and more, but they are not supported by most browsers). The World Wide Web Consortium (W3C) provides a checklist for choosing HTTP GET or POST: +The HTTP protocol basically provides two main types of requests - GET and POST (DELETE, PUT, and PATCH should be used like POST). The World Wide Web Consortium (W3C) provides a checklist for choosing HTTP GET or POST: **Use GET if:** @@ -224,7 +224,7 @@ The HTTP protocol basically provides two main types of requests - GET and POST ( * The interaction _changes the state_ of the resource in a way that the user would perceive (e.g., a subscription to a service), or * The user is _held accountable for the results_ of the interaction. -If your web application is RESTful, you might be used to additional HTTP verbs, such as PATCH, PUT or DELETE. Most of today's web browsers, however, do not support them - only GET and POST. Rails uses a hidden `_method` field to handle this barrier. +If your web application is RESTful, you might be used to additional HTTP verbs, such as PATCH, PUT or DELETE. Some legacy web browsers, however, do not support them - only GET and POST. Rails uses a hidden `_method` field to handle these cases. _POST requests can be sent automatically, too_. In this example, the link www.harmless.com is shown as the destination in the browser's status bar. But it has actually dynamically created a new form that sends a POST request. -- cgit v1.2.3 From 40f226ae94a726ca8935062a8aac50af8cad1de9 Mon Sep 17 00:00:00 2001 From: Ryunosuke Sato Date: Thu, 30 Mar 2017 01:10:20 +0900 Subject: Fix link to rails-ujs https://github.com/rails/rails-ujs is merged into actionview in favor of https://github.com/rails/rails/pull/28098. [skip ci] --- guides/source/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index 7e27e6f37d..c305350243 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -257,7 +257,7 @@ protect_from_forgery with: :exception This will automatically include a security token in all forms and Ajax requests generated by Rails. If the security token doesn't match what was expected, an exception will be thrown. -NOTE: By default, Rails includes an [unobtrusive scripting adapter](https://github.com/rails/rails-ujs), +NOTE: By default, Rails includes an [unobtrusive scripting adapter](https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts), which adds a header called `X-CSRF-Token` with the security token on every non-GET Ajax call. Without this header, non-GET Ajax requests won't be accepted by Rails. When using another library to make Ajax calls, it is necessary to add the security -- cgit v1.2.3 From d23fb68e3d4b8cc81e877266aefce95dac562699 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Sun, 21 May 2017 08:56:24 -0500 Subject: Fix broken external link in security guide. --- guides/source/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index c305350243..1fcb2fc91f 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -796,7 +796,7 @@ In December 2006, 34,000 actual user names and passwords were stolen in a [MySpa INFO: _CSS Injection is actually JavaScript injection, because some browsers (IE, some versions of Safari and others) allow JavaScript in CSS. Think twice about allowing custom CSS in your web application._ -CSS Injection is explained best by the well-known [MySpace Samy worm](http://namb.la/popular/tech.html). This worm automatically sent a friend request to Samy (the attacker) simply by visiting his profile. Within several hours he had over 1 million friend requests, which created so much traffic that MySpace went offline. The following is a technical explanation of that worm. +CSS Injection is explained best by the well-known [MySpace Samy worm](https://samy.pl/popular/tech.html). This worm automatically sent a friend request to Samy (the attacker) simply by visiting his profile. Within several hours he had over 1 million friend requests, which created so much traffic that MySpace went offline. The following is a technical explanation of that worm. MySpace blocked many tags, but allowed CSS. So the worm's author put JavaScript into CSS like this: -- cgit v1.2.3 From 5a3ba63d9abad86b7f6dd36a92cfaf722e52760b Mon Sep 17 00:00:00 2001 From: Michael Coyne Date: Thu, 23 Feb 2017 13:54:17 -0500 Subject: AEAD encrypted cookies and sessions This commit changes encrypted cookies from AES in CBC HMAC mode to Authenticated Encryption using AES-GCM. It also provides a cookie jar to transparently upgrade encrypted cookies to this new scheme. Some other notable changes include: - There is a new application configuration value: +use_authenticated_cookie_encryption+. When enabled, AEAD encrypted cookies will be used. - +cookies.signed+ does not raise a +TypeError+ now if the name of an encrypted cookie is used. Encrypted cookies using the same key as signed cookies would be verified and serialization would then fail due the message still be encrypted. --- guides/source/security.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index c305350243..61b0c5e368 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -95,16 +95,23 @@ Rails 2 introduced a new default session storage, CookieStore. CookieStore saves * The client can see everything you store in a session, because it is stored in clear-text (actually Base64-encoded, so not encrypted). So, of course, _you don't want to store any secrets here_. To prevent session hash tampering, a digest is calculated from the session with a server-side secret (`secrets.secret_token`) and inserted into the end of the cookie. -However, since Rails 4, the default store is EncryptedCookieStore. With -EncryptedCookieStore the session is encrypted before being stored in a cookie. -This prevents the user from accessing and tampering the content of the cookie. -Thus the session becomes a more secure place to store data. The encryption is -done using a server-side secret key `secrets.secret_key_base` stored in -`config/secrets.yml`. +In Rails 4, encrypted cookies through AES in CBC mode with HMAC using SHA1 for +verification was introduced. This prevents the user from accessing and tampering +the content of the cookie. Thus the session becomes a more secure place to store +data. The encryption is performed using a server-side `secrets.secret_key_base`. +Two salts are used when deriving keys for encryption and verification. These +salts are set via the `config.action_dispatch.encrypted_cookie_salt` and +`config.action_dispatch.encrypted_signed_cookie_salt` configuration values. -That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA1, for compatibility). So _don't use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters, use `rails secret` instead_. +Rails 5.2 uses AES-GCM for the encryption which couples authentication +and encryption in one faster step and produces shorter ciphertexts. -`secrets.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `secrets.secret_key_base` initialized to a random key present in `config/secrets.yml`, e.g.: +Encrypted cookies are automatically upgraded if the +`config.action_dispatch.use_authenticated_cookie_encryption` is enabled. + +_Do not use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters! Instead use `rails secret` to generate secret keys!_ + +Applications get `secrets.secret_key_base` initialized to a random key present in `config/secrets.yml`, e.g.: development: secret_key_base: a75d... -- cgit v1.2.3 From 40bdbce191ad90dfea43dad51fac5c4726b89392 Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Mon, 15 May 2017 14:17:28 +0000 Subject: Define path with __dir__ ".. with __dir__ we can restore order in the Universe." - by @fxn Related to 5b8738c2df003a96f0e490c43559747618d10f5f --- guides/source/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index 1fcb2fc91f..75522834df 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -356,7 +356,7 @@ send_file('/var/www/uploads/' + params[:filename]) Simply pass a file name like "../../../etc/passwd" to download the server's login information. A simple solution against this, is to _check that the requested file is in the expected directory_: ```ruby -basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files')) +basename = File.expand_path('../../files', __dir__) filename = File.expand_path(File.join(basename, @file.public_filename)) raise if basename != File.expand_path(File.join(File.dirname(filename), '../../../')) -- cgit v1.2.3 From 8426978c54429c28398daca3d14c8b5e52939657 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Mon, 12 Jun 2017 18:40:36 +0530 Subject: Add brakeman to guides/additional resources. Fixes #29383 [ci skip] (#29427) --- guides/source/security.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index f69a0c72b0..9b1f28a283 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -1060,6 +1060,7 @@ Additional Resources The security landscape shifts and it is important to keep up to date, because missing a new vulnerability can be catastrophic. You can find additional resources about (Rails) security here: -* Subscribe to the Rails security [mailing list](http://groups.google.com/group/rubyonrails-security) -* [Keep up to date on the other application layers](http://secunia.com/) (they have a weekly newsletter, too) -* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet) +* Subscribe to the Rails security [mailing list.](http://groups.google.com/group/rubyonrails-security) +* [Brakeman - Rails Security Scanner](http://brakemanscanner.org/)- To perform static security analysis for Rails applications. +* [Keep up to date on the other application layers.](http://secunia.com/) (they have a weekly newsletter, too) +* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet.](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet) -- cgit v1.2.3 From dafe3f82cf3120b1e61ffdaa3c20e989c87c851f Mon Sep 17 00:00:00 2001 From: Yauheni Dakuka Date: Mon, 26 Jun 2017 22:17:16 +0300 Subject: Update security.md --- guides/source/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'guides/source/security.md') diff --git a/guides/source/security.md b/guides/source/security.md index 9b1f28a283..297680b176 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -1061,6 +1061,6 @@ Additional Resources The security landscape shifts and it is important to keep up to date, because missing a new vulnerability can be catastrophic. You can find additional resources about (Rails) security here: * Subscribe to the Rails security [mailing list.](http://groups.google.com/group/rubyonrails-security) -* [Brakeman - Rails Security Scanner](http://brakemanscanner.org/)- To perform static security analysis for Rails applications. +* [Brakeman - Rails Security Scanner](http://brakemanscanner.org/) - To perform static security analysis for Rails applications. * [Keep up to date on the other application layers.](http://secunia.com/) (they have a weekly newsletter, too) * A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet.](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet) -- cgit v1.2.3