diff options
Diffstat (limited to 'guides')
-rw-r--r-- | guides/code/getting_started/config/environments/production.rb | 2 | ||||
-rw-r--r-- | guides/source/4_1_release_notes.md | 17 | ||||
-rw-r--r-- | guides/source/action_controller_overview.md | 24 | ||||
-rw-r--r-- | guides/source/action_mailer_basics.md | 2 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 2 | ||||
-rw-r--r-- | guides/source/active_record_validations.md | 16 | ||||
-rw-r--r-- | guides/source/api_documentation_guidelines.md | 52 | ||||
-rw-r--r-- | guides/source/asset_pipeline.md | 22 | ||||
-rw-r--r-- | guides/source/configuring.md | 26 | ||||
-rw-r--r-- | guides/source/security.md | 43 |
10 files changed, 170 insertions, 36 deletions
diff --git a/guides/code/getting_started/config/environments/production.rb b/guides/code/getting_started/config/environments/production.rb index 93d44723fb..8c514e065e 100644 --- a/guides/code/getting_started/config/environments/production.rb +++ b/guides/code/getting_started/config/environments/production.rb @@ -5,7 +5,7 @@ Blog::Application.configure do config.cache_classes = true # Eager load code on boot. This eager loads most of Rails and - # your application in memory, allowing both thread web servers + # your application in memory, allowing both threaded web servers # and those relying on copy on write to perform better. # Rake tasks automatically ignore this option for performance. config.eager_load = true diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md index 1980f4d4cf..4e75bf400c 100644 --- a/guides/source/4_1_release_notes.md +++ b/guides/source/4_1_release_notes.md @@ -422,11 +422,6 @@ for detailed changes. * Deprecated `quoted_locking_column` method, which isn't used anywhere. -* Deprecated the delegation of Array bang methods for associations. - To use them, instead first call `#to_a` on the association to access the - array to be acted - on. ([Pull Request](https://github.com/rails/rails/pull/12129)) - * Deprecated `ConnectionAdapters::SchemaStatements#distinct`, as it is no longer used by internals. ([Pull Request](https://github.com/rails/rails/pull/10556)) @@ -502,6 +497,9 @@ for detailed changes. * Don't create or drop the test database if RAILS_ENV is specified explicitly. +* `Relation` no longer has mutator methods like `#map!` and `#delete_if`. Convert + to an `Array` by calling `#to_a` before using these methods. ([Pull Request](https://github.com/rails/rails/pull/13314)) + Active Model ------------ @@ -569,6 +567,9 @@ for detailed changes. * Removed deprecated `assert_present` and `assert_blank` methods, use `assert object.blank?` and `assert object.present?` instead. +* Remove deprecated `#filter` method for filter objects, use the corresponding + method instead (e.g. `#before` for a before filter). + ### Deprecations * Deprecated `Numeric#{ago,until,since,from_now}`, the user is expected to @@ -585,7 +586,7 @@ for detailed changes. [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) * Deprecated `ActiveSupport.encode_big_decimal_as_string` option. This feature has - been extracetd into the [activesupport-json_encoder](https://github.com/rails/activesupport-json_encoder) + been extracted into the [activesupport-json_encoder](https://github.com/rails/activesupport-json_encoder) gem. ([Pull Request](https://github.com/rails/rails/pull/13060) / [More Details](upgrading_ruby_on_rails.html#changes-in-json-handling)) @@ -606,6 +607,10 @@ for detailed changes. `Time.now` and `Date.today`. ([Pull Request](https://github.com/rails/rails/pull/12824)) +* Added `ActiveSupport::Testing::TimeHelpers#travel_back`. This method returns + the current time to the original state, by removing the stubs added by `travel` + and `travel_to`. ([Pull Request](https://github.com/rails/rails/pull/13884)) + * Added `Numeric#in_milliseconds`, like `1.hour.in_milliseconds`, so we can feed them to JavaScript functions like `getTime()`. ([Commit](https://github.com/rails/rails/commit/423249504a2b468d7a273cbe6accf4f21cb0e643)) diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md index f394daa6aa..9eaf03dd82 100644 --- a/guides/source/action_controller_overview.md +++ b/guides/source/action_controller_overview.md @@ -112,6 +112,10 @@ NOTE: The actual URL in this example will be encoded as "/clients?ids%5b%5d=1&id The value of `params[:ids]` will now be `["1", "2", "3"]`. Note that parameter values are always strings; Rails makes no attempt to guess or cast the type. +NOTE: Values such as `[]`, `[nil]` or `[nil, nil, ...]` in `params` are replaced +with `nil` for security reasons by default. See [Security Guide](security.html#unsafe-query-generation) +for more information. + To send a hash you include the key name inside the brackets: ```html @@ -377,6 +381,22 @@ You can also pass a `:domain` key and specify the domain name for the cookie: YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', domain: ".example.com" ``` +You can pass `:serializer` key to specify serializer for serializing session: + +```ruby +YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', serializer: :json +``` + +The default serializer for new application is `:json`. For compatibility with +old applications `:marshal` is used when `serializer` option is not specified. + +It is also possible to pass a custom serializer class with `load` and `dump` +public methods defined: + +```ruby +YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', serializer: MyCustomSerializer +``` + Rails sets up (for the CookieStore) a secret key used for signing the session data. This can be changed in `config/initializers/secret_token.rb` ```ruby @@ -683,7 +703,7 @@ class ApplicationController < ActionController::Base end class LoginFilter - def self.filter(controller) + def self.before(controller) unless controller.send(:logged_in?) controller.flash[:error] = "You must be logged in to access this section" controller.redirect_to controller.new_login_url @@ -692,7 +712,7 @@ class LoginFilter end ``` -Again, this is not an ideal example for this filter, because it's not run in the scope of the controller but gets the controller passed as an argument. The filter class has a class method `filter` which gets run before or after the action, depending on if it's a before or after filter. Classes used as around filters can also use the same `filter` method, which will get run in the same way. The method must `yield` to execute the action. Alternatively, it can have both a `before` and an `after` method that are run before and after the action. +Again, this is not an ideal example for this filter, because it's not run in the scope of the controller but gets the controller passed as an argument. The filter class must implement a method with the same name as the filter, so for the `before_action` filter the class must implement a `before` method, and so on. The `around` method must `yield` to execute the action. Request Forgery Protection -------------------------- diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md index 293e999c14..6dc7fb1606 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -611,7 +611,7 @@ files (environment.rb, production.rb, etc...) |`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default "localhost" setting.</li><li>`:port` - On the off chance that your mail server doesn't run on port 25, you can change it.</li><li>`:domain` - If you need to specify a HELO domain, you can do it here.</li><li>`:user_name` - If your mail server requires authentication, set the username in this setting.</li><li>`:password` - If your mail server requires authentication, set the password in this setting.</li><li>`:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain`, `:login`, `:cram_md5`.</li><li>`:enable_starttls_auto` - Set this to `false` if there is a problem with your server certificate that you cannot resolve.</li></ul>| |`sendmail_settings`|Allows you to override options for the `:sendmail` delivery method.<ul><li>`:location` - The location of the sendmail executable. Defaults to `/usr/sbin/sendmail`.</li><li>`:arguments` - The command line arguments to be passed to sendmail. Defaults to `-i -t`.</li></ul>| |`raise_delivery_errors`|Whether or not errors should be raised if the email fails to be delivered. This only works if the external email server is configured for immediate delivery.| -|`delivery_method`|Defines a delivery method. Possible values are `:smtp` (default), `:sendmail`, `:file` and `:test`.| +|`delivery_method`|Defines a delivery method. Possible values are:<ul><li>`:smtp` (default), can be configured by using `config.action_mailer.smtp_settings`.</li><li>`:sendmail`, can be configured by using `config.action_mailer.sendmail_settings`.</li><li>`:file`: save emails to files; can be configured by using `config.action_mailer.file_settings`.</li><li>`:test`: save emails to `ActionMailer::Base.deliveries` array.</li></ul>See [API docs](http://api.rubyonrails.org/classes/ActionMailer/Base.html) for more info.| |`perform_deliveries`|Determines whether deliveries are actually carried out when the `deliver` method is invoked on the Mail message. By default they are, but this can be turned off to help functional testing.| |`deliveries`|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.| |`default_options`|Allows you to set default values for the `mail` method options (`:from`, `:reply_to`, etc.).| diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 3783be50c0..d164b08d93 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -1455,7 +1455,7 @@ If you'd like to use your own SQL to find records in a table you can use `find_b ```ruby Client.find_by_sql("SELECT * FROM clients INNER JOIN orders ON clients.id = orders.client_id - ORDER clients.created_at desc") + ORDER BY clients.created_at desc") ``` `find_by_sql` provides you with a simple way of making custom calls to the database and retrieving instantiated objects. diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md index efa826e8df..b04c7a90e2 100644 --- a/guides/source/active_record_validations.md +++ b/guides/source/active_record_validations.md @@ -616,10 +616,6 @@ The default error message is _"has already been taken"_. This helper passes the record to a separate class for validation. ```ruby -class Person < ActiveRecord::Base - validates_with GoodnessValidator -end - class GoodnessValidator < ActiveModel::Validator def validate(record) if record.first_name == "Evil" @@ -627,6 +623,10 @@ class GoodnessValidator < ActiveModel::Validator end end end + +class Person < ActiveRecord::Base + validates_with GoodnessValidator +end ``` NOTE: Errors added to `record.errors[:base]` relate to the state of the record @@ -644,10 +644,6 @@ Like all other validations, `validates_with` takes the `:if`, `:unless` and validator class as `options`: ```ruby -class Person < ActiveRecord::Base - validates_with GoodnessValidator, fields: [:first_name, :last_name] -end - class GoodnessValidator < ActiveModel::Validator def validate(record) if options[:fields].any?{|field| record.send(field) == "Evil" } @@ -655,6 +651,10 @@ class GoodnessValidator < ActiveModel::Validator end end end + +class Person < ActiveRecord::Base + validates_with GoodnessValidator, fields: [:first_name, :last_name] +end ``` Note that the validator will be initialized *only once* for the whole application diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md index 311cc23cf0..7466b4ff48 100644 --- a/guides/source/api_documentation_guidelines.md +++ b/guides/source/api_documentation_guidelines.md @@ -128,6 +128,53 @@ On the other hand, regular comments do not use an arrow: # polymorphic_url(record) # same as comment_url(record) ``` +Booleans +-------- + +In predicates and flags prefer documenting boolean semantics over exact values. + +When "true" or "false" are used as defined in Ruby use regular font. The +singletons `true` and `false` need fixed-width font. Please avoid terms like +"truthy", Ruby defines what is true and false in the language, and thus those +words have a technical meaning and need no substitutes. + +As a rule of thumb, do not document singletons unless absolutely necessary. That +prevents artificial constructs like `!!` or ternaries, allows refactors, and the +code does not need to rely on the exact values returned by methods being called +in the implementation. + +For example: + +```markdown +`config.action_mailer.perform_deliveries` specifies whether mail will actually be delivered and is true by default +``` + +the user does not need to know which is the actual default value of the flag, +and so we only document its boolean semantics. + +An example with a predicate: + +```ruby +# Returns true if the collection is empty. +# +# If the collection has been loaded +# it is equivalent to <tt>collection.size.zero?</tt>. If the +# collection has not been loaded, it is equivalent to +# <tt>collection.exists?</tt>. If the collection has not already been +# loaded and you are going to fetch the records anyway it is better to +# check <tt>collection.length.zero?</tt>. +def empty? + if loaded? + size.zero? + else + @target.blank? && !scope.exists? + end +end +``` + +The API is careful not to commit to any particular value, the predicate has +predicate semantics, that's enough. + Filenames --------- @@ -163,7 +210,10 @@ class Array end ``` -WARNING: Using a pair of `+...+` for fixed-width font only works with **words**; that is: anything matching `\A\w+\z`. For anything else use `<tt>...</tt>`, notably symbols, setters, inline snippets, etc. +WARNING: Using `+...+` for fixed-width font only works with simple content like +ordinary method names, symbols, paths (with forward slashes), etc. Please use +`<tt>...</tt>` for everything else, notably class or module names with a +namespace as in `<tt>ActiveRecord::Base</tt>`. ### Regular Font diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md index bce5d6c55f..0422dda0d8 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -496,16 +496,11 @@ In this example, `require_self` is used. This puts the CSS contained within the file (if any) at the precise location of the `require_self` call. If `require_self` is called more than once, only the last call is respected. -NOTE. If you want to use multiple Sass files, you should generally use the [Sass -`@import` -rule](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import) instead -of these Sprockets directives. Using Sprockets directives all Sass files exist -within their own scope, making variables or mixins only available within the -document they were defined in. You can do file globbing as well using -`@import "*"`, and `@import "**/*"` to add the whole tree equivalent to how -`require_tree` works. Check the [sass-rails -documentation](https://github.com/rails/sass-rails#features) for more info and -important caveats. +NOTE. If you want to use multiple Sass files, you should generally use the [Sass `@import` rule](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import) +instead of these Sprockets directives. Using Sprockets directives all Sass files exist within +their own scope, making variables or mixins only available within the document they were defined in. +You can do file globbing as well using `@import "*"`, and `@import "**/*"` to add the whole tree +equivalent to how `require_tree` works. Check the [sass-rails documentation](https://github.com/rails/sass-rails#features) for more info and important caveats. You can have as many manifest files as you need. For example, the `admin.css` and `admin.js` manifest could contain the JS and CSS files that are used for the @@ -938,7 +933,7 @@ Customizing the Pipeline ### CSS Compression -There is currently one option for compressing CSS, YUI. The [YUI CSS +One of the options for compressing CSS is YUI. The [YUI CSS compressor](http://yui.github.io/yuicompressor/css.html) provides minification. @@ -948,6 +943,11 @@ gem. ```ruby config.assets.css_compressor = :yui ``` +The other option for compressing CSS if you have the sass-rails gem installed is + +```ruby +config.assets.css_compressor = :sass +``` ### JavaScript Compression diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 412aecadd5..5e0010725e 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -352,6 +352,10 @@ value. Defaults to `'encrypted cookie'`. * `config.action_dispatch.encrypted_signed_cookie_salt` sets the signed encrypted cookies salt value. Defaults to `'signed encrypted cookie'`. +* `config.action_dispatch.perform_deep_munge` configures whether `deep_munge` + method should be performed on the parameters. See [Security Guide](security.html#unsafe-query-generation) + for more information. It defaults to true. + * `ActionDispatch::Callbacks.before` takes a block of code to run before the request. * `ActionDispatch::Callbacks.to_prepare` takes a block to run after `ActionDispatch::Callbacks.before`, but before the request. Runs for every request in `development` mode, but only once for `production` or environments with `cache_classes` set to `true`. @@ -386,6 +390,8 @@ encrypted cookies salt value. Defaults to `'signed encrypted cookie'`. The default setting is `true`, which uses the partial at `/admin/posts/_post.erb`. Setting the value to `false` would render `/posts/_post.erb`, which is the same behavior as rendering from a non-namespaced controller such as `PostsController`. +* `config.action_view.raise_on_missing_translations` determines whether an error should be raised for missing translations + ### Configuring Action Mailer There are a number of settings available on `config.action_mailer`: @@ -406,17 +412,25 @@ There are a number of settings available on `config.action_mailer`: * `config.action_mailer.raise_delivery_errors` specifies whether to raise an error if email delivery cannot be completed. It defaults to true. -* `config.action_mailer.delivery_method` defines the delivery method. The allowed values are `:smtp` (default), `:sendmail`, and `:test`. +* `config.action_mailer.delivery_method` defines the delivery method and defaults to `:smtp`. See the [configuration section in the Action Mailer guide](http://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration) for more info. * `config.action_mailer.perform_deliveries` specifies whether mail will actually be delivered and is true by default. It can be convenient to set it to false for testing. * `config.action_mailer.default_options` configures Action Mailer defaults. Use to set options like `from` or `reply_to` for every mailer. These default to: ```ruby - :mime_version => "1.0", - :charset => "UTF-8", - :content_type => "text/plain", - :parts_order => [ "text/plain", "text/enriched", "text/html" ] + mime_version: "1.0", + charset: "UTF-8", + content_type: "text/plain", + parts_order: ["text/plain", "text/enriched", "text/html"] + ``` + + Assign a hash to set additional options: + + ```ruby + config.action_mailer.default_options = { + from: "noreply@example.com" + } ``` * `config.action_mailer.observers` registers observers which will be notified when mail is delivered. @@ -441,6 +455,8 @@ There are a few configuration options available in Active Support: * `config.active_support.use_standard_json_time_format` enables or disables serializing dates to ISO 8601 format. Defaults to `true`. +* `config.active_support.time_precision` sets the precision of JSON encoded time values. Defaults to `3`. + * `ActiveSupport::Logger.silencer` is set to `false` to disable the ability to silence logging in a block. The default is `true`. * `ActiveSupport::Cache::Store.logger` specifies the logger to use within cache store operations. diff --git a/guides/source/security.md b/guides/source/security.md index cffe7c85f1..70fb066b64 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -915,6 +915,49 @@ Content-Type: text/html Under certain circumstances this would present the malicious HTML to the victim. However, this only seems to work with Keep-Alive connections (and many browsers are using one-time connections). But you can't rely on this. _In any case this is a serious bug, and you should update your Rails to version 2.0.5 or 2.1.2 to eliminate Header Injection (and thus response splitting) risks._ +Unsafe Query Generation +----------------------- + +Due to the way Active Record interprets parameters in combination with the way +that Rack parses query parameters it was possible to issue unexpected database +queries with `IS NULL` where clauses. As a response to that security issue +([CVE-2012-2660](https://groups.google.com/forum/#!searchin/rubyonrails-security/deep_munge/rubyonrails-security/8SA-M3as7A8/Mr9fi9X4kNgJ), +[CVE-2012-2694](https://groups.google.com/forum/#!searchin/rubyonrails-security/deep_munge/rubyonrails-security/jILZ34tAHF4/7x0hLH-o0-IJ) +and [CVE-2013-0155](https://groups.google.com/forum/#!searchin/rubyonrails-security/CVE-2012-2660/rubyonrails-security/c7jT-EeN9eI/L0u4e87zYGMJ)) +`deep_munge` method was introduced as a solution to keep Rails secure by default. + +Example of vulnerable code that could be used by attacker, if `deep_munge` +wasn't performed is: + +```ruby +unless params[:token].nil? + user = User.find_by_token(params[:token]) + user.reset_password! +end +``` + +When `params[:token]` is one of: `[]`, `[nil]`, `[nil, nil, ...]` or +`['foo', nil]` it will bypass the test for `nil`, but `IS NULL` or +`IN ('foo', NULL)` where clauses still will be added to the SQL query. + +To keep rails secure by default, `deep_munge` replaces some of the values with +`nil`. Below table shows what the parameters look like based on `JSON` sent in +request: + +| JSON | Parameters | +|-----------------------------------|--------------------------| +| `{ "person": null }` | `{ :person => nil }` | +| `{ "person": [] }` | `{ :person => nil }` | +| `{ "person": [null] }` | `{ :person => nil }` | +| `{ "person": [null, null, ...] }` | `{ :person => nil }` | +| `{ "person": ["foo", null] }` | `{ :person => ["foo"] }` | + +It is possible to return to old behaviour and disable `deep_munge` configuring +your application if you are aware of the risk and know how to handle it: + +```ruby +config.action_dispatch.perform_deep_munge = false +``` Default Headers --------------- |