| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
| |
Not strictly necessary, but this limits the damage in pathological
cases. These limits are probably already too generous, we could
probably get by with 8 params and 1024 bytes. One of tests uses
more than 1024 bytes, though. Still, it seems unlikely any
legitimate requests would exceed these limits. We could make the
limits configurable via an accessor method, if desired.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The ReDoS fix in ee25ab9a7ee981d7578f559701085b0cf39bde77 breaks valid
requests, because colons are valid inside parameter values. You cannot
use a regexp scan and ensure correct behavior, since values inside
parameters can be escaped. Issues like this are the reason for the
famous "now they have two problems" quote regarding regexps.
Add a basic parser for parameters in Content-Disposition. This parser
is based purely on String#{index,slice!,[],==}, usually with string
arguments for #index (though one case uses a simple regexp). There
are two loops (one nested in the other), but the use of slice! ensures
that forward progress is always made on each loop iteration.
In addition to fixing the bug introduced by the security fix, this
removes multiple separate passes over the mime head, one pass to get
the parameter name for Content-Disposition, and a separate pass to get
the filename. It removes the get_filename method, though some of the
code is kept in a smaller normalize_filename method.
This removes 18 separate regexp contents that were previously used
just for the separate parse to find the filename for the content
disposition.
Fixes #2076
|
| |
|
|
|
| |
- Fixes #1968
|
|
|
|
|
|
|
| |
An alternative approach would be using a single string inside an array
and appending to that. This approach is more backwards compatible,
but results in more memory usage.
Fixes #1957
|
|
|
|
|
|
|
|
| |
See https://github.com/rack/rack-test/issues/335 for an example
where allowing BodyProxy to respond to to_str (when provided an
invalid rack body) complicated debugging.
Call BodyProxy#close if BodyProxy#to_ary is called, as not doing so
violates SPEC.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Revert "Prefer to use `query_parser` itself as the cache key. (#2058)"
This reverts commit 5f90c33e4ccee827cb5df3d8854dc72791345c51.
* Revert "Fix handling of cached values in `Rack::Request`. (#2054)"
This reverts commit d25feddcbe634d95ec693bfbd710167a11c74069.
* Revert "Add `QueryParser#missing_value` for handling missing values + tests. (#2052)"
This reverts commit 59d9ba903fdb50cf8db708c8263a7b2a79de83fb.
* Revert "Split form/query parsing into two steps (#2038)"
This reverts commit 9f059d19647aeaef5c2cc683a333c06120caf939.
* Make query parameters without = have nil values
This was Rack's historical behavior. While it doesn't match
URL spec section 5.1.3.3, keeping the historical behavior avoids
all of the complexity required to support the URL spec standard
by default, but also support frameworks that want to be backwards
compatible.
This keeps as much of the specs added by the recently reverted
commits that make sense.
|
|
|
|
|
| |
* Per-class cache keys for cached query/body parameters.
* Use the query parser class as the default cache key.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
* Split form/query parsing into two steps
First we parse the raw input into a stream of [key, value] pairs, and
only after that do we expand that into the deep params hash.
This allows a user to operate directly on the pair stream if they need
to apply different semantics, without needing to rewind the input, and
without creating a conflict with anything else (like a middleware) that
wants to use Rack's standard GET / POST hash format.
|
| |
|
|
|
|
|
|
|
|
| |
Previously we would limit the number of multipart parts which were
files, but not other parts. In some cases this could cause parsing of
maliciously crafted inputs to take longer than expected.
[CVE-2023-27530]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Because of the to_params_hash method, this cannot be Hash itself.
We should consider deprecating that method and maybe the Params
constant as well.
Most of the spec changes are just changing overrides of
Params#initialize.
This tweaks the "not create infinite loops with cycle structures"
spec, because it wasn't actually testing for loops, it was
checking the string representation was the same between Hash
and Params. This spec could probably be eliminated, but the
tweak allows it to pass by checking that the level 1 hash string
representation is the same as the level 2 hash string representation.
|
| |
|
|
|
|
| |
Used to communicate a class of exceptions that represent 400 Bad Request
semantics.
|
| |
|
| |
|
|
|
|
|
|
| |
Cache errors that occur when invoking `Rack::Request#POST` so they can be
raised again later.
* Don't throw exactly the same error - so we have the correct backtrace.
|
|
|
|
|
|
|
| |
Followup: https://github.com/rack/rack/pull/2006
I renamed the wrong spec.
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
|
| |
|
|
|
|
|
|
| |
This middleware already handle two types of parsing issues
but somehow not this one.
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the formatted query string, the field should be fully URL-encoded.
The previous implementation left the square brackets as un-escaped.
It was noticed that if params were provided as a nested hash it produced
a different result than a hash of string fields. For example, the params
{ 'q[s]' => 'name' }
would result in the query string:
q%5Bs%5D=name
but
{ q: { s: 'name' } }
would result in:
q[s]=name
Both forms now produce the same correct result with fully URL-encoded
params.
|
|
|
|
|
|
| |
Many editors clean up trailing white space on save. By removing it all
in one go, it helps keep future diffs cleaner and eases new
contributions by avoiding spurious white space changes on unrelated
lines.
|
| |
|
|
|
|
|
| |
* Fix handling of `to_path` and add spec.
* Also forward `call`.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add rack.response_finished to Rack::Lint
This updates Rack::Lint to validate that `rack.response_finished` is an
array of callables when present in the `env`. e.g. procs, lambdas, or
objects that respond to `call`.
This validates that:
* `rack.response_finished` is an array
* The contents of the array all respond to `call`
|
|
|
|
|
| |
This is a better check that the internals are correctly using
require_relative and not relying on autoload.
|
|
|
| |
* Raise ArgumentError if both app and block given.
|
|
|
|
| |
into a separate gem. (#1937)
|
| |
|
|
|
|
|
|
|
| |
* Move Rack::MockRequest/Response into dedicated files.
At some point I think we want to improve the implementation of `Rack::Mock`
in a separate gem. So let's be consistent with naming these files to avoid
clobbering namespace in the future.
|
|
|
|
|
|
|
| |
* Separate full and partial rack hijack.
- Remove `rack.hijack_io` which is at best difficult to use and at worst buggy.
- Separate full and partial hijack specifications, `rack.hijack?` implies that partial hijacking is supported, `rack.hijack` implies that full hijacking is supported.
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
GzipWriter#close also closes the underlying IO, which in turn closes the
wrapped response body. If that body is a Rack::BodyProxy, the associated
block will run too early, before control has returned to the app server.
GzipWriter#finish closes the gzip stream, but not the underlying IO. The
response body will then be closed by the app server after iteration.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Ruby 3.2 will provide `Exception#detailed_message` which returns more
informative message including hints for debugging.
https://bugs.ruby-lang.org/issues/18564
The did_you_mean gem and error_highlight gem is planned to use the
method to add their hints in Ruby 3.2. So using `Exception#message` will
not include did_you_mean and error_highlight hints.
This changeset uses `Exception#detailed_message` if available to show
exceptions.
|
|
|
| |
When using \x prefix, users would expect hex escaping.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remove the use of BOUNDARY_REGEX, as well as the @boundary, @full_boundary,
and @end_boundary instance variables. Replace them with the existing
@body_regex, which already contains the boundary. Tweak body_regex slightly
so the preceding EOF is required if we aren't at the start of the buffer,
since boundaries must be on their own lines.
When looking for the boundary, scan until using @body_regex (i.e. until you
found the boundary). Differentiate the full_boundary from the end_boundary
by seeing if the scanned data ends with \r\n (full boundary will,
end_boundary must end with --). If no boundary is found, clear the buffer
and try again, for behavior similar to previous.
For the fast forward state, if the first boundary found is the end boundary,
ignore it and keep scanning. We could alternatively raise an exception, not
sure if that is better. The previous behavior of treating the end boundary
as the starting boundary was definitely wrong, though.
Add some comments describing this boundary parsing behavior (which was my
initial intent when working on this).
Speeds up test/spec_multipart.rb more than 6x in my testing.
|
|
|
|
|
|
| |
This fixes a shell escape issue
[CVE-2022-30123]
|
|
|
|
|
|
|
| |
This commit restricts broken mime parsing to deal with a ReDOS
vulnerability.
[CVE-2022-30122]
|
|
|
|
|
|
| |
It's already skipped on Ruby 2.4 and 2.5, so it's not like we
expect this to pass in all cases anyway. If it is fixed on JRuby,
we can renable. But it's better to not generate false negatives
in CI for unrelated changes.
|
|
|
|
|
| |
This limit comes from RFC 1521 Section 7.2.1. Clients generally
do not use boundaries longer than 55 characters.
|
|
|
|
|
|
|
| |
Coverage after this commit:
3273 relevant lines, 3273 lines covered and 0 lines missed. ( 100.0% )
1083 total branches, 1083 branches covered and 0 branches missed. ( 100.0% )
|
|
|
|
|
|
|
|
| |
Previously, this would raise an error for invalid charsets, but that
is unlikely to be desired behavior.
While here, inline the CHARSET constant, since it is only used in
a single case, and we are using frozen string literals.
|