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 %00 in query string leads to out of bound reads when printing the param key #266

Closed Fusl closed 6 months ago

Fusl commented 7 months ago

This is very similar to https://github.com/curl/trurl/issues/265 but unsure if it's the same root cause so I'm opening a separate issue. Please close this one if they appear to be the same root cause.

trurl incorrectly decodes a %00 found in the query string part of a URL which causes an out of bound reads when trying to print the result with --json.

Example (note the random data in the key of the param):

$ trurl --json 0?0%000000000000000000000000000000000
[
  {
    "url": "http://0.0.0.0/?0%000000000000000000000000000000000",
    "parts": {
      "scheme": "http",
      "host": "0.0.0.0",
      "path": "/"
    },
    "params": [
      {
        "key": "0\u0000t%H\u0000\u0000Lt%H\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
                       ^^^            ^^^^
        "value": ""
      }
    ]
  }
]

With ASan enabled:

$ trurl --json 0?0%000000000000000000000000000000000
[
  {
    "url": "http://0.0.0.0/?0%000000000000000000000000000000000",
    "parts": {
      "scheme": "http",
      "host": "0.0.0.0",
      "path": "/"
    },
    "params": [
      {
=================================================================
==2774789==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6030000209a0 at pc 0x557b8594fa81 bp 0x7ffc2d3fa3b0 sp 0x7ffc2d3fa3a8
READ of size 1 at 0x6030000209a0 thread T0
    #0 0x557b8594fa80 in jsonString /src/trurl/trurl.c:884:12
    #1 0x557b8594bc32 in json /src/trurl/trurl.c:965:7
    #2 0x557b8594bc32 in singleurl /src/trurl/trurl.c:1424:7
    #3 0x557b859458b8 in main /src/trurl/trurl.c:1544:9
    #4 0x7fdc6c9011c9  (/lib/x86_64-linux-gnu/libc.so.6+0x271c9) (BuildId: 51657f818beb1ae70372216a99b7412b8a100a20)
    #5 0x7fdc6c901284 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x27284) (BuildId: 51657f818beb1ae70372216a99b7412b8a100a20)
    #6 0x557b8586f200 in _start (/trurl/trurl+0x59200) (BuildId: 44a807945411d9d4)

0x6030000209a0 is located 0 bytes after 32-byte region [0x603000020980,0x6030000209a0)

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

jacobmealey commented 7 months ago

hmm digging into this more, it seems like something seriously breaks when its decoding a query greater that 32 with a null in the string. very strange. it breaks in a similar way if you do ./trurl "0?f=0%000000000000000000000000000000" --json it works fine (here the entire query string is exactly 32 characters. if you add a single 0 to the send it totally breaks down as well. though I should note this happens at appqpair and not in JsonString, where your example is breaking.

jacobmealey commented 7 months ago

I also wouldn't be surprised if it has a similar root cause https://github.com/curl/trurl/issues/262