aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/http
Commit message (Collapse)AuthorAgeFilesLines
* Use match? where we don't need MatchDataAkira Matsuda2019-07-272-2/+2
| | | | We're already running Performance/RegexpMatch cop, but it seems like the cop is not always =~ justice
* Add `Vary: Accept` header when renderingst00122019-07-261-7/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem description (quoted from @rafaelfranca's excellent explanation in https://github.com/rails/jquery-ujs/issues/318#issuecomment-88129005): > Let say that we requested /tasks/1 using Ajax, and the previous page has the same url. When we click the back button the browser tries to get the response from its cache and it gets the javascript response. With vary we "fix" this behavior because we are telling the browser that the url is the same but it is not from the same type what will skip the cache. And there's a Rails issue discussing about this problem as well https://github.com/rails/rails/issues/25842 Also, according to [RFC 7231 7.1.4](https://tools.ietf.org/html/rfc7231#section-7.1.4) > An origin server SHOULD send a Vary header field when its algorithm > for selecting a representation varies based on aspects of the request > message other than the method and request target we should add `Vary: Accept` header when determining content based on the `Accept` header. Although adding such header by default could cause unnecessary cache invalidation. But this PR only adds the header if: - The format param is not provided - The request is a `xhr` request - The request has accept headers and the headers are valid So if the user - sends request with explicit format, like `/users/1.json` - or sends a normal request (non xhr) - or doesn't specify accept headers then the header won't be added. See the discussion in https://github.com/rails/rails/issues/25842 and https://github.com/rails/rails/pull/36213 for more details.
* Add support for script-src-attr / elem and style-src-attr / elem directivesyuuji.yaginuma2019-07-181-0/+4
| | | | | These directives can be used in Chrome 75. Ref: https://www.chromestatus.com/feature/5141352765456384
* Adds support for configuring HTTP Feature Policy (#33439)Jacob Bednarz2019-07-102-0/+169
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A HTTP feature policy is Yet Another HTTP header for instructing the browser about which features the application intends to make use of and to lock down access to others. This is a new security mechanism that ensures that should an application become compromised or a third party attempts an unexpected action, the browser will override it and maintain the intended UX. WICG specification: https://wicg.github.io/feature-policy/ The end result is a HTTP header that looks like the following: ``` Feature-Policy: geolocation 'none'; autoplay https://example.com ``` This will prevent the browser from using geolocation and only allow autoplay on `https://example.com`. Full feature list can be found over in the WICG repository[1]. As of today Chrome and Safari have public support[2] for this functionality with Firefox working on support[3] and Edge still pending acceptance of the suggestion[4]. #### Examples Using an initializer ```rb # config/initializers/feature_policy.rb Rails.application.config.feature_policy do |f| f.geolocation :none f.camera :none f.payment "https://secure.example.com" f.fullscreen :self end ``` In a controller ```rb class SampleController < ApplicationController def index feature_policy do |f| f.geolocation "https://example.com" end end end ``` Some of you might realise that the HTTP feature policy looks pretty close to that of a Content Security Policy; and you're right. So much so that I used the Content Security Policy DSL from #31162 as the starting point for this change. This change *doesn't* introduce support for defining a feature policy on an iframe and this has been intentionally done to split the HTTP header and the HTML element (`iframe`) support. If this is successful, I'll look to add that on it's own. Full documentation on HTTP feature policies can be found at https://wicg.github.io/feature-policy/. Google have also published[5] a great in-depth write up of this functionality. [1]: https://github.com/WICG/feature-policy/blob/master/features.md [2]: https://www.chromestatus.com/feature/5694225681219584 [3]: https://bugzilla.mozilla.org/show_bug.cgi?id=1390801 [4]: https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/33507907-support-feature-policy [5]: https://developers.google.com/web/updates/2018/06/feature-policy
* Add the ability to set the CSP nonce only to the specified directivesyuuji.yaginuma2019-06-221-9/+20
| | | | | | | | | | | I changed to set CSP nonce to `style-src` directive in #32932. But this causes an issue when `unsafe-inline` is specified to `style-src` (If a nonce is present, a nonce takes precedence over `unsafe-inline`). So, I fixed to nonce directives configurable. By configure this, users can make CSP as before. Fixes #35137.
* Make `ActionDispatch::Response#content_type` behavior configurableyuuji.yaginuma2019-06-211-1/+12
| | | | | | | | | I changed return value of `ActionDispatch::Response#content_type` in #36034. But this change seems to an obstacle to upgrading. https://github.com/rails/rails/pull/36034#issuecomment-498795893 Therefore, I restored the behavior of `ActionDispatch::Response#content_type` to 5.2 and deprecated old behavior. Also, made it possible to control the behavior with the config.
* Enable `Layout/EmptyLinesAroundAccessModifier` copRyuta Kamizono2019-06-1310-13/+0
| | | | | | | | | | | We sometimes say "✂️ newline after `private`" in a code review (e.g. https://github.com/rails/rails/pull/18546#discussion_r23188776, https://github.com/rails/rails/pull/34832#discussion_r244847195). Now `Layout/EmptyLinesAroundAccessModifier` cop have new enforced style `EnforcedStyle: only_before` (https://github.com/rubocop-hq/rubocop/pull/7059). That cop and enforced style will reduce the our code review cost.
* Simplify `ActionDispatch::Response#content_type`yuuji.yaginuma2019-06-021-2/+1
|
* Change `ActionDispatch::Response#content_type` returning Content-Type header ↵yuuji.yaginuma2019-06-011-2/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | as it is Since #35709, `Response#conten_type` returns only MIME type correctly. It is a documented behavior that this method only returns MIME type, so this change seems appropriate. https://github.com/rails/rails/blob/39de7fac0507070e3c5f8b33fbad6fced84d97ed/actionpack/lib/action_dispatch/http/response.rb#L245-L249 But unfortunately, some users expect this method to return all Content-Type that does not contain charset. This seems to be breaking changes. We can change this behavior with the deprecate cycle. But, in that case, a method needs that include Content-Type with additional parameters. And that method name is probably the `content_type` seems to properly. So I changed the new behavior to more appropriate `media_type` method. And `Response#content_type` changed (as the method name) to return Content-Type header as it is. Fixes #35709. [Rafael Mendonça França & Yuuji Yaginuma ]
* Remove :all symbol from Mime::ALLJohn Hawthorn2019-03-271-1/+1
| | | | | | .all isn't a valid file extension, so it shouldn't used as a symbol. This also makes Mime::ALL better match how */* is parsed from an Accept header.
* Update regular expression for checking valid MIME typeCliff Pruitt2019-03-191-1/+4
| | | | MIME Type validation regular expression does not allow for MIME types initialized with strings that contain parameters after the MIME type name.
* Raise exception when building invalid mime typeJohn Hawthorn2019-03-141-0/+9
| | | | | | | This allows mime types in the form text/html, text/*, or */* This required a few minor test/code changes where previously nil was used as a mime string.
* Merge tag 'v6.0.0.beta3'eileencodes2019-03-131-0/+5
|\ | | | | | | v6.0.0.beta3 release
| * Only accept formats from registered mime typesJohn Hawthorn2019-03-101-0/+5
| | | | | | | | | | [CVE-2019-5418] [CVE-2019-5419]
* | Support other optional parameters and quoted-strings on Content-Type parserr7kamura2019-03-101-4/+3
|/
* Restore UploadedFile compatibility with IO.copy_streamJanko Marohnić2019-02-231-1/+4
| | | | | | | | | | | | | | | | | | In https://github.com/rails/rails/pull/28676 the `#to_path` method was added to `ActionDispatch::Http::UploadedFile`. This broke usage with `IO.copy_stream`: source = ActionDispatch::Http::UploadedFile.new(...) IO.copy_stream(source, destination) # ~> TypeError: can't convert ActionDispatch::Http::UploadedFile to IO (ActionDispatch::Http::UploadedFile#to_io gives Tempfile) Normally `IO.copy_stream` just calls `#read` on the source object. However, when `#to_path` is defined, `IO.copy_stream` calls `#to_io` in order to retrieve the raw `File` object. In that case it trips up, because `ActionDispatch::Http::UploadedFile#to_io` returned a `Tempfile` object, which is not an `IO` subclass. We fix this by having `#to_io` return an actual `File` object.
* Allow using combine the Cache-Control `public` and `no-cache` headersyuuji.yaginuma2019-01-071-4/+6
| | | | | | | | | | | | | | | | | Since #30367, if `no-cache` includes Cache-Control headers, special keys like `public`, `must-revalidate` are ignored. But in my understanding, `public` still need in case of want to cache authenticated pages. The authenticated pages to be cacheable, but still authenticated for every user, need to specify the `Cache-Control: public, no-cache`. For keys other than `public`, I did not know the case where it was necessary to use it in combination with `no-cache`, so I fixed that can be used only for `public`. Ref: https://www.mnot.net/cache_docs/#CACHE-CONTROL Fixes #34780.
* Upgrade Rubocop to 0.61.1 and fix offensesVinicius Stock2018-12-101-79/+79
|
* Allow rescue from parameter parse errorsGannon McGibbon2018-11-134-7/+21
| | | | [Gannon McGibbon + Josh Cheek]
* Use request object for context if there's no controllerAndrew White2018-10-221-1/+2
| | | | | | | | There is no controller instance when using a redirect route or a mounted rack application so pass the request object as the context when resolving dynamic CSP sources in this scenario. Fixes #34200.
* Apply mapping to symbols returned from dynamic CSP sourcesAndrew White2018-10-221-1/+2
| | | | | | | | | | | | | | | Previously if a dynamic source returned a symbol such as :self it would be converted to a string implicity, e.g: policy.default_src -> { :self } would generate the header: Content-Security-Policy: default-src self and now it generates: Content-Security-Policy: default-src 'self'
* Remove invalid magic comment [ci skip]Yoshiyuki Kinjo2018-10-111-2/+0
|
* Deprecate ActionDispatch::Http::ParameterFilter in favor of ↵Yoshiyuki Kinjo2018-10-082-84/+9
| | | | ActiveSupport::ParameterFilter
* Add `Style/RedundantFreeze` to remove redudant `.freeze`Yasuo Honda2018-09-298-38/+38
| | | | | | | | | | | | | | | | | | | | | Since Rails 6.0 will support Ruby 2.4.1 or higher `# frozen_string_literal: true` magic comment is enough to make string object frozen. This magic comment is enabled by `Style/FrozenStringLiteralComment` cop. * Exclude these files not to auto correct false positive `Regexp#freeze` - 'actionpack/lib/action_dispatch/journey/router/utils.rb' - 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb' It has been fixed by https://github.com/rubocop-hq/rubocop/pull/6333 Once the newer version of RuboCop released and available at Code Climate these exclude entries should be removed. * Replace `String#freeze` with `String#-@` manually if explicit frozen string objects are required - 'actionpack/test/controller/test_case_test.rb' - 'activemodel/test/cases/type/string_test.rb' - 'activesupport/lib/active_support/core_ext/string/strip.rb' - 'activesupport/test/core_ext/string_ext_test.rb' - 'railties/test/generators/actions_test.rb'
* Merge pull request #33829 from mtsmfm/encode-filenameKasper Timm Hansen2018-09-231-0/+45
|\ | | | | Encode Content-Disposition filenames on send_data and send_file
| * Encode Content-Disposition filenames on send_data and send_fileFumiaki MATSUSHIMA2018-09-131-0/+45
| |
* | Enable `Performance/UnfreezeString` copyuuji.yaginuma2018-09-232-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In Ruby 2.3 or later, `String#+@` is available and `+@` is faster than `dup`. ```ruby # frozen_string_literal: true require "bundler/inline" gemfile(true) do source "https://rubygems.org" gem "benchmark-ips" end Benchmark.ips do |x| x.report('+@') { +"" } x.report('dup') { "".dup } x.compare! end ``` ``` $ ruby -v benchmark.rb ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] Warming up -------------------------------------- +@ 282.289k i/100ms dup 187.638k i/100ms Calculating ------------------------------------- +@ 6.775M (± 3.6%) i/s - 33.875M in 5.006253s dup 3.320M (± 2.2%) i/s - 16.700M in 5.032125s Comparison: +@: 6775299.3 i/s dup: 3320400.7 i/s - 2.04x slower ```
* | Merge pull request #32932 from y-yagi/fixes_32920Yuji Yaginuma2018-09-201-1/+1
|\ \ | | | | | | Add CSP nonce to `style-src` directive
| * | Add CSP nonce to `style-src` directiveyuuji.yaginuma2018-05-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For nonce, only `script-src` and` style-src` are meaningful in the definition of Content Security Policy Level 2. https://www.w3.org/TR/CSP2/#script-src-nonce-usage https://www.w3.org/TR/CSP2/#style-src-nonce-usage Therefore, I think that customization function not needs and it is enough to enable both directives inside the framework. Fixes #32920
* | | [ci skip] Fix documentation for Response#content_typeprintercu2018-09-141-10/+10
| |/ |/|
* | Permit list usage cleanup and clearer documentationKevin Deisz2018-08-271-4/+1
| |
* | Convert over the rest of the whitelist referencesKevin Deisz2018-08-241-1/+1
| |
* | Update ParameterFilter to yield original parametersPeter Zhu2018-08-221-6/+6
| |
* | Use `Array#extract!` where possiblebogdanvlviv2018-08-141-2/+3
| |
* | Enable Start/EndWith and RegexpMatch copsBart de Water2018-07-281-1/+1
| | | | | | | | | | In cases where the MatchData object is not used, this provides a speed-up: https://github.com/JuanitoFatas/fast-ruby/#stringmatch-vs-stringmatch-vs-stringstart_withstringend_with-code-start-code-end
* | Add implicit to path conversion to uploaded file (#28676)Aaron Kromer2018-07-221-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add implicit to path conversion to uploaded file Ruby has a few implicit conversion protocols (e.g. `to_hash`, `to_str`, `to_path`, etc.). These are considered implicit conversion protocols because in certain instances Ruby (MRI core objects) will check if an argument responds to the appropriate protocol and automatically convert it when it does; this is why you can provide a `Pathname` instance into `File.read` without having to explicitly call `to_s`. ```ruby a_file_path = 'some/path/file.ext' File.write a_file_path, 'String Path Content' File.read a_file_path a_pathname = Pathname(a_file_path) File.write core_file, 'Pathname Content' File.read a_file_path core_file = File.new(a_pathname) File.write core_file, 'File Content' File.read core_file tmp_file = Tempfile.new('example') File.write tmp_file, 'Tempfile Content' File.read tmp_file ``` So how does an uploaded file work in such cases? ```ruby tmp_file = Tempfile.new('example') File.write tmp_file, 'Uploaded Content' uploaded_file = ActionDispatch::Http::UploadedFile.new(tempfile: tmp_file) File.read uploaded_file ``` It fails with a `TypeError`: no implicit conversion of ActionDispatch::Http::UploadedFile into String In order to make an uploaded file work it must be explicitly converted to a file path using `path`. ```ruby File.read uploaded_file.path ``` This requires any code that expects path/file like objects to either special case an uploaded file, re-implement the path conversion protocol to use `path`, or forces the developer to explicitly cast uploaded files to paths. This last option can sometimes be difficult to do when such calls are deep within the inner workings of libraries. Since an uploaded file already has a path it makes sense to implement the implicit "path" conversion protocol (just like `File` and `Tempfile`). This change allows uploaded file content to be treated more closely to regular file content, without requiring any special case handling or explicit conversion for common file utilities. * Note uploaded file path delegation in CHANGELOG
* | Add support for more HTTP cache controlsDaniel Schierbeck2018-06-131-1/+5
|/ | | | | | | | | | | | | | | | | | From <https://tools.ietf.org/html/rfc5861>: > The stale-if-error HTTP Cache-Control extension allows a cache to > return a stale response when an error -- e.g., a 500 Internal Server > Error, a network segment, or DNS failure -- is encountered, rather > than returning a "hard" error. This improves availability. > > The stale-while-revalidate HTTP Cache-Control extension allows a > cache to immediately return a stale response while it revalidates it > in the background, thereby hiding latency (both in the network and on > the server) from clients. These are useful, fully standardized parts of the HTTP protocol with widespread support among CDN vendors. Supporting them will make it easier to utilize reverse proxies and CDNs from Rails.
* Add support for prefetch-src directiveyuuji.yaginuma2018-05-031-0/+1
| | | | | | | Specification: https://w3c.github.io/webappsec-csp/#directive-prefetch-src This directive can already be used as an experimental feature in Chrome. Ref: https://bugs.chromium.org/p/chromium/issues/detail?id=801561
* [ci skip] Fix doc typos ActionDispatch::Http::FilterParametersAlberto Almagro2018-04-201-2/+2
| | | | Fixes two documentation typos found at ActionDispatch::Http::FilterParameters
* Remove unused literal introduced in #32602Andrew White2018-04-181-1/+0
|
* Pass nonce to CSP policy from outsideAndrew White2018-04-181-31/+24
|
* Output only one nonce in CSP header per requestAndrey Novikov2018-04-171-17/+30
|
* Add WebSocket URI support to CSP DSL mappingsStephen Solis2018-04-121-1/+3
|
* Add support for automatic nonce generation for Rails UJSAndrew White2018-02-191-0/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | Because the UJS library creates a script tag to process responses it normally requires the script-src attribute of the content security policy to include 'unsafe-inline'. To work around this we generate a per-request nonce value that is embedded in a meta tag in a similar fashion to how CSRF protection embeds its token in a meta tag. The UJS library can then read the nonce value and set it on the dynamically generated script tag to enable it to execute without needing 'unsafe-inline' enabled. Nonce generation isn't 100% safe - if your script tag is including user generated content in someway then it may be possible to exploit an XSS vulnerability which can take advantage of the nonce. It is however an improvement on a blanket permission for inline scripts. It is also possible to use the nonce within your own script tags by using `nonce: true` to set the nonce value on the tag, e.g <%= javascript_tag nonce: true do %> alert('Hello, World!'); <% end %> Fixes #31689.
* Remove trailing semi-colon from CSPAndrew White2018-02-191-1/+1
| | | | | | | | | Although the spec[1] is defined in such a way that a trailing semi-colon is valid it also doesn't allow a semi-colon by itself to indicate an empty policy. Therefore it's easier (and valid) just to omit it rather than to detect whether the policy is empty or not. [1]: https://www.w3.org/TR/CSP2/#policy-syntax
* Revert "Merge pull request #32045 from eagletmt/skip-csp-header"Andrew White2018-02-191-10/+2
| | | | | | | | | This reverts commit 86f7c269073a3a9e6ddec9b957deaa2716f2627d, reversing changes made to 5ece2e4a4459065b5efd976aebd209bbf0cab89b. If a policy is set then we should generate it even if it's empty. However what is happening is that we're accidentally generating an empty policy when the initializer is commented out by default.
* Skip generating empty CSP header when no policy is configuredKohei Suzuki2018-02-181-2/+10
| | | | | | | | `Rails.application.config.content_security_policy` is configured with no policies by default. In this case, Content-Security-Policy header should not be generated instead of generating the header with no directives. Firefox also warns "Content Security Policy: Couldn't process unknown directive ''".
* Partly revert 1e526788e6b1d3f42f4d8fdca20e588d42838c80bogdanvlviv2018-02-171-1/+4
| | | | | | Some attr_readers should be `protected` instead of `private` See https://travis-ci.org/rails/rails/builds/342800276
* Rails 6 requires Ruby 2.3+Jeremy Daer2018-02-171-6/+1
|
* Enable autocorrect for `Lint/EndAlignment` copKoichi ITO2018-01-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ### Summary This PR changes .rubocop.yml. Regarding the code using `if ... else ... end`, I think the coding style that Rails expects is as follows. ```ruby var = if cond a else b end ``` However, the current .rubocop.yml setting does not offense for the following code. ```ruby var = if cond a else b end ``` I think that the above code expects offense to be warned. Moreover, the layout by autocorrect is unnatural. ```ruby var = if cond a else b end ``` This PR adds a setting to .rubocop.yml to make an offense warning and autocorrect as expected by the coding style. And this change also fixes `case ... when ... end` together. Also this PR itself is an example that arranges the layout using `rubocop -a`. ### Other Information Autocorrect of `Lint/EndAlignment` cop is `false` by default. https://github.com/bbatsov/rubocop/blob/v0.51.0/config/default.yml#L1443 This PR changes this value to `true`. Also this PR has changed it together as it is necessary to enable `Layout/ElseAlignment` cop to make this behavior.