Fixed issue #2141 by switching to strict_decode64 for validating base64 content

This commit is contained in:
Billy Zhou 2018-08-02 18:04:09 +08:00
commit b358374ff5
2 changed files with 83 additions and 3 deletions

View file

@ -94,14 +94,17 @@ module CreatesTicketArticles
preferences[store_key] = attachment[key]
end
if !attachment[:data].match?(%r{^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$})
begin
base64_data = attachment[:data].gsub(/[\r\n]/, '')
attachment_data = Base64.strict_decode64(base64_data)
rescue ArgumentError => e
raise Exceptions::UnprocessableEntity, "Invalid base64 for attachment with index '#{index}'"
end
Store.add(
object: 'Ticket::Article',
o_id: article.id,
data: Base64.decode64(attachment[:data]),
data: attachment_data,
filename: attachment[:filename],
preferences: preferences,
)

View file

@ -551,7 +551,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_not(file.preferences['Content-ID'])
end
test '01.15 ticket create with agent - minimal article and attachment missing mine-type with customer' do
test '01.15 ticket create with agent - minimal article and simple invalid base64 attachment with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = {
title: 'a new ticket #15',
@ -574,6 +574,83 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal('Invalid base64 for attachment with index \'0\'', result['error'])
end
test '01.15a ticket create with agent - minimal article and large invalid base64 attachment with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = {
title: 'a new ticket #15a',
group: 'Users',
customer_id: @customer_without_org.id,
article: {
subject: 'some test 123',
body: 'some test 123',
attachments: [
'filename' => 'some_file.txt',
'data' => "LARGE_INVALID_BASE64_#{'#' * 20_000_000}",
'mime-type' => 'text/plain',
],
},
}
post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
assert_response(422)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('Invalid base64 for attachment with index \'0\'', result['error'])
end
test '01.15b ticket create with agent - minimal article and valid multiline base64 with linebreaks attachment with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = {
title: 'a new ticket #15b',
group: 'Users',
customer_id: @customer_without_org.id,
article: {
subject: 'some test 123',
body: 'some test 123',
attachments: [
'filename' => 'some_file.txt',
'data' => Base64.encode64('a' * 1_000),
'mime-type' => 'text/plain',
],
},
}
post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
assert_response(201)
result = JSON.parse(@response.body)
assert_equal('a new ticket #15b', result['title'])
ticket = Ticket.find(result['id'])
assert_equal(1, ticket.articles.count)
assert_equal(1, ticket.articles.first.attachments.count)
file = ticket.articles.first.attachments.first
assert_equal('a' * 1_000, file.content)
end
test '01.15c ticket create with agent - minimal article and valid multiline base64 without linebreaks attachment with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = {
title: 'a new ticket #15c',
group: 'Users',
customer_id: @customer_without_org.id,
article: {
subject: 'some test 123',
body: 'some test 123',
attachments: [
'filename' => 'some_file.txt',
'data' => Base64.strict_encode64('a' * 1_000),
'mime-type' => 'text/plain',
],
},
}
post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
assert_response(201)
result = JSON.parse(@response.body)
assert_equal('a new ticket #15c', result['title'])
ticket = Ticket.find(result['id'])
assert_equal(1, ticket.articles.count)
assert_equal(1, ticket.articles.first.attachments.count)
file = ticket.articles.first.attachments.first
assert_equal('a' * 1_000, file.content)
end
test '01.16 ticket create with agent - minimal article and attachment invalid base64 with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = {