fix(ssrf): allow provider audio downloads
This commit is contained in:
@@ -101,6 +101,7 @@ class Sms::IncomingMessageService
|
||||
SafeFetch.fetch(
|
||||
media_url,
|
||||
http_basic_authentication: [channel.provider_config['api_key'], channel.provider_config['api_secret']],
|
||||
allowed_content_type_prefixes: %w[image/ video/ audio/],
|
||||
allowed_content_types: Attachment::ACCEPTABLE_FILE_TYPES,
|
||||
&
|
||||
)
|
||||
|
||||
@@ -175,6 +175,7 @@ class Twilio::IncomingMessageService
|
||||
SafeFetch.fetch(
|
||||
media_url,
|
||||
http_basic_authentication: auth_credentials,
|
||||
allowed_content_type_prefixes: %w[image/ video/ audio/],
|
||||
allowed_content_types: Attachment::ACCEPTABLE_FILE_TYPES,
|
||||
&
|
||||
)
|
||||
@@ -184,6 +185,7 @@ class Twilio::IncomingMessageService
|
||||
Rails.logger.info "Error downloading attachment from Twilio: #{error.message}: Retrying without auth"
|
||||
SafeFetch.fetch(
|
||||
media_url,
|
||||
allowed_content_type_prefixes: %w[image/ video/ audio/],
|
||||
allowed_content_types: Attachment::ACCEPTABLE_FILE_TYPES,
|
||||
&
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ module Whatsapp::IncomingMessageServiceHelpers
|
||||
SafeFetch.fetch(
|
||||
inbox.channel.media_url(attachment_payload[:id]),
|
||||
headers: inbox.channel.api_headers,
|
||||
allowed_content_type_prefixes: %w[image/ video/ audio/],
|
||||
allowed_content_types: Attachment::ACCEPTABLE_FILE_TYPES,
|
||||
&
|
||||
)
|
||||
|
||||
@@ -20,6 +20,7 @@ class Whatsapp::IncomingMessageWhatsappCloudService < Whatsapp::IncomingMessageB
|
||||
SafeFetch.fetch(
|
||||
url_response.parsed_response['url'],
|
||||
headers: inbox.channel.api_headers,
|
||||
allowed_content_type_prefixes: %w[image/ video/ audio/],
|
||||
allowed_content_types: Attachment::ACCEPTABLE_FILE_TYPES,
|
||||
&
|
||||
)
|
||||
|
||||
@@ -100,6 +100,18 @@ describe Sms::IncomingMessageService do
|
||||
expect(sms_channel.inbox.messages.first.attachments.present?).to be true
|
||||
end
|
||||
|
||||
it 'creates audio attachment messages' do
|
||||
stub_request(:get, 'http://test.com/test.mp3')
|
||||
.to_return(status: 200, body: File.read('spec/assets/sample.mp3'), headers: { 'Content-Type' => 'audio/mpeg' })
|
||||
|
||||
media_params = { 'media': ['http://test.com/test.mp3'] }.with_indifferent_access
|
||||
|
||||
described_class.new(inbox: sms_channel.inbox, params: params.merge(media_params)).perform
|
||||
|
||||
attachment = sms_channel.inbox.messages.first.attachments.first
|
||||
expect(attachment.file_type).to eq('audio')
|
||||
end
|
||||
|
||||
it 'skips blocked attachment URLs' do
|
||||
media_params = { 'media': ['http://127.0.0.1/blocked.png'] }.with_indifferent_access
|
||||
|
||||
|
||||
@@ -179,6 +179,8 @@ describe Twilio::IncomingMessageService do
|
||||
before do
|
||||
stub_request(:get, 'https://chatwoot-assets.local/sample.png')
|
||||
.to_return(status: 200, body: 'image data', headers: { 'Content-Type' => 'image/png' })
|
||||
stub_request(:get, 'https://chatwoot-assets.local/sample.mp3')
|
||||
.to_return(status: 200, body: File.read('spec/assets/sample.mp3'), headers: { 'Content-Type' => 'audio/mpeg' })
|
||||
end
|
||||
|
||||
let(:params_with_attachment) do
|
||||
@@ -207,6 +209,18 @@ describe Twilio::IncomingMessageService do
|
||||
expect(WebMock).to(have_requested(:get, 'https://chatwoot-assets.local/sample.png')
|
||||
.with { |request| request.headers['Authorization']&.start_with?('Basic ') })
|
||||
end
|
||||
|
||||
it 'creates an audio attachment when the provider serves audio media' do
|
||||
params_with_audio_attachment = params_with_attachment.merge(
|
||||
MediaContentType0: 'audio/mpeg',
|
||||
MediaUrl0: 'https://chatwoot-assets.local/sample.mp3'
|
||||
)
|
||||
|
||||
described_class.new(params: params_with_audio_attachment).perform
|
||||
|
||||
attachment = conversation.reload.messages.last.attachments.first
|
||||
expect(attachment.file_type).to eq('audio')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is an error downloading the attachment' do
|
||||
|
||||
@@ -234,6 +234,27 @@ describe Whatsapp::IncomingMessageService do
|
||||
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be true
|
||||
end
|
||||
|
||||
it 'creates audio attachments when the provider serves audio media' do
|
||||
stub_request(:get, whatsapp_channel.media_url('b1c68f38-8734-4ad3-b4a1-ef0c10d683')).to_return(
|
||||
status: 200,
|
||||
body: File.read('spec/assets/sample.mp3'),
|
||||
headers: { 'Content-Type' => 'audio/mpeg' }
|
||||
)
|
||||
params = {
|
||||
'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }],
|
||||
'messages' => [{ 'from' => '2423423243', 'id' => 'SDFADSf23sfasdafasdfa',
|
||||
'audio' => { 'id' => 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
|
||||
'mime_type' => 'audio/mpeg',
|
||||
'sha256' => '29ed500fa64eb55fc19dc4124acb300e5dcca0f822a301ae99944db' },
|
||||
'timestamp' => '1633034394', 'type' => 'audio' }]
|
||||
}.with_indifferent_access
|
||||
|
||||
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
||||
|
||||
attachment = whatsapp_channel.inbox.messages.first.attachments.first
|
||||
expect(attachment.file_type).to eq('audio')
|
||||
end
|
||||
|
||||
it 'skips blocked attachment URLs' do
|
||||
allow(whatsapp_channel).to receive(:media_url).and_return('http://127.0.0.1/blocked.png')
|
||||
params = {
|
||||
|
||||
@@ -47,6 +47,30 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
||||
expect_message_has_attachment
|
||||
end
|
||||
|
||||
it 'creates audio attachments when the provider serves audio media' do
|
||||
params[:entry][0][:changes][0][:value][:messages][0] = {
|
||||
from: '2423423243',
|
||||
audio: {
|
||||
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
|
||||
mime_type: 'audio/mpeg',
|
||||
sha256: '29ed500fa64eb55fc19dc4124acb300e5dcca0f822a301ae99944db'
|
||||
},
|
||||
timestamp: '1664799904',
|
||||
type: 'audio'
|
||||
}
|
||||
stub_media_url_request(url: 'https://chatwoot-assets.local/sample.mp3')
|
||||
stub_request(:get, 'https://chatwoot-assets.local/sample.mp3').to_return(
|
||||
status: 200,
|
||||
body: File.read('spec/assets/sample.mp3'),
|
||||
headers: { 'Content-Type' => 'audio/mpeg' }
|
||||
)
|
||||
|
||||
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
||||
|
||||
attachment = whatsapp_channel.inbox.messages.first.attachments.first
|
||||
expect(attachment.file_type).to eq('audio')
|
||||
end
|
||||
|
||||
it 'sends the provider headers when downloading the resolved media URL' do
|
||||
stub_media_url_request
|
||||
stub_sample_png_request
|
||||
|
||||
Reference in New Issue
Block a user