Item14381: mod_perl unexpectedly decodes the URI, and X-FoswikiURI header should be debug only.
Priority: Security
Current State: Closed
Released In: 2.1.4
Target Release: patch
The second security issue has been recreated.
The X-FoswikiURI header is not encoded, but only when mod_perl is used. CGI and
FastCGI appear to return the encoded string from calls to
->uri()
function.
The result is that an encoded URI containing %0D%0A introduces a break in the page headers and can inject additional headers and/or content.
My proposed fix is:
- Make the X-FoswikiAction and x=FoswikiURI headers optional - only include them when DEBUG is enabled. I cannot find any use of those headers in core or a few dozen extensions that I've checked. Foswiki seems to work just fine without them.
- Change Foswiki::Engine::Apache to encode the URI so that it is equivalent to CGI & FastCGI.
Note that the
FoswikiURI string includes the full query string of the request. As it is generated early in the request, it's possible that normally redacted query parameters like password might end up in the headers of the page. I have not tested this yet, but making the header optional is probably the safest action.
--
GeorgeClark - 19 Apr 2017
Patch:
diff --git a/ModPerlEngineContrib/lib/Foswiki/Engine/Apache.pm b/ModPerlEngineContrib/lib/Foswiki/Engine/Apache.pm
index 13b37c8..2d6681b 100644
--- a/ModPerlEngineContrib/lib/Foswiki/Engine/Apache.pm
+++ b/ModPerlEngineContrib/lib/Foswiki/Engine/Apache.pm
@@ -151,7 +151,9 @@ sub preparePath {
$pathInfo = '/' . $action . $pathInfo;
}
$req->pathInfo($pathInfo);
- my $uri = $this->{r}->uri;
+
+ #SMELL: CGI and FastCGI leave the URI encoded, mod_perl decodes it.
+ my $uri = Foswiki::urlEncode( $this->{r}->uri );
my $qs = $this->{r}->args;
$uri .= '?' . $qs if $qs;
$req->uri($uri);
diff --git a/core/lib/Foswiki.pm b/core/lib/Foswiki.pm
index 90e23da..d5168d1 100644
--- a/core/lib/Foswiki.pm
+++ b/core/lib/Foswiki.pm
@@ -1105,8 +1105,9 @@ sub generateHTTPHeaders {
# use our version of the content type
$hopts->{'Content-Type'} = $contentType;
- $hopts->{'X-FoswikiAction'} = $this->{request}->action;
- $hopts->{'X-FoswikiURI'} = $this->{request}->uri;
+ # These headers don't appear to be used, and can leak stuff.
+ $hopts->{'X-FoswikiAction'} = $this->{request}->action if DEBUG;
+ $hopts->{'X-FoswikiURI'} = $this->{request}->uri if DEBUG;
# Turn off XSS protection in DEBUG so it doesn't mask problems
$hopts->{'X-XSS-Protection'} = 0 if DEBUG;
--
GeorgeClark - 19 Apr 2017
Based on the
SecurityAlertProcess, I don't see that this rises above the Severity 3 criteria:
- Foswiki content or browser is compromised
If you agree, we can fix this one on a task and avoid the formal CVE. We can release
ModPerlEngineContrib immediately, which will mitigate the issue.
--
GeorgeClark - 19 Apr 2017
There is a bit more too this. It appears that the latest version of mod_perl also fixes this issue by aborting if a header contains invalid characters:
[Sat Apr 22 11:37:13.696507 2017] [http:error] [pid 2037:tid 2932714304] [client 192.168.122.1:51378] AH02430: Response header 'X-Foswikiuri' value of '/wiki/test\r\n\r\n<script>alert(1)</script>' contains invalid characters, aborting request
[Sat Apr 22 11:45:38.808648 2017] [http:error] [pid 2036:tid 3041909568] [client 192.168.122.1:51386] AH02430: Response header 'X-Foswikiuri' value of '/wiki/Main/\r' contains invalid characters, aborting request
So there are 3 aspects to this issue:
- The CGI-equivalent functions provided by
mod_perl
return the URI / URL in decoded form. CGI and FastCGI provide a urlEncoded string.
- The X-Foswikiuri header doesn't appear to be used by Foswiki and could probably be eliminated, or only enabled when DEBUG is active.
- The latest security updates of Apache block presence of a line-break in generated headers, also resolving the issue.
--
GeorgeClark - 22 Apr 2017
It's a CVE against Apache:
apache2 (2.4.10-10+deb8u8) jessie-security; urgency=medium
* CVE-2016-8743: Enforce more HTTP conformance for request lines and
request headers, to prevent response splitting and cache pollution
by malicious clients or downstream proxies.
--
GeorgeClark - 22 Apr 2017
And a bit more to the analysis: Engine::CGI gets the sets the URI using:
$req->uri( $ENV{REQUEST_URI}
|| $req->url( -absolute => 1, -path => 1, -query => 1 ) );
It's the
ENV{REQUEST_URI}
that contains the encoded URI, eg the
Main/WebHome%0D%0A
. The data returned by
$req->url
function has the encoded data stripped, and returns only
Main/WebHome
.
--
GeorgeClark - 22 Apr 2017
Fixed in
ModPerlEngineContrib 1.05 - 30 Apr 2017.
--
GeorgeClark - 01 May 2017