From 96e3e2607dbfc454e0af1aa704fb49a9383f3e5d Mon Sep 17 00:00:00 2001 From: Lari Taskula Date: Thu, 5 Feb 2026 16:31:11 +0200 Subject: [PATCH] Bug 38365: Set limitations on endpoint input This patch attempts to set some sane input limits to the CSP violation report. To test: 1. Rebuild API redocly bundle --ext json api/v1/swagger/swagger.yaml --output api/v1/swagger/swagger_bundle.json 2. t/db_dependent/api/v1/public/csp_reports.t --- api/v1/swagger/definitions/csp_report.yaml | 14 +++++++++++ t/db_dependent/api/v1/public/csp_reports.t | 27 +++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/api/v1/swagger/definitions/csp_report.yaml b/api/v1/swagger/definitions/csp_report.yaml index e175c911f2f..69793c0d925 100644 --- a/api/v1/swagger/definitions/csp_report.yaml +++ b/api/v1/swagger/definitions/csp_report.yaml @@ -11,37 +11,51 @@ properties: document-uri: type: string description: The URI of the document where the violation occurred + maxLength: 200 referrer: type: string description: The referrer of the document where the violation occurred + maxLength: 200 violated-directive: type: string description: The directive that was violated (e.g., "script-src 'self'") + maxLength: 100 effective-directive: type: string description: The effective directive that was violated + maxLength: 100 original-policy: type: string description: The original CSP policy as specified in the header + maxLength: 400 disposition: type: string description: Either "enforce" or "report" depending on CSP mode + enum: + - enforce + - report blocked-uri: type: string description: The URI of the resource that was blocked + maxLength: 200 line-number: type: integer description: Line number in the document where the violation occurred + maximum: 999999 column-number: type: integer description: Column number where the violation occurred + maximum: 999999 source-file: type: string description: The URI of the script where the violation occurred + maxLength: 200 status-code: type: integer description: HTTP status code of the document + maximum: 999 script-sample: type: string description: First 40 characters of the inline script that caused the violation + maxLength: 41 additionalProperties: true diff --git a/t/db_dependent/api/v1/public/csp_reports.t b/t/db_dependent/api/v1/public/csp_reports.t index 2a910baf997..50d0c4cf3fa 100755 --- a/t/db_dependent/api/v1/public/csp_reports.t +++ b/t/db_dependent/api/v1/public/csp_reports.t @@ -37,7 +37,7 @@ t::lib::Mocks::mock_config( 'api_secret_passphrase', 'test' ); subtest 'add() tests' => sub { - plan tests => 13; + plan tests => 19; $schema->storage->txn_begin; @@ -68,6 +68,31 @@ subtest 'add() tests' => sub { $csp_report )->status_is( 401, 'CSP report denied (401)' ) ->json_is( '/error', 'Invalid token.', '...because of an invalid token' ); + $csp_report->{'csp-report'}->{'line-number'} = 99999999999999999; + + # Anonymous request should reject too long integers + $t->post_ok( '/api/v1/public/csp-reports?token=' + . csp_token() => { 'Content-Type' => 'application/csp-report' } => json => $csp_report ) + ->status_is( 400, 'CSP report rejected (400) because of line-number exceeding maximum value' ); + $csp_report->{'csp-report'}->{'line-number'} = 42; + + $csp_report->{'csp-report'}->{'disposition'} = 'this is not okay'; + + # Anonymous request should reject values not in enum + $t->post_ok( '/api/v1/public/csp-reports?token=' + . csp_token() => { 'Content-Type' => 'application/csp-report' } => json => $csp_report ) + ->status_is( 400, 'CSP report rejected (400) because of disposition is not either "enforce" nor "report"' ); + $csp_report->{'csp-report'}->{'disposition'} = 'enforce'; + + $csp_report->{'csp-report'}->{'script-sample'} = + 'this is way too long script sample. a maximum of only 40 characters is allowed'; + + # Anonymous request should reject too long strings + $t->post_ok( '/api/v1/public/csp-reports?token=' + . csp_token() => { 'Content-Type' => 'application/csp-report' } => json => $csp_report ) + ->status_is( 400, 'CSP report rejected (400) because of script-sample exceeding maximum length' ); + $csp_report->{'csp-report'}->{'script-sample'} = 'console.log("hi");'; + # Anonymous request should work (browsers send these without auth) $t->post_ok( '/api/v1/public/csp-reports?token=' . csp_token() => { 'Content-Type' => 'application/csp-report' } => json => $csp_report ) -- 2.34.1