diff --git a/spec/models/ticket/article_spec.rb b/spec/models/ticket/article_spec.rb index 9dce6b42c..888682f0a 100644 --- a/spec/models/ticket/article_spec.rb +++ b/spec/models/ticket/article_spec.rb @@ -57,6 +57,37 @@ RSpec.describe Ticket::Article, type: :model do end end + describe 'DoS protection:' do + context 'when #body exceeds 1.5MB' do + subject(:article) { create(:ticket_article, body: body) } + let(:body) { 'a' * 2_000_000 } + + context 'for "web" thread', application_handle: 'web' do + it 'raises an Unprocessable Entity error' do + expect { article }.to raise_error(Exceptions::UnprocessableEntity) + end + end + + context 'for "test.postmaster" thread', application_handle: 'test.postmaster' do + it 'truncates body to 1.5 million chars' do + expect(article.body.length).to eq(1_500_000) + end + + context 'with NULL bytes' do + let(:body) { "\u0000" + 'a' * 2_000_000 } + + it 'still removes them, if necessary (postgres doesn’t like them)' do + expect(article).to be_persisted + end + + it 'still truncates body' do + expect(article.body.length).to eq(1_500_000) + end + end + end + end + end + describe 'Cti::Log syncing:' do context 'with existing Log records' do context 'for an incoming call from an unknown number' do diff --git a/test/unit/ticket_article_dos_test.rb b/test/unit/ticket_article_dos_test.rb deleted file mode 100644 index 0cb816b6c..000000000 --- a/test/unit/ticket_article_dos_test.rb +++ /dev/null @@ -1,108 +0,0 @@ -require 'test_helper' - -class TicketArticleDos < ActiveSupport::TestCase - - def two_mio_random_chars - @two_mio_random_chars ||= Array.new(2_000_000) { [*'0'..'9', *'a'..'z', ' ', ' ', ' ', '. '].sample }.join - end - - test 'check body size' do - - org_community = Organization.create_if_not_exists( - name: 'Zammad Foundation', - ) - user_community = User.create_or_update( - login: 'article.dos@example.org', - firstname: 'Article', - lastname: 'Dos', - email: 'article.dos@example.org', - password: '', - active: true, - roles: [ Role.find_by(name: 'Customer') ], - organization_id: org_community.id, - updated_by_id: 1, - created_by_id: 1, - ) - - UserInfo.current_user_id = user_community.id - ApplicationHandleInfo.current = 'test.postmaster' - - ticket1 = Ticket.create!( - group_id: Group.first.id, - customer_id: user_community.id, - title: 'DoS 1!', - updated_by_id: 1, - created_by_id: 1, - ) - article1 = Ticket::Article.create!( - ticket_id: ticket1.id, - type_id: Ticket::Article::Type.find_by(name: 'phone').id, - sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, - from: 'Zammad Feedback ', - body: two_mio_random_chars, - internal: false, - updated_by_id: 1, - created_by_id: 1, - ) - assert_equal(1_500_000, article1.body.length) - - ticket2 = Ticket.create!( - group_id: Group.first.id, - customer_id: user_community.id, - title: 'DoS 2!', - updated_by_id: 1, - created_by_id: 1, - ) - article2 = Ticket::Article.create!( - ticket_id: ticket2.id, - type_id: Ticket::Article::Type.find_by(name: 'phone').id, - sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, - from: 'Zammad Feedback ', - body: "\u0000#{two_mio_random_chars}", - internal: false, - updated_by_id: 1, - created_by_id: 1, - ) - assert_equal(1_500_000, article2.body.length) - - ApplicationHandleInfo.current = 'web' - - ticket3 = Ticket.create!( - group_id: Group.first.id, - customer_id: user_community.id, - title: 'DoS 3!', - updated_by_id: 1, - created_by_id: 1, - ) - - assert_raises(Exceptions::UnprocessableEntity) do - article3 = Ticket::Article.create!( - ticket_id: ticket3.id, - type_id: Ticket::Article::Type.find_by(name: 'phone').id, - sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, - from: 'Zammad Feedback ', - body: "\u0000#{two_mio_random_chars}", - internal: false, - updated_by_id: 1, - created_by_id: 1, - ) - end - - end - - test 'check body size / cut if email' do - - email_raw_string = <<-MAIL.strip_indent - From: me@example.com - To: customer@example.com - Subject: some new subject - - Some Text#{two_mio_random_chars} - MAIL - - ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) - assert_equal(1_500_000, article_p.body.length) - - end - -end