Fix a potential log spamming and DOS attack #308
Merged
+63
−3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
What does this do and why is this needed?
I have discovered an attack that allows you to attack any non-trivial programs that use onion. At the very least it allows you to spam the logs with a few hundred thousand useless messages, and maybe even deny service to other clients. And the worst part about it? You only need Firefox (maybe Chrome can do it as well, I haven't tested that) and a functional F5 key.
To reproduce it:
<Your IP>:8080/teapot.localhost:8080/teapot.C source file
So, how does it work?
It's quite simple: when Firefox refreshes, it'll reset all current connections with the server, if any, and then it'll reconnect. Thus, by holding down F5 Firefox will connect to the server and reset that connection almost immediately and will continue doing that while the key is being held down. When the connection is reset, onion will complain about being unable to write the chunk encoding length in a warning, which is reasonable behavior most of the time - but not always. By connecting and resetting countless times we'll not only create a bunch of useless warnings in the log, but we'll also make all the threads very busy writing that log down to the stdout (or syslog). And, quite obviously, when a thread is writing a warning to the log it's not doing any serving, and when all threads are writing to the log the client will not get served at all.
The fix
The fix is as simple as the problem: allow onion to log a chunk encoding write error only once a second, and at other times just count the errors and output the count if an error occurs after a second since the previous warning had been written.
Logs of the sample program before the commit
Some onion logs
Logs of the sample program after the commit
Some more onion logs