Caddy: [FUZZIT] Crash at fuzzing target parse-caddyfile

Created on 20 Apr 2020  路  13Comments  路  Source: caddyserver/caddy

A new crash was discovered for fuzzing target parse-caddyfile.
Here is a snippet of the log:

1 workers: 1, corpus: 367 (31m58s ago), crashers: 1, restarts: 1/9756, execs: 614674 (69/sec), cover: 1310, uptime: 2h27m
FUZZER: 2020/04/16 00:08:24 workers: 1, corpus: 367 (32m1s ago), crashers: 1, restarts: 1/9759, execs: 614826 (69/sec), cover: 1310, uptime: 2h27m
FUZZER: 2020/04/16 00:08:27 workers: 1, corpus: 367 (32m4s ago), crashers: 1, restarts: 1/9759, execs: 614826 (69/sec), cover: 1310, uptime: 2h27m
FUZZER: 2020/04/16 00:08:30 workers: 1, corpus: 367 (32m7s ago), crashers: 1, restarts: 1/9759, execs: 614826 (69/sec), cover: 1310, uptime: 2h27m
FUZZER: 2020/04/16 00:08:33 workers: 1, corpus: 367 (32m10s ago), crashers: 1, restarts: 1/9760, execs: 614918 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:36 workers: 1, corpus: 367 (32m13s ago), crashers: 1, restarts: 1/9762, execs: 615021 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:39 workers: 1, corpus: 367 (32m16s ago), crashers: 1, restarts: 1/9764, execs: 615151 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:42 workers: 1, corpus: 367 (32m19s ago), crashers: 1, restarts: 1/9765, execs: 615245 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:45 workers: 1, corpus: 367 (32m22s ago), crashers: 1, restarts: 1/9767, execs: 615374 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:48 workers: 1, corpus: 367 (32m25s ago), crashers: 1, restarts: 1/9769, execs: 615469 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:51 workers: 1, corpus: 367 (32m28s ago), crashers: 1, restarts: 1/9770, execs: 615564 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:54 workers: 1, corpus: 367 (32m31s ago), crashers: 1, restarts: 1/9772, execs: 615660 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:08:57 workers: 1, corpus: 367 (32m34s ago), crashers: 1, restarts: 1/9773, execs: 615753 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:00 workers: 1, corpus: 367 (32m37s ago), crashers: 1, restarts: 1/9775, execs: 615849 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:03 workers: 1, corpus: 367 (32m40s ago), crashers: 1, restarts: 1/9776, execs: 615941 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:06 workers: 1, corpus: 367 (32m43s ago), crashers: 1, restarts: 1/9778, execs: 616057 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:09 workers: 1, corpus: 367 (32m46s ago), crashers: 1, restarts: 1/9781, execs: 616242 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:12 workers: 1, corpus: 367 (32m49s ago), crashers: 1, restarts: 1/9783, execs: 616365 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:15 workers: 1, corpus: 367 (32m52s ago), crashers: 1, restarts: 1/9785, execs: 616460 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:18 workers: 1, corpus: 367 (32m55s ago), crashers: 1, restarts: 1/9786, execs: 616555 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:21 workers: 1, corpus: 367 (32m58s ago), crashers: 1, restarts: 1/9788, execs: 616663 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:24 workers: 1, corpus: 367 (33m1s ago), crashers: 1, restarts: 1/9789, execs: 616758 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:27 workers: 1, corpus: 367 (33m4s ago), crashers: 1, restarts: 1/9791, execs: 616855 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:30 workers: 1, corpus: 367 (33m7s ago), crashers: 1, restarts: 1/9792, execs: 616946 (69/sec), cover: 1310, uptime: 2h28m
FUZZER: 2020/04/16 00:09:33 workers: 1, corpus: 367 (33m10s ago), crashers: 1, restarts: 1/9794, execs: 617050 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:36 workers: 1, corpus: 367 (33m13s ago), crashers: 1, restarts: 1/9796, execs: 617191 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:39 workers: 1, corpus: 367 (33m16s ago), crashers: 1, restarts: 1/9798, execs: 617285 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:42 workers: 1, corpus: 367 (33m19s ago), crashers: 1, restarts: 1/9800, execs: 617406 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:45 workers: 1, corpus: 367 (33m22s ago), crashers: 1, restarts: 1/9801, execs: 617517 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:48 workers: 1, corpus: 367 (33m25s ago), crashers: 1, restarts: 1/9803, execs: 617611 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:51 workers: 1, corpus: 367 (33m28s ago), crashers: 1, restarts: 1/9804, execs: 617704 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:54 workers: 1, corpus: 367 (33m31s ago), crashers: 1, restarts: 1/9807, execs: 617869 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:09:57 workers: 1, corpus: 367 (33m34s ago), crashers: 1, restarts: 1/9808, execs: 617964 (69/sec), cover: 1310, uptime: 2h29m
FUZZER: 2020/04/16 00:10:00 workers: 1, corpus: 367 (33m37s ago), crashers: 1, restarts: 1/9810, execs: 618060 (69/sec), cover: 1310, uptime: 2h29m

