1
0
Fork 0
mirror of https://github.com/rest-client/rest-client.git synced 2022-11-09 13:49:40 -05:00

Switch to multipart boundary with more entropy.

The previous boundary used a random number up to 1,000,000 as the
boundary. This is extremely low entropy compared to what most major
browsers use (20 bits). Instead, use a convention more like WebKit.

RestClient previously would be completely unable to upload a file
generated like so, containing `--0--` through `--1000000--`:

    File.open('foo.txt', 'w') {|f|
      1_000_000.times {|i| f.write("--#{i}--\n") }}

Instead, the boundary now looks like this, with about 95 bits of entropy:
    `----RubyFormBoundaryFg2MqiXXQlT5RkUF`
This commit is contained in:
Andy Brody 2015-11-14 18:37:56 -08:00
parent 66b05f9cac
commit 0d5674d84a
2 changed files with 19 additions and 2 deletions

View file

@ -1,5 +1,7 @@
require 'tempfile'
require 'securerandom'
require 'stringio'
require 'mime/types'
module RestClient
@ -153,7 +155,7 @@ module RestClient
EOL = "\r\n"
def build_stream(params)
b = "--#{boundary}"
b = '--' + boundary
@stream = Tempfile.new("RESTClient.Stream.#{rand(1000)}")
@stream.binmode
@ -209,7 +211,15 @@ module RestClient
end
def boundary
@boundary ||= rand(1_000_000).to_s
return @boundary if @boundary
# Use the same algorithm used by WebKit: generate 16 random
# alphanumeric characters, replacing `+` `/` with `A` `B` (included in
# the list twice) to round out the set of 64.
s = SecureRandom.base64(12)
s.tr!('+/', 'AB')
@boundary = '----RubyFormBoundary' + s
end
# for Multipart do not escape the keys

View file

@ -167,6 +167,13 @@ Content-Type: text/plain\r
EOS
end
it 'should correctly format hex boundary' do
SecureRandom.stub(:base64).with(12).and_return('TGs89+ttw/xna6TV')
f = File.new(File.dirname(__FILE__) + '/master_shake.jpg')
m = RestClient::Payload::Multipart.new({:foo => f})
m.boundary.should eq('-' * 4 + 'RubyFormBoundary' + 'TGs89AttwBxna6TV')
end
end
context "streamed payloads" do