mirror of
https://github.com/jnunemaker/httparty
synced 2023-03-27 23:23:07 -04:00
escape filename in the multipart/form-data Content-Disposition header
This commit is contained in:
parent
c27adec455
commit
051c181ef4
2 changed files with 40 additions and 1 deletions
|
@ -32,6 +32,13 @@ module HTTParty
|
|||
|
||||
private
|
||||
|
||||
# https://html.spec.whatwg.org/#multipart-form-data
|
||||
MULTIPART_FORM_DATA_REPLACEMENT_TABLE = {
|
||||
'"' => '%22',
|
||||
"\r" => '%0D',
|
||||
"\n" => '%0A'
|
||||
}.freeze
|
||||
|
||||
def generate_multipart
|
||||
normalized_params = params.flat_map { |key, value| HashConversions.normalize_keys(key, value) }
|
||||
|
||||
|
@ -40,7 +47,7 @@ module HTTParty
|
|||
memo << %(Content-Disposition: form-data; name="#{key}")
|
||||
# value.path is used to support ActionDispatch::Http::UploadedFile
|
||||
# https://github.com/jnunemaker/httparty/pull/585
|
||||
memo << %(; filename="#{file_name(value)}") if file?(value)
|
||||
memo << %(; filename="#{file_name(value).gsub(/["\r\n]/, MULTIPART_FORM_DATA_REPLACEMENT_TABLE)}") if file?(value)
|
||||
memo << NEWLINE
|
||||
memo << "Content-Type: #{content_type(value)}#{NEWLINE}" if file?(value)
|
||||
memo << NEWLINE
|
||||
|
|
|
@ -105,6 +105,38 @@ RSpec.describe HTTParty::Request::Body do
|
|||
|
||||
it { is_expected.to eq multipart_params }
|
||||
end
|
||||
|
||||
context 'when file name contains [ " \r \n ]' do
|
||||
let(:options) { { force_multipart: true } }
|
||||
let(:some_temp_file) { Tempfile.new(['basefile', '.txt']) }
|
||||
let(:file_content) { 'test' }
|
||||
let(:raw_filename) { "dummy=tampering.sh\"; \r\ndummy=a.txt" }
|
||||
let(:expected_file_name) { 'dummy=tampering.sh%22; %0D%0Adummy=a.txt' }
|
||||
let(:file) { double(:mocked_action_dispatch, path: some_temp_file.path, original_filename: raw_filename, read: file_content) }
|
||||
let(:params) do
|
||||
{
|
||||
user: {
|
||||
attachment_file: file,
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
end
|
||||
let(:multipart_params) do
|
||||
"--------------------------c772861a5109d5ef\r\n" \
|
||||
"Content-Disposition: form-data; name=\"user[attachment_file]\"; filename=\"#{expected_file_name}\"\r\n" \
|
||||
"Content-Type: text/plain\r\n" \
|
||||
"\r\n" \
|
||||
"test\r\n" \
|
||||
"--------------------------c772861a5109d5ef\r\n" \
|
||||
"Content-Disposition: form-data; name=\"user[enabled]\"\r\n" \
|
||||
"\r\n" \
|
||||
"true\r\n" \
|
||||
"--------------------------c772861a5109d5ef--\r\n"
|
||||
end
|
||||
|
||||
it { is_expected.to eq multipart_params }
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue