2

我的目标是通过为从客户端收到的任何和所有 POST 数据创建一个严格的允许字符白名单来保护我的网站免受攻击。

当停留在 ASCII 字符内时,这是小菜一碟。就像是:

if(preg_match('/[^aA-zZ0-9]/', $stringToTest))
{
   // Battle stations!!
}

但是,我需要能够允许任何和所有 utf-8 字符,尤其是亚洲字符集,如日文、中文和韩文。但我不想排除任何有古怪字符的人,比如阿拉伯语或俄语,或者其他什么。一个世界,一份爱!;)

我怎样才能允许人们输入他们母语的字符,同时排除邪恶脚本中使用的讨厌的东西,比如*、?、尖括号等等?

4

4 回答 4

5

\w会给你单词字符(字母、数字和下划线),这可能是你想要\s的空格。

例如

if(preg_match('/[\w\s]/', $stringToTest))
{
   // Battle stations!!
}

regular-expressions.info是这些东西的一个很好的参考——这里这里有几个相关的页面 :)

编辑:需要更多澄清,对不起!

这是我通常用于 CJK 的:

function get_CJK_ranges() {

    return array(
                "[\x{2E80}-\x{2EFF}]",      # CJK Radicals Supplement
                "[\x{2F00}-\x{2FDF}]",      # Kangxi Radicals
                "[\x{2FF0}-\x{2FFF}]",      # Ideographic Description Characters
                "[\x{3000}-\x{303F}]",      # CJK Symbols and Punctuation
                "[\x{3040}-\x{309F}]",      # Hiragana
                "[\x{30A0}-\x{30FF}]",      # Katakana
                "[\x{3100}-\x{312F}]",      # Bopomofo
                "[\x{3130}-\x{318F}]",      # Hangul Compatibility Jamo
                "[\x{3190}-\x{319F}]",      # Kanbun
                "[\x{31A0}-\x{31BF}]",      # Bopomofo Extended
                "[\x{31F0}-\x{31FF}]",      # Katakana Phonetic Extensions
                "[\x{3200}-\x{32FF}]",      # Enclosed CJK Letters and Months
                "[\x{3300}-\x{33FF}]",      # CJK Compatibility
                "[\x{3400}-\x{4DBF}]",      # CJK Unified Ideographs Extension A
                "[\x{4DC0}-\x{4DFF}]",      # Yijing Hexagram Symbols
                "[\x{4E00}-\x{9FFF}]",      # CJK Unified Ideographs
                "[\x{A000}-\x{A48F}]",      # Yi Syllables
                "[\x{A490}-\x{A4CF}]",      # Yi Radicals
                "[\x{AC00}-\x{D7AF}]",      # Hangul Syllables
                "[\x{F900}-\x{FAFF}]",      # CJK Compatibility Ideographs
                "[\x{FE30}-\x{FE4F}]",      # CJK Compatibility Forms
                "[\x{1D300}-\x{1D35F}]",    # Tai Xuan Jing Symbols
                "[\x{20000}-\x{2A6DF}]",    # CJK Unified Ideographs Extension B
                "[\x{2F800}-\x{2FA1F}]"     # CJK Compatibility Ideographs Supplement
    );

}

function contains_CJK($string) {
    $regex = '/'.implode('|',get_CJK_ranges()).'/u';
    return preg_match($regex,$string);
}

要获得所有可能成为转义和其他黑帽问题的问题,请使用:

/[^\p{Punctuation}]/( == /[^\p{P}]/)

或者

/[^\32-\151]/( == /[^!-~]/)

另一个很好的链接

于 2011-02-22T05:01:16.243 回答
2

对于某些事情,您可以进行 base64 编码,但我不得不删除一些不可行的功能,因为保留所有字符似乎更重要,而且现在肯定不值得花更多时间。

...

在说我遇到了这个问题之后,如果你想要一个通用功能,那么由于字符太多,问题似乎变成了效率,但这不是一个大问题(中文、俄语和希腊语可能有单独的网页等)。

http://www.php.net/manual/en/regexp.reference.unicode.php

于 2011-04-02T00:08:51.567 回答
0

尝试反转测试 - 使用黑名单而不是白名单。例如

if(preg_match('/[\*\?<>]/', $stringToTest))
{
    // Battle stations!!
}

正则表达式可能不太正确,但你明白了。

于 2011-02-22T04:59:04.603 回答
0

我怀疑你可以用这种方式保护任何东西。
您只会使公平用户的事情复杂化,但不要阻止恶意用户。

我会退出一个不允许我输入问号、引用或电子邮件的网站。
简单的点肯定是“邪恶脚本中使用的脏东西”之一。但是没有它的任何消息都会看起来很难看。

虽然 SQL 注入只能使用字母字符来完成。

我认为这种“保护”毫无意义。

于 2011-02-22T07:43:35.173 回答