Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:apache2
User: [email protected]
Usertags: pu

[ Reason ]
Apache2 is vulnerable to various medium CVEs (CVE-2026-29167, CVE-2026-29170,
CVE-2026-34355, CVE-2026-34356, CVE-2026-42535, CVE-2026-42536,
CVE-2026-43951, CVE-2026-44119, CVE-2026-44185, CVE-2026-44186,
CVE-2026-44631, CVE-2026-48913).

[ Impact ]
Medium security issues

[ Tests ]
Diff contains a test-framework update

[ Risks ]
As usual with Apache, low but not null risk

[ Checklist ]
  [X] *all* changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in (old)stable
  [X] the issue is verified as fixed in unstable

[ Changes ]
This release contains only fixes (a lot...)

[ Other info ]
I put here just the debian/ diff. The whole diff is big
diff --git a/debian/changelog b/debian/changelog
index a04158c1..8e4b38fa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+apache2 (2.4.68-1~deb13u1) trixie; urgency=medium
+
+  * New upstream version (Closes: CVE-2026-29167, CVE-2026-29170,
+    CVE-2026-34355, CVE-2026-34356, CVE-2026-42535, CVE-2026-42536,
+    CVE-2026-43951, CVE-2026-44119, CVE-2026-44185, CVE-2026-44186,
+    CVE-2026-44631, CVE-2026-48913)
+  * Drop CVE-2026-49975_*, now included in upstream
+  * Update debian/convert_docs
+  * Update test framework
+
+ -- Xavier Guimard <[email protected]>  Thu, 11 Jun 2026 20:28:43 +0200
+
 apache2 (2.4.67-1~deb13u3) trixie-security; urgency=medium
 
   * Fix CVE-2026-49975 (HTTP/2 Bomb)
