首页 > 代码库 > 黑名单过滤绕过有感

黑名单过滤绕过有感

今天发现一个绕过正则过滤的问题,很多应用使用正则表达式对输入数据做安全验证,比如,在修改设备名称时的过滤过则为:

String regex = "^.*[\\\\/:\\*\\?\"<>\\|‘%&]+.*$"; //出现1个或多个”\/:*?"<>|‘%&”字符表示不合法

Pattern pattern = Pattern.compile(regex);

Matcher matcher = pattern.matcher(str);

但我们发现当输入回车换行符(\r\n)时该验证正则表达式即可被绕过(紧接着出现安全问题),比如输入”abc\r\n<>”是检测不到的,原因在于‘.‘ 默认是不匹配象‘\r‘,‘\n‘等的,如果要匹配则使用OPTIONS Pattern.DOTALL,故应写:

Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);

但是,没人能保证这样写就没有其它可以继续绕过的情况了,所以这个问题的本质原因并非错误地使用了方法,而是没有使用白名单进行过滤,即只允许指定的字符通过,其它都是不允许的,以下是OWASP ESAPI对文件名和目录名的白名单过滤规则,供大家参考:

Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~‘` ]{1,255}$  //[]内的字符是允许出现的白名单字符,长度为1-255,出现其它字符都是非法的

Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~‘` ]{1,255}$

同理地,我们也可以为设备名称等各种用户输入设定类似字符白名单,因此,强烈建议大家改用白名单的方式来做数据安全验证。

黑名单过滤绕过有感