More details can be found here

Cheers,
Fuzzit Bot

bug

All 13 comments

It's not a crasher in local environment. The parser returns an error locally, but crashes in the fuzzing environment possibly due to presence of many files that match the glob. Anyways -- this is really interesting case. @mholt , the parser receives import as the token with this input:
impor{${}t \f*

Seems like a lexer bug.

@Mohammed90 Interesting -- although I don't think it's a bug in our code. The parser sees {${} as an environment variable placeholder just like {$VAR} is, for example. Since there is no environment variable named { (or ${ if you include the dollar sign), it substitutes {${} with an empty string before parsing, thus resulting in import \f*.

I kind of just want to turn off the fuzz testing on the Caddyfile. Seems broken. All the results in the past 5 weeks have been false positives...

Idea: Could we set some ENV flag that Caddy could use to disable import entirely? Thinking something like CADDY_DISABLE_IMPORT which would make import a no-op (so fuzzit shuts up about it)

The point of tests is to keep our code correct and clean -- I'd rather not clutter it with hacks to accommodate test environments that are not producing any useful results :-/

@francislavoie , we already tried skipping import if it's in the fuzzing input, but this demon managed to circumvent it!

That said, if we _really_ want to keep the Caddyfile fuzzing going, and if it's just a if os.Getenv("CADDY_DISABLE_IMPORT") == "1" { return nil } or something as @francislavoie suggested, we could do that.

But I'd just as much rather fix the fuzzer or turn it off instead. (For the Caddyfile only; leaving the other ones on.)

That change would go in parse.go's doImport() I'd say. Just return return p.Err("Import is disabled")

it substitutes {${} with an empty string before parsing, thus resulting in import \f*

The consequences of this are... going to be weird. So it'll be possible to have this absolutely valid Caddyfile that runs:

example.com

root * /path/to/public_html
tr{$non_existent_var1}y_file{$non_existent_var2}s {path} /in{$non_existent_var3}dex.php?{query}&p={path}
php_fa{$non_existent_var4}stcgi unix//run/ph{$non_existent_var5}p/php-fpm.sock
file_se{$non_existent_var6}rver

Pretty much, yep!

Sigh.

So, what do you think - should we keep fuzzing the Caddyfile and fix the fuzzer, or turn off the Caddyfile fuzzing?

Honestly, the thought in my head is to not do the replacement of env var if the resulting token after replacement is one of the known directives and let the parser later reject it as invalid directive, but I don't see a way to do that. How do you suggest we fix the fuzzer? Skip if it contains an asterisk (which could occur in other places)? I'm not totally opposed to turning of the Caddyfile fuzzing, but I like having it to show its solid implementation.

I don't know how to fix the fuzzer, which is why I suggest just disabling it for now. I also like having it on to prove its robustness (it gives me the "warm fuzzies" 馃槣 ), but only if the fuzzer can be fixed.

Okay, let's disable the fuzzer until we figure out how to fix either. The env var can get us into Hyrum's Law territory (and this xkcd, of course), so disabling the fuzzer is the safer option.

Sounds good to me. I do know there are users who use env variables to configure directives.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

muhammadmuzzammil1998 picture muhammadmuzzammil1998  路  3Comments

wayneashleyberry picture wayneashleyberry  路  3Comments

mikolysz picture mikolysz  路  3Comments

ericmdantas picture ericmdantas  路  3Comments

dafanasiev picture dafanasiev  路  3Comments