diff --git a/debian/convert_docs b/debian/convert_docs
index b39a58fa..b8c07370 100755
--- a/debian/convert_docs
+++ b/debian/convert_docs
@@ -49,7 +49,7 @@ foreach my $h (@html) {
                elsif ( -f "$SRC/$h.$l" ) {
                        conv("$SRC/$h.$l", "$tdir$h", $h, $updir);
                }
-               else {
+               elsif ( ! -e "$tdir$h" ) {
                        symlink("$updir/en/$h", "$tdir$h");
                }
                
diff --git a/debian/patches/CVE-2026-49975_1.patch 
b/debian/patches/CVE-2026-49975_1.patch
deleted file mode 100644
index 28ec9897..00000000
--- a/debian/patches/CVE-2026-49975_1.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Stefan Eissing <[email protected]>
-Date: Wed, 27 May 2026 10:50:32 +0200
-Subject: cookie reqest header counting
-
-Account merged cookie headers as an "add" to keep LimitRequestFields effective.
-
-origin: backport, 
https://github.com/icing/mod_h2/commit/cb7cd2eec3b6ef02dea62d77de2a38a108af66ee
-bug: https://github.com/icing/mod_h2/pull/324
-bug-security: https://blog.calif.io/p/codex-discovered-a-hidden-http2-bomb
----
- modules/http2/h2_util.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c
-index b377ff7..b265bc9 100644
---- a/modules/http2/h2_util.c
-+++ b/modules/http2/h2_util.c
-@@ -1719,6 +1719,8 @@ static apr_status_t req_add_header(apr_table_t *headers, 
apr_pool_t *pool,
-             apr_table_setn(headers, "Cookie",
-                            apr_psprintf(pool, "%s; %.*s", existing,
-                                         (int)nv->valuelen, nv->value));
-+            /* Treat the merge as an "add" to not escape LimitRequestFields */
-+            *pwas_added = 1;
-             return APR_SUCCESS;
-         }
-     }
diff --git a/debian/patches/CVE-2026-49975_2.patch 
b/debian/patches/CVE-2026-49975_2.patch
deleted file mode 100644
index 851e5b36..00000000
--- a/debian/patches/CVE-2026-49975_2.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Stefan Eissing <[email protected]>
-Date: Wed, 27 May 2026 11:05:44 +0200
-Subject: ignore duplicate empty cookie headers
-
-origin: backport, 
https://github.com/icing/mod_h2/commit/b5c211e7010d31224ac2621664479177314aec96
-bug: https://github.com/icing/mod_h2/pull/324
-bug-security: https://blog.calif.io/p/codex-discovered-a-hidden-http2-bomb
----
- modules/http2/h2_util.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c
-index b265bc9..b303945 100644
---- a/modules/http2/h2_util.c
-+++ b/modules/http2/h2_util.c
-@@ -1708,6 +1708,8 @@ static apr_status_t req_add_header(apr_table_t *headers, 
apr_pool_t *pool,
-              && !ap_cstr_casecmpn("cookie", (const char *)nv->name, 
nv->namelen)) {
-         existing = apr_table_get(headers, "cookie");
-         if (existing) {
-+            if (!nv->valuelen)
-+                return APR_SUCCESS;
-             /* Cookie header come separately in HTTP/2, but need
-              * to be merged by "; " (instead of default ", ")
-              */
diff --git a/debian/patches/fhs_compliance.patch 
b/debian/patches/fhs_compliance.patch
index ee4715fd..b0c3b185 100644
--- a/debian/patches/fhs_compliance.patch
+++ b/debian/patches/fhs_compliance.patch
@@ -6,7 +6,7 @@ Last-Update: 2026-05-05
 
 --- a/configure
 +++ b/configure
-@@ -42443,16 +42443,17 @@
+@@ -42455,16 +42455,17 @@
  
  cat >>confdefs.h <<_ACEOF
  #define HTTPD_ROOT "${ap_prefix}"
@@ -28,7 +28,7 @@ Last-Update: 2026-05-05
  
 --- a/configure.in
 +++ b/configure.in
-@@ -934,11 +934,11 @@
+@@ -936,11 +936,11 @@
  echo $MODLIST | $AWK -f $srcdir/build/build-modules-c.awk > modules.c
  
  APR_EXPAND_VAR(ap_prefix, $prefix)
diff --git a/debian/patches/series b/debian/patches/series
index 2aabdc69..450653aa 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -5,5 +5,3 @@ customize_apxs.patch
 build_suexec-custom.patch
 reproducible_builds.diff
 fix-macro.patch
-CVE-2026-49975_1.patch
-CVE-2026-49975_2.patch
diff --git a/debian/perl-framework/t/apache/expr.t 
b/debian/perl-framework/t/apache/expr.t
index 7d62bc04..06e031d0 100644
--- a/debian/perl-framework/t/apache/expr.t
+++ b/debian/perl-framework/t/apache/expr.t
@@ -115,7 +115,6 @@ my @test_cases = (
     [ q[toupper(escape('?')) = '%3F' ] => 1 ],
     [ q[tolower(toupper(escape('?'))) = '%3f' ] => 1 ],
     [ q[%{toupper:%{escape:?}} = '%3F' ] => 1 ],
-    [ q[file('] . $file_foo . q[') = 'foo\n' ]  => 1 ],
     # unary operators
     [ q[-n '']  => 0 ],
     [ q[-z '']  => 1 ],
@@ -198,11 +197,13 @@ push @test_cases, @bool_test_cases;
 push @test_cases, map { ["!($_->[0])" => neg($_->[1]) ] } @bool_test_cases;
 
 if (have_min_apache_version("2.3.13")) {
+    my $restrict2_result = have_min_apache_version('2.4.68') ? undef : 1;
     push(@test_cases, (
         # functions
-        [ q[filesize('] . $file_foo      . q[') = 4 ]  => 1 ],
-        [ q[filesize('] . $file_notexist . q[') = 0 ]  => 1 ],
-        [ q[filesize('] . $file_zero     . q[') = 0 ]  => 1 ],
+        [ q[filesize('] . $file_foo      . q[') = 4 ]  => $restrict2_result ],
+        [ q[filesize('] . $file_notexist . q[') = 0 ]  => $restrict2_result ],
+        [ q[filesize('] . $file_zero     . q[') = 0 ]  => $restrict2_result ],
+        [ q[file('] . $file_foo . q[') = 'foo\n' ]  => $restrict2_result ],
         # unary operators
         [ qq[-d '$file_foo' ] => 0 ],
         [ qq[-e '$file_foo' ] => 1 ],
diff --git a/debian/perl-framework/t/apache/pr64339.t 
b/debian/perl-framework/t/apache/pr64339.t
index 00097e66..4915418c 100644
--- a/debian/perl-framework/t/apache/pr64339.t
+++ b/debian/perl-framework/t/apache/pr64339.t
@@ -18,7 +18,7 @@ my @testcases = (
     ['/doc.notxml', "application/notreallyxml", "f\xf3\xf3\n" ],
 
     # Sent with charset=ISO-8859-1 - should be transformed to utf-8
-    ['/doc.isohtml', "text/html;charset=utf-8", 
"<html><body><p>fóó\n</p></body></html>" ],
+    ['/doc.isohtml', "text/html;charset=utf-8", 
"<html><body>.*fóó\n.*</body></html>" ],
 );
 
 # mod_xml2enc on trunk behaves quite differently to the 2.4.x version
@@ -42,5 +42,5 @@ foreach my $t (@testcases) {
     
     ok t_cmp($r->code, 200, "fetching ".$t->[0]);
     ok t_cmp($r->header('Content-Type'), $t->[1], "content-type header test 
for ".$t->[0]);
-    ok t_cmp($r->content, $t->[2], "content test for ".$t->[0]);
+    ok t_cmp($r->content, qr/$t->[2]/, "content test for ".$t->[0]);
 }
diff --git 
a/debian/perl-framework/t/htdocs/modules/include/apexpr/restrict_func.shtml 
b/debian/perl-framework/t/htdocs/modules/include/apexpr/restrict_func.shtml
new file mode 100644
index 00000000..31401606
--- /dev/null
+++ b/debian/perl-framework/t/htdocs/modules/include/apexpr/restrict_func.shtml
@@ -0,0 +1,5 @@
+<!--#if expr="file('%{DOCUMENT_ROOT}/foobar.html') =~ /foobar/" -->
+IF_FUNC_TRUE
+<!--#else -->
+IF_FUNC_FALSE
+<!--#endif -->
diff --git a/debian/perl-framework/t/modules/dav.t 
b/debian/perl-framework/t/modules/dav.t
index a1b6248b..8ff990d8 100644
--- a/debian/perl-framework/t/modules/dav.t
+++ b/debian/perl-framework/t/modules/dav.t
@@ -10,7 +10,7 @@ use HTTP::Date;
 ## mod_dav tests
 ##
 
-plan tests => 21, [qw(dav HTTP::DAV)];
+plan tests => 22, [qw(dav HTTP::DAV)];
 require HTTP::DAV;
 
 my $vars = Apache::Test::vars();
@@ -178,6 +178,15 @@ print "PR 49825: expect 400 bad request got: $actual\n";
 ok $actual == 400;
 $user_agent->default_header('Content-Range' => undef);
 
+## Test PUT to .DAV subdirectory (should be blocked in 2.4.68+) ##
+my $dav_uri = "/$dir/.DAV/test.html";
+my $dav_resource = $dav->new_resource( -uri => "http://$server$dav_uri";);
+my $expected = have_min_apache_version('2.4.68') ? 403 : 201;
+$response = $dav_resource->put($body);
+$actual = $response->code;
+ok t_cmp($actual, $expected);
+
 ## clean up ##
+unlink "$htdocs/$dir/.DAV/test.html";
 rmdir "$htdocs/$dir/.DAV" or print "warning: could not remove .DAV dir: $!";
 rmdir "$htdocs/$dir" or print "warning: could not remove dav dir: $!";
diff --git a/debian/perl-framework/t/modules/headers.t 
b/debian/perl-framework/t/modules/headers.t
index 4892b95c..40bd5c32 100644
--- a/debian/perl-framework/t/modules/headers.t
+++ b/debian/perl-framework/t/modules/headers.t
@@ -115,7 +115,27 @@ my @testcases = (
        [  ],
        [ 'Test-Header' => 'foo' ],
     ],
+    # 500 error test - invalid regex pattern
+    [
+       "Header edit Test-Header (unclosed bar",                      # 
malformed regex (unmatched parenthesis)
+       [  ],
+       [  ],
+       500,
+    ],
 );
+if (have_min_apache_version('2.4.68')) {
+    push(@testcases,
+        (
+            # edit*
+        [
+           "Header set Test-Header \"expr=%{base64:%{file:$htaccess}}\"", # no 
file() in htaccess
+           [  ],
+           [  ],
+           500,
+        ],
+    )
+  );
+}
 if (have_min_apache_version('2.5.1')) {
     push(@testcases,
         (
@@ -297,6 +317,9 @@ sub test_header2 {
     my @test = @_;
     my $h = HTTP::Headers->new;
     
+    # Extract expected status code (default to 200 if not specified)
+    my $expected_status = $test[0][3] // 200;
+    
     print "\n\n\n";
     for (my $i = 0; $i < scalar @{$test[0][1]}; $i += 2) {
         print "Header sent n°" . $i/2 . ":\n";
@@ -312,22 +335,30 @@ sub test_header2 {
     ## 
     my $r = HTTP::Request->new('GET', 
"http://$hostport/modules/headers/htaccess/";, $h);
     my $res = $ua->request($r);
-    ok t_cmp($res->code, 200, "Checking return code is '200'");
+    ok t_cmp($res->code, $expected_status, "Checking return code is 
'$expected_status'");
     
-    my $isok = 1;
-    for (my $i = 0; $i < scalar @{$test[0][2]}; $i += 2) {
-        print "\n";
-        print "Header received n°" . $i/2 . ":\n";
-        print "  header:   " . $test[0][2][$i] . "\n";
-        print "  expected: " . $test[0][2][$i+1] . "\n";
-        if ($res->header($test[0][2][$i])) {
-            print "  received: " . $res->header($test[0][2][$i]) . "\n";
-        } else {
-            print "  received: <undefined>\n";
+    # Only validate headers if we expect a successful response
+    if ($expected_status == 200) {
+        my $isok = 1;
+        for (my $i = 0; $i < scalar @{$test[0][2]}; $i += 2) {
+            print "\n";
+            print "Header received n°" . $i/2 . ":\n";
+            print "  header:   " . $test[0][2][$i] . "\n";
+            print "  expected: " . $test[0][2][$i+1] . "\n";
+            if ($res->header($test[0][2][$i])) {
+                print "  received: " . $res->header($test[0][2][$i]) . "\n";
+            } else {
+                print "  received: <undefined>\n";
+            }
+            $isok = $isok && $res->header($test[0][2][$i]) && 
$test[0][2][$i+1] eq $res->header($test[0][2][$i]);
         }
-        $isok = $isok && $res->header($test[0][2][$i]) && $test[0][2][$i+1] eq 
$res->header($test[0][2][$i]);
-    }
-    print "\nResponse received is:\n" . $res->as_string;
+        print "\nResponse received is:\n" . $res->as_string;
 
-    ok $isok;
+        ok $isok;
+    } else {
+        # For error responses, skip header validation
+        print "\nExpected error response received (status $expected_status)\n";
+        print "Response received is:\n" . $res->as_string;
+        ok 1;
+    }
 }
diff --git a/debian/perl-framework/t/modules/include.t 
b/debian/perl-framework/t/modules/include.t
index 99644971..a4b1e80b 100644
--- a/debian/perl-framework/t/modules/include.t
+++ b/debian/perl-framework/t/modules/include.t
@@ -85,7 +85,7 @@ my %test = (
 "echo3.shtml"           =>    ['<!--#echo var="DOCUMENT_NAME" -->', 
"retagged1"], 
 "notreal.shtml"         =>    "pass <!--",
 "malformed.shtml"       =>    "[an error occurred while processing this ".
-                              "directive] malformed.shtml",
+                              "directive]",
 "exec/off/cmd.shtml"    =>    "[an error occurred while processing this ".
                               "directive]",
 "exec/on/cmd.shtml"     =>    "pass",
@@ -107,9 +107,11 @@ my %test = (
 my %ap_expr_test = (
 "apexpr/if1.shtml"      =>    "pass",
 "apexpr/err.shtml"      =>    "[an error occurred while processing this ".
-                              "directive] err.shtml",
+                              "directive]",
 "apexpr/restrict.shtml" =>    "[an error occurred while processing this ".
-                              "directive] restrict.shtml",
+                              "directive]",
+"apexpr/restrict_func.shtml" => "[an error occurred while processing this ".
+                              "directive]",
 "apexpr/var.shtml"      =>    "pass   pass   pass",
 "apexpr/lazyvar.shtml"  =>    "pass",
 );
@@ -303,6 +305,12 @@ foreach $doc (sort keys %tests) {
             skip "Skipping 'exec cgi' test; no cgi module.", 2;
         }
     }
+    elsif ($doc =~ m/malformed|apexpr/) {
+        ok t_cmp(super_chomp(GET_BODY "$dir$doc"),
+                 qr/\Q$tests{$doc}\E/,
+                 "GET $dir$doc"
+                );
+    }
     else {
         ok t_cmp(super_chomp(GET_BODY "$dir$doc"),
                  $tests{$doc},
diff --git a/debian/perl-framework/t/modules/proxy_fcgi.t 
b/debian/perl-framework/t/modules/proxy_fcgi.t
index dce4a804..6da6253f 100644
--- a/debian/perl-framework/t/modules/proxy_fcgi.t
+++ b/debian/perl-framework/t/modules/proxy_fcgi.t
@@ -154,7 +154,7 @@ sub run_fcgi_envvar_request
     }
 
     if(defined($fcgi_port)) {
-        if ($r->code ge '500') {
+        if ($r->code ge '400') {
             # Unknown failure, probably the request didn't hit the FCGI child
             # process, so it will hang waiting for our request
             kill 'TERM', $child;
@@ -328,6 +328,11 @@ foreach my $url (@udstests) {
 }
 
 for my $t (@balancertests) {
+    if (!have_module("proxy_balancer")) {
+        skip "no proxy_balancer";
+        skip "no proxy_balancer";
+        next;
+    }
     my $url = $t->{"url"};
     my $pathinfo = $t->{"pathinfo"};
     $envs = run_fcgi_envvar_request($fcgi_port, $url);
diff --git a/debian/perl-framework/t/modules/setenvif.t 
b/debian/perl-framework/t/modules/setenvif.t
index cb561c28..0b13fb81 100644
--- a/debian/perl-framework/t/modules/setenvif.t
+++ b/debian/perl-framework/t/modules/setenvif.t
@@ -56,7 +56,7 @@ my @var = qw(VAR_ONE VAR_TWO VAR_THREE);
 
 my $htaccess = "$htdocs/modules/setenvif/htaccess/.htaccess";
 
-plan tests => @var * 10 + (keys %var_att) * 6 * @var + 4,
+plan tests => @var * 10 + (keys %var_att) * 6 * @var + 5,
     have_module qw(setenvif include);
 
 sub write_htaccess {
@@ -178,6 +178,16 @@ else {
     skip "skipping inverted match test with version <2.4.38"
 }
 
+if (need_min_apache_version("2.4.67")) {
+    # file() access should be disallowed in htaccess context
+    write_htaccess("SetEnvIfExpr \"file('$htdocs/foobar.html') =~ /(.+)/\" 
VAR_ONE=\$0");
+    $body = GET_BODY $page;
+    ok ! t_cmp($body, qr/^1:foobar/);
+}
+else {
+    skip "skipping test for CVE-2026-24072 in version <2.4.67";
+}
+
 ## i think this should work, but it doesnt.
 ## leaving it commented now pending investigation.
 ## seems you cant override variables that have been previously set.

Reply via email to