These are pretty beautiful attacks, which build off what I think are two basic issues Apache deals with that other webservers don't:
* A maybe ill-advised architecture where lots of independently-developed modules cooperate to handle a request, all working on an over-complicated under-specified request "object".
* The requirement to honor `httpd.conf` file structures dating back to the 1990s, which has led to legacy support code paths that do surprising things.
The core of this article is a two-step attack that exploits (1) the fact that modules alternately interpret `request->filename` as a filename and as a URL, which allows attackers to truncate URLs at path separator characters, which by itself can slip you past some basic ACLs, and (2) the fact that Apache will try to serve request both with and without the `DocumentRoot` applied, which, combined with the first attack pattern, means that config directives that have attacker-controlled targets give attackers full filesystem access. Hilarity ensues.
There's a really slick attack here that takes you from CRLF-injection to SSRF and RCE, which is neat, because CRLF-injection ("header splitting") would ordinarily not be that interesting of an attack.
This is great stuff that just makes me wish more people ran Apache in 2024.
A similar but different class of issues common to web stacks is when you have proxies and multiple layers of HTTP “things”, especially when they parse data differently (eg: nginx fronting Apache)
The lesson I've learned from this: Ambiguity may not always resolve. If some technical details in a spec seem confusing or ambiguous between two contradictory options, then half of the implementations will probably do option #1, the other will half will do option #2 and some may do both at the same time.
Some attacks did not rely on mod_rewrite. For instance, the splitting of response headers.
The Apache vulnerabilities list provides a short summary of each: https://httpd.apache.org/security/vulnerabilities_24.html
The fixes are in versions 2.4.59 and 2.4.60. Then a fix of the fix of CVE-2024-39884 in 2.4.61. Then a better fix of CVE-2024-39884 in 2.4.62.
> The entire development process must be carefully built upon a pile of legacy code and technical debt. So, if any Apache HTTP Server developers are reading this: Thank you for your hard work and contributions!
Quite the tone shift, a bit amusing, but definitely an attention catching choice and immensely cool that people are doing research like this.
I'm fairly sure that most large systems have a bunch of potential vulnerabilities, for example you can most likely do more with Apache than you can with Nginx due to its dynamic nature and module system, but at the same time that comes with dangers like this.
> you can most likely do more with Apache than you can with Nginx
Apache having more features than Nginx is debatable. Apache has probably more unofficial modules, but that's irrelevant to the core developpers. With the official modules, I suppose Apache and Nginx more or less on par, but it's hard to compare. Apache has many useless modules in its distribution, e.g. "cern_meta" or "dialup" (for 56K modems!). And some modern features are lacking in Apache: e.g. HTTP3 was an experimental feature of Nginx 4 years ago, it's stable for more than one year, and AFAIK it's not even planned in Apache.
> due to its dynamic nature and module system,
Nginx has a module system, like Apache. E.g. "ngx_echo" is an unofficial module.
> but at the same time that comes with dangers like this.
As you noted, the post explains that the problem was not the features surface, it was the legacy code and the technical debt. Nginx is better on these aspects, and Caddy probably even more so.
> Apache has probably more unofficial modules, but that's irrelevant to the core developpers.
In a way it's irrelevant, but in a way not. The myth was that they called it Apache because it's "A patchy" web server.[1] IOW it was designed to use modules to do most of its work.
That's relevant to me! If I want Apache to act as an OpenID connect relying party, for example, I can just use mod_auth_openidc https://github.com/OpenIDC/mod_auth_openidc installing which is pretty much trivial and requires little work on my part:
17 comments
[ 2.7 ms ] story [ 43.1 ms ] thread* A maybe ill-advised architecture where lots of independently-developed modules cooperate to handle a request, all working on an over-complicated under-specified request "object".
* The requirement to honor `httpd.conf` file structures dating back to the 1990s, which has led to legacy support code paths that do surprising things.
The core of this article is a two-step attack that exploits (1) the fact that modules alternately interpret `request->filename` as a filename and as a URL, which allows attackers to truncate URLs at path separator characters, which by itself can slip you past some basic ACLs, and (2) the fact that Apache will try to serve request both with and without the `DocumentRoot` applied, which, combined with the first attack pattern, means that config directives that have attacker-controlled targets give attackers full filesystem access. Hilarity ensues.
There's a really slick attack here that takes you from CRLF-injection to SSRF and RCE, which is neat, because CRLF-injection ("header splitting") would ordinarily not be that interesting of an attack.
This is great stuff that just makes me wish more people ran Apache in 2024.
A similar but different class of issues common to web stacks is when you have proxies and multiple layers of HTTP “things”, especially when they parse data differently (eg: nginx fronting Apache)
Really impressive to find that many exploitable issues without once relying on a buffer overflow.
The Apache vulnerabilities list provides a short summary of each: https://httpd.apache.org/security/vulnerabilities_24.html The fixes are in versions 2.4.59 and 2.4.60. Then a fix of the fix of CVE-2024-39884 in 2.4.61. Then a better fix of CVE-2024-39884 in 2.4.62.
> Why Apache HTTP Server Smells Bad?
In the end:
> The entire development process must be carefully built upon a pile of legacy code and technical debt. So, if any Apache HTTP Server developers are reading this: Thank you for your hard work and contributions!
Quite the tone shift, a bit amusing, but definitely an attention catching choice and immensely cool that people are doing research like this.
I'm fairly sure that most large systems have a bunch of potential vulnerabilities, for example you can most likely do more with Apache than you can with Nginx due to its dynamic nature and module system, but at the same time that comes with dangers like this.
Apache having more features than Nginx is debatable. Apache has probably more unofficial modules, but that's irrelevant to the core developpers. With the official modules, I suppose Apache and Nginx more or less on par, but it's hard to compare. Apache has many useless modules in its distribution, e.g. "cern_meta" or "dialup" (for 56K modems!). And some modern features are lacking in Apache: e.g. HTTP3 was an experimental feature of Nginx 4 years ago, it's stable for more than one year, and AFAIK it's not even planned in Apache.
> due to its dynamic nature and module system,
Nginx has a module system, like Apache. E.g. "ngx_echo" is an unofficial module.
> but at the same time that comes with dangers like this.
As you noted, the post explains that the problem was not the features surface, it was the legacy code and the technical debt. Nginx is better on these aspects, and Caddy probably even more so.
In a way it's irrelevant, but in a way not. The myth was that they called it Apache because it's "A patchy" web server.[1] IOW it was designed to use modules to do most of its work.
[1] https://dan.hersam.com/2004/07/29/a-patchy-web-server/
That's relevant to me! If I want Apache to act as an OpenID connect relying party, for example, I can just use mod_auth_openidc https://github.com/OpenIDC/mod_auth_openidc installing which is pretty much trivial and requires little work on my part:
If I want something similar for Nginx, I can take a look here https://openid.net/developers/certified-openid-connect-imple... and realize that I'll need to use OpenResty with LuaRocks, which does add a bit more complexity: https://github.com/zmartzone/lua-resty-openidc If I want a basic WAF with something that runs ModSecurity rules, on Apache I can just do: and can use the OWASP CRS with no issues: https://owasp.org/www-project-modsecurity-core-rule-set/With Nginx that is no longer properly supported and needed their Plus version anyways: https://docs.nginx.com/nginx-waf/admin-guide/nginx-plus-mods...
If I want to do that myself with the regular Nginx, I suddenly have to compile a bunch of stuff myself, which becomes far less pleasant and a bit more long winded: https://www.linode.com/docs/guides/securing-nginx-with-modse... (old versions in the example, but same principle)At that point I might as well look in the direction of OWASP Coraza: https://coraza.io/
When it comes to ACME and Let's Encrypt, I can use mod_md out of the box with Apache: https://httpd.apache.org/docs/2.4/mod/mod_md.html
It's experimental but works nicely in my experience, whereas with Nginx, I have to go with Certbot separately: https:/...