Bug #2945


Security - SIGABRT during GET request handling with url-path-2f-decode enabled

Added by stze about 5 years ago. Updated about 5 years ago.

Target version:


Dear lighttpd team —

I have detected a SIGABRT during handling a malicious GET request with option url-path-2f-decode from server.http-parseopts enabled.

Version: lighttpd-1.4.53

How to reproduce:

$ ./configure --prefix=/tmp/lighttpd
$ mkdir -p /tmp/lighttpd/lib/
$ make
$ cp src/.libs/* /tmp/lighttpd/lib/
$ ./src/lighttpd -f <attached lighttpd.conf> -D

The server is started on localhost:8090

$ nc 8090 < crash.light

Aborted (core dumped)


 <0x00007ffff7baf895> [[UNKNOWN]():0 at /usr/lib64/]
 <0x0000000000567f32> [log_failed_assert():1027 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000568957> [buffer_realloc():83 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000056856b> [buffer_string_prepare_copy():102 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000568daf> [buffer_copy_string_len():166 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000056f3f8> [burl_normalize_path():300 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000056dd5a> [burl_normalize():349 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000053e1b4> [http_response_prepare():342 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000544bb2> [connection_state_machine():1157 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000054e550> [network_server_handle_fdevent():64 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x00000000005370d5> [server_main():2031 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000530c63> [HonggfuzzNetDriver_main():2102 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x00000000005d4407> [netDriver_mainProgram():0 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x00007ffff7f0c58e> [[UNKNOWN]():0 at /usr/lib64/]
 <0x00007ffff7c8a683> [[UNKNOWN]():0 at /usr/lib64/]


(gdb) bt
#0  0x00007f0f2220e57f in raise () from /lib64/
#1  0x00007f0f221f8895 in abort () from /lib64/
#2  0x0000000000416d81 in log_failed_assert (filename=<optimized out>, line=<optimized out>, msg=<optimized out>) at buffer.c:1027
#3  0x00000000004171e5 in buffer_realloc (b=<optimized out>, len=0) at buffer.c:81
#4  0x0000000000417346 in buffer_string_prepare_copy (b=<optimized out>, size=<optimized out>) at buffer.c:102
#5  buffer_copy_string_len (b=0x1deb920, s=0x1e2c701 "601", s_len=18446744073709551613) at buffer.c:164
#6  0x000000000040cbaf in http_response_prepare (srv=0x1dd9260, con=0x1deb4e0) at response.c:387
#7  0x000000000040e541 in connection_state_machine (srv=0x1dd9260, con=0x1deb4e0) at connections.c:1157
#8  0x000000000040b905 in server_main (srv=0x1dd9260, argc=<optimized out>, argv=<optimized out>) at server.c:2044
#9  0x0000000000408ed9 in main (argc=4, argv=0x7fffa2c75b38) at server.c:2102

Please let me know what additional information I can provide to successfully reproduce the issue.


-Stephan Zeisberg


lighttpd.conf (2.02 KB) lighttpd.conf stze, 2019-04-09 14:01
crash.light (250 Bytes) crash.light stze, 2019-04-09 14:01
fix-2f-to-slash-crash.patch (471 Bytes) fix-2f-to-slash-crash.patch stbuehler, 2019-04-09 18:49
Actions #1

Updated by stze about 5 years ago

One more information. The issue looks like it's an int overflow in buffer_copy_string_len:

buffer_copy_string_len(con->uri.query, qstr + 1, rlen - plen - 1); <-- overflow

in the provided crash example rlen = 206 and plen = 208. The subtraction of both values results in an overflow.

Actions #2

Updated by stbuehler about 5 years ago

Nice catch. Simple reproducer:

Actions #3

Updated by gstrauss about 5 years ago

  • Category set to core
  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.54

Thanks for the analysis. We've reproduced the issue and I hope to push the tested patch this coming weekend, along with some additional test cases.

Actions #4

Updated by gstrauss about 5 years ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100
Actions #5

Updated by stze about 5 years ago

tracked as CVE-2019-11072

Actions #6

Updated by gstrauss about 5 years ago

Please note that url-path-2f-decode => "enable" is not yet default behavior in lighttpd

Actions #7

Updated by gstrauss about 5 years ago

@stze: please correct the CVE. "Base Score: 9.8 CRITICAL" is entirely inappropriate for a feature that is both optional and must be explicitly enabled -- it is not enabled by default.

Actions #8

Updated by stze about 5 years ago

@gstrauss. The score is set by Mitre, not by me. I just issued the cve request and also mentioned that it is only exploitable with url-path-2f-decode enabled.

Actions #9

Updated by gstrauss about 5 years ago

The feature which can be abused to cause the crash is a new feature in lighttpd 1.4.50, and is not enabled by default. It must be explicitly configured in the config file (e.g. lighttpd.conf) with:
server.http-parseopts = ( "url-path-2f-decode" => "enable" )
and can be disabled in the config file (or commented out) with:
server.http-parseopts = ( "url-path-2f-decode" => "disable" )
losing only the functionality of that feature.

Certain input will trigger an abort() in lighttpd when that feature is enabled. However, unlike the original text in the CVE, there is no unspecified impact. The impact is fully specified.

lighttpd detects the underflow or realloc() will fail (in both 32-bit and 64-bit executables), also detected in lighttpd. Either triggers an explicit abort() by lighttpd. This is not exploitable beyond triggering the explicit abort() with subsequent application exit.


Also available in: Atom