curl / trurl

trurl is a command line tool for URL parsing and manipulation.
https://curl.se/trurl/
Other
3.1k stars 99 forks source link

incorrect decode of %3d as = character in query string leads to out of bound reads #265

Closed Fusl closed 6 months ago

Fusl commented 7 months ago

trurl incorrectly decodes a %3d found in the URL as = which causes an out of bound reads when trying to print the result with --json.

Example:

$ trurl --json "http://host/?key%3dvalue"
[
  {
    "url": "http://host/?key%3dvalue",
    "parts": {
      "scheme": "http",
      "host": "host",
      "path": "/",
      "query": "key=value"  <----- decoded as "="
    },
    "params": [
      {
        "key": "key",
        "value": "value\u0000"  <----- null-terminator at end of string included in params
      }
    ]
  }
]

The out of bounds read can be triggered with a specially crafted URL like this one:

$ trurl --json "0?0000000000000000%3d"
[
  {
    "url": "http://0.0.0.0/?0000000000000000%3d",
    "parts": {
      "scheme": "http",
      "host": "0.0.0.0",
      "path": "/",
      "query": "0000000000000000="
    },
    "params": [
      {
        "key": "0000000000000000",
=================================================================
==1392071==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000020a60 at pc 0x55f9312dca81 bp 0x7ffc0725dcd0 sp 0x7ffc0725dcc8
READ of size 1 at 0x603000020a60 thread T0
    #0 0x55f9312dca80 in jsonString /src/trurl/trurl.c:884:12
    #1 0x55f9312d8d01 in json /src/trurl/trurl.c:970:7
    #2 0x55f9312d8d01 in singleurl /src/trurl/trurl.c:1424:7
    #3 0x55f9312d28b8 in main /src/trurl/trurl.c:1544:9
    #4 0x7fd330dda1c9  (/lib/x86_64-linux-gnu/libc.so.6+0x271c9) (BuildId: 51657f818beb1ae70372216a99b7412b8a100a20)
    #5 0x7fd330dda284 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x27284) (BuildId: 51657f818beb1ae70372216a99b7412b8a100a20)
    #6 0x55f9311fc200 in _start (/trurl/trurl+0x59200) (BuildId: 44a807945411d9d4)

0x603000020a60 is located 0 bytes after 32-byte region [0x603000020a40,0x603000020a60)

With ASan disabled, the out of bounds read produces this output:

$ trurl --json "0?0000000000000000%3d"
[
  {
    "url": "http://0.0.0.0/?0000000000000000%3d",
    "parts": {
      "scheme": "http",
      "host": "0.0.0.0",
      "path": "/",
      "query": "0000000000000000="
    },
    "params": [
      {
        "key": "0000000000000000",
        "value": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
      }
    ]
  }
]

This bug was discovered with the help of AFL++ in combination with ASan.