From baedef6e14a6351fa4bc87a759a498da927c68a7 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Thu, 18 Jun 2026 11:21:38 +0200 Subject: [PATCH] Bug 42866: Prevent SQL injection in Koha::AddtionalContents->search_for_display Signed-off-by: Sanjar Tulkinov Anvar o'g'li Signed-off-by: Marcel de Rooy Signed-off-by: Lucas Gass (cherry picked from commit 9ed242f2e3ccdb944bac87f9033a695eac187f5c) Signed-off-by: Lucas Gass --- Koha/AdditionalContents.pm | 22 +++++++++++++++------- t/db_dependent/Koha/AdditionalContents.t | 11 ++++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Koha/AdditionalContents.pm b/Koha/AdditionalContents.pm index a30123d357..765eddb875 100644 --- a/Koha/AdditionalContents.pm +++ b/Koha/AdditionalContents.pm @@ -95,15 +95,23 @@ sub search_for_display { my ( $self, $params ) = @_; my $lang = $params->{lang} || q{}; - # If lang is not default, we will search for entries matching $lang but fallback to default if $lang is not found - # Then we need a subquery count in where clause; DBIx::Class/SQL::Abstract does not support it, fallback to literal SQL - my $subquery = - qq|(SELECT COUNT(*) FROM additional_contents_localizations WHERE lang='$lang' AND additional_content_id=me.additional_content_id)=0|; - my $search_params = get_public_query_search_params($params); $search_params->{lang} = 'default' if !$lang || $lang eq 'default'; - $search_params->{-or} = [ { 'lang' => $lang }, '-and' => [ 'lang', 'default', \$subquery ] ] - if !$search_params->{lang}; + + unless ( $search_params->{lang} ) { + $search_params->{-or} = [ + { lang => $lang }, + { + -and => [ + { lang => 'default' }, + \[ + '(SELECT COUNT(*) FROM additional_contents_localizations WHERE lang = ? AND additional_content_id = me.additional_content_id) = 0', + $lang + ] + ] + } + ]; + } my $attribs = { prefetch => 'additional_content', diff --git a/t/db_dependent/Koha/AdditionalContents.t b/t/db_dependent/Koha/AdditionalContents.t index 6811e480e3..b9cf4fadb5 100755 --- a/t/db_dependent/Koha/AdditionalContents.t +++ b/t/db_dependent/Koha/AdditionalContents.t @@ -192,7 +192,7 @@ subtest '->author' => sub { subtest '->search_for_display' => sub { - plan tests => 4; + plan tests => 5; $schema->storage->txn_begin; @@ -305,6 +305,15 @@ subtest '->search_for_display' => sub { # TODO We should add more tests here $schema->storage->txn_rollback; + + subtest 'prevent SQL injections' => sub { + plan tests => 1; + $schema->storage->txn_begin; + my $lang = q{' OR Booh!}; + Koha::AdditionalContents->search_for_display( { lang => $lang } )->count; + pass(q{Shouldn't get a warning or exception}); + $schema->storage->txn_rollback; + }; }; subtest 'find_best_match' => sub {