Skip to content

Commit

Permalink
Limit description lengths to mitigate potential DoS
Browse files Browse the repository at this point in the history
  • Loading branch information
akadusei committed Jul 27, 2024
1 parent 52c993b commit cd7012c
Show file tree
Hide file tree
Showing 15 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Changed
- Upgrade GitHub actions
- Limit description lengths to mitigate potential DoS

## [0.17.0] - 2024-06-02

Expand Down
1 change: 1 addition & 0 deletions docs/10-I18N.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ en:
credit_note_not_found: Credit note does not exist
credit_or_debit_required: Is this a credit or a debit?
description_required: Description is required
description_too_long: Description cannot be longer than %{max} characters
due_at_required: Due time is required
inactive_at_earlier: Inactive time cannot be earlier than active time
invoice_id_invalid: Invoice ID is invalid
Expand Down
29 changes: 29 additions & 0 deletions spec/bill/operations/mixins/validate_credit_note_item_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,33 @@ describe Bill::ValidateCreditNoteItem do
operation.id.should_not have_error
end
end

it "rejects long description" do
invoice = CreateInvoice.create!(
params(
user_id: UserFactory.create.id,
description: "New invoice",
due_at: 3.days.from_now,
status: :open
),
line_items: [{
"description" => "Item 1",
"quantity" => "1",
"price" => "999"
}]
)

credit_note = CreditNoteFactory.create &.invoice_id(invoice.id)

SaveCreditNoteItem.create(params(
description: "d" * 600,
credit_note_id: credit_note.id,
price: 1
)) do |operation, credit_note_item|
credit_note_item.should be_nil

operation.description
.should(have_error "operation.error.description_too_long")
end
end
end
17 changes: 17 additions & 0 deletions spec/bill/operations/mixins/validate_credit_note_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,21 @@ describe Bill::ValidateCreditNote do
operation.reference.should have_error("operation.error.reference_exists")
end
end

it "rejects long description" do
user = UserFactory.create
invoice = InvoiceFactory.create &.user_id(user.id).status(:open)

SaveCreditNote.create(params(
invoice_id: invoice.id,
description: "d" * 600,
reference: "123",
status: :open
)) do |operation, credit_note|
credit_note.should be_nil

operation.description
.should(have_error "operation.error.description_too_long")
end
end
end
17 changes: 17 additions & 0 deletions spec/bill/operations/mixins/validate_invoice_item_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,21 @@ describe Bill::ValidateInvoiceItem do
.should have_error("operation.error.quantity_lte_zero")
end
end

it "rejects long description" do
user = UserFactory.create
invoice = InvoiceFactory.create &.user_id(user.id)

SaveInvoiceItem.create(params(
invoice_id: invoice.id,
description: "d" * 600,
quantity: 0,
price: 222
)) do |operation, invoice_item|
invoice_item.should be_nil

operation.description
.should(have_error "operation.error.description_too_long")
end
end
end
19 changes: 19 additions & 0 deletions spec/bill/operations/mixins/validate_invoice_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,23 @@ describe Bill::ValidateInvoice do
operation.reference.should have_error("operation.error.reference_exists")
end
end

it "rejects long description" do
user = UserFactory.create

SaveInvoice.create(params(
user_id: user.id,
business_details: "ACME Inc",
description: "d" * 600,
due_at: 1.day.from_now,
reference: "123",
status: :open,
user_details: "Mary Smith"
)) do |operation, invoice|
invoice.should be_nil

operation.description
.should(have_error "operation.error.description_too_long")
end
end
end
19 changes: 19 additions & 0 deletions spec/bill/operations/mixins/validate_receipt_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,23 @@ describe Bill::ValidateReceipt do
operation.reference.should have_error("operation.error.reference_exists")
end
end

it "rejects long description" do
user = UserFactory.create

SaveReceipt.create(params(
user_id: user.id,
business_details: "ACME Inc",
description: "d" * 600,
amount: 90,
reference: "123",
status: :open,
user_details: "Mary Smith"
)) do |operation, receipt|
receipt.should be_nil

operation.description
.should(have_error "operation.error.description_too_long")
end
end
end
18 changes: 18 additions & 0 deletions spec/bill/operations/mixins/validate_transaction_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,22 @@ describe Bill::ValidateTransaction do
operation.reference.should have_error("operation.error.reference_exists")
end
end

it "rejects long description" do
user = UserFactory.create

SaveTransaction.create(params(
user_id: user.id,
description: "d" * 600,
amount: 33,
reference: "123",
status: :open,
type: :invoice,
)) do |operation, transaction|
transaction.should be_nil

operation.description
.should(have_error "operation.error.description_too_long")
end
end
end
1 change: 1 addition & 0 deletions src/bill/operations/mixins/validate_credit_note.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Bill::ValidateCreditNote

include Bill::ValidateStatusTransition
include Bill::ValidateReference
include Bill::ValidateDescription

private def validate_status_required
validate_required status,
Expand Down
2 changes: 2 additions & 0 deletions src/bill/operations/mixins/validate_credit_note_item.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ module Bill::ValidateCreditNoteItem
validate_credit_lte_invoice
end

include Bill::ValidateDescription

private def validate_credit_note_id_required
validate_required credit_note_id,
message: Rex.t(:"operation.error.credit_note_id_required")
Expand Down
17 changes: 17 additions & 0 deletions src/bill/operations/mixins/validate_description.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Bill::ValidateDescription
macro included
skip_default_validations

before_save do
validate_description_length
end

private def validate_description_length
max = 510

validate_size_of description,
max: max,
message: Rex.t(:"operation.error.description_too_long", max: max)
end
end
end
1 change: 1 addition & 0 deletions src/bill/operations/mixins/validate_invoice.cr
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Bill::ValidateInvoice

include Bill::ValidateStatusTransition
include Bill::ValidateReference
include Bill::ValidateDescription
include Lucille::ValidateUserExists

private def validate_business_details_required
Expand Down
2 changes: 2 additions & 0 deletions src/bill/operations/mixins/validate_invoice_item.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ module Bill::ValidateInvoiceItem
validate_invoice_exists
end

include Bill::ValidateDescription

private def validate_invoice_id_required
validate_required invoice_id,
message: Rex.t(:"operation.error.invoice_id_required")
Expand Down
1 change: 1 addition & 0 deletions src/bill/operations/mixins/validate_receipt.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Bill::ValidateReceipt

include Bill::ValidateStatusTransition
include Bill::ValidateReference
include Bill::ValidateDescription
include Lucille::ValidateUserExists

private def validate_amount_required
Expand Down
1 change: 1 addition & 0 deletions src/bill/operations/mixins/validate_transaction.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Bill::ValidateTransaction
include Lucille::ValidateUserExists
include Bill::ValidateStatusTransition
include Bill::ValidateReference
include Bill::ValidateDescription

private def validate_user_id_required
validate_required user_id,
Expand Down

0 comments on commit cd7012c

Please sign in to comment.