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

Signed-off-by: David Cook <dcook@prosentient.com.au>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
Lari Taskula 2026-02-05 16:31:11 +02:00 committed by Jonathan Druart
parent b027a437c1
commit a472e6354a
No known key found for this signature in database
GPG Key ID: A085E712BEF0E0F0
2 changed files with 47 additions and 2 deletions

View File

@ -11,37 +11,54 @@ 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
minimum: 0
maximum: 999999
column-number:
type: integer
description: Column number where the violation occurred
minimum: 0
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
minimum: 0
maximum: 999
script-sample:
type: string
description: First 40 characters of the inline script that caused the violation
maxLength: 41
additionalProperties: true

View File

@ -36,7 +36,7 @@ t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
subtest 'add() tests' => sub {
plan tests => 7;
plan tests => 15;
$schema->storage->txn_begin;
@ -52,11 +52,39 @@ subtest 'add() tests' => sub {
'blocked-uri' => 'inline',
'line-number' => 42,
'column-number' => 10,
'source-file' => 'https://library.example.org/cgi-bin/koha/opac-main.pl',
'source-file' => 'https://library.example.org/cgi-bin/koah/opac-main.pl',
'status-code' => 200,
}
};
$csp_report->{'csp-report'}->{'line-number'} = 99999999999999999;
# Too large integers should be rejected
$t->post_ok( '/api/v1/public/csp-reports' => { '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'} = -1;
# Too small integers should be rejected
$t->post_ok( '/api/v1/public/csp-reports' => { 'Content-Type' => 'application/csp-report' } => json => $csp_report )
->status_is( 400, 'CSP report rejected (400) because of line-number not reaching minimum value' );
$csp_report->{'csp-report'}->{'line-number'} = 42;
$csp_report->{'csp-report'}->{'disposition'} = 'this is not okay';
# Enum values should be confirmed
$t->post_ok( '/api/v1/public/csp-reports' => { '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';
# Too long strings should be rejected
$t->post_ok( '/api/v1/public/csp-reports' => { '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' => { 'Content-Type' => 'application/csp-report' } => json => $csp_report )
->status_is( 204, 'CSP report accepted' );