diff options
author | Jeremy Evans <code@jeremyevans.net> | 2022-05-25 11:07:17 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2022-05-25 12:52:44 -0700 |
commit | d866dc42f5d886d94b91eacba9f7da8ba72e66ce (patch) | |
tree | bac515974ff98782e0df9f68494479475d7c8c0e | |
parent | 7605ec326c342d444ec0c9eb77dcb5a08739e9e2 (diff) | |
download | rack-d866dc42f5d886d94b91eacba9f7da8ba72e66ce.tar.gz |
Impose a 70 character limit on boundary size
This limit comes from RFC 1521 Section 7.2.1. Clients generally do not use boundaries longer than 55 characters.
-rw-r--r-- | lib/rack/multipart/parser.rb | 10 | ||||
-rw-r--r-- | test/spec_multipart.rb | 7 |
2 files changed, 17 insertions, 0 deletions
diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb index 8e770ecf..6fcfd487 100644 --- a/lib/rack/multipart/parser.rb +++ b/lib/rack/multipart/parser.rb @@ -12,6 +12,10 @@ module Rack # that ends early. class EmptyContentError < ::EOFError; end + # Base class for multipart exceptions that do not subclass from + # other exception classes for backwards compatibility. + class Error < StandardError; end + EOL = "\r\n" MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|ni TOKEN = /[^\s()<>,;:\\"\/\[\]?=]+/ @@ -92,6 +96,12 @@ module Rack boundary = parse_boundary content_type return EMPTY unless boundary + if boundary.length > 70 + # RFC 1521 Section 7.2.1 imposes a 70 character maximum for the boundary. + # Most clients use no more than 55 characters. + raise Error, "multipart boundary size too large (#{boundary.length} characters)" + end + io = BoundedIO.new(io, content_length) if content_length parser = new(boundary, tmpfile, bufsize, qp) diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb index 12065aa1..d921a4b9 100644 --- a/test/spec_multipart.rb +++ b/test/spec_multipart.rb @@ -35,6 +35,13 @@ describe Rack::Multipart do Rack::Multipart.parse_multipart(env).must_be_nil end + it "raises exception if boundary is too long" do + env = Rack::MockRequest.env_for("/", multipart_fixture(:content_type_and_no_filename, "A"*71)) + lambda { + Rack::Multipart.parse_multipart(env) + }.must_raise Rack::Multipart::Error + end + it "parse multipart content when content type present but disposition is not" do env = Rack::MockRequest.env_for("/", multipart_fixture(:content_type_and_no_disposition)) params = Rack::Multipart.parse_multipart(env) |