DOC: developing filters without DoS

pull/260/head
Daniel Black 2013-06-15 13:17:09 +10:00
parent 9d4b613ee4
commit ee786671aa
1 changed files with 85 additions and 2 deletions

87
DEVELOP
View File

@ -41,8 +41,91 @@ Filters
example.com/example.org used for DNS names
* Ensure ./fail2ban-regex testcases/files/logs/{samplelog} config/filter.d/{filter}.conf
has matches for EVERY regex
* Ensure regexs end with a $ and are restrictive as possible. E.g. not .* if
[0-9]+ is sufficient
* Ensure regexs start with a ^ and are restrictive as possible. E.g. not .* if
\d+ is sufficient
* Use the functionality of regexs http://docs.python.org/2/library/re.html
* Take a look at the source code of the application. You may see optional or
extra log messages, or parts there of, that need to form part of your regex.
If you only have a basic knowledge of regular repressions read
http://docs.python.org/2/library/re.html first.
Filter Security
---------------
Poor filter regular expressions are suseptable to DoS attacks.
When a remote user has the ability to introduce text that will match the
filter regex such that the inserted text matches the <HOST> part they have the
ability to deny any host they choose.
So the <HOST> part must be anchored on text generated by the application and not
the user. Ideally this should anchor to the beginning and end of the log line
however as more applications log at the beginning than the end, achoring the
beginning is more important.
When creating a regex that extends back to the begining remember the date part
has been removed within fail2ban so theres no need to match that. If the format
is like '<date...> error 1.2.3.4 is evil' then you will need to match the < at
the start so here the regex would start like '^<> <HOST> is evil$'.
Some applications log spaces at the end. If you're not sure add \s*$ as the
end part of the regex.
Examples of poor filters
------------------------
1. Too restrictive
We find a log message:
Apr-07-13 07:08:36 Invalid command fial2ban from 1.2.3.4
We make a failregex
^Invalid command \S+ from <HOST>
Now think evil. The user does the command 'blah from 1.2.3.44'
The program diliently logs:
Apr-07-13 07:08:36 Invalid command blah from 1.2.3.44 from 1.2.3.4
And fail2ban matches 1.2.3.44 as the IP that it ban. A DoS attack was successful.
The fix here is that the command can be anything so .* is approprate.
^Invalid command .* from <HOST>
Here the .* will match until the end of the string. Then realise it has more to
match, i.e. "from <HOST>" and go back until it find this. Then it will ban
1.2.3.4 correctly. Since the <HOST> is always at the end, end the regex witha $
^Invalid command .* from <HOST>$
Note if we'd just had the expression:
^Invalid command \S+ from <HOST>$
Then provided the user put a space in their command they would have never been
banned.
2. Applicaiton generates two identical log messages with different meanings
If the application generates the following two messages under different
circmstances:
client <IP>: authentication failed
client <USER>: authentication failed
Then its obvious that a regex of "^client <HOST>: authentication
failed$" will still cause problems if the user can trigger the second
log message with a <USER> of 123.1.1.1.
Here there's nothing to do except request/change the application so it logs
messages differently.
Code Testing
============