2

让我把我的问题简单化我想要的是我使用白名单正则表达式模式来避免 xss 和 sql 注入,因此我允许的字符串中的字符是 [A-Za-z0-9,()[]{}\"\: ./_\s] 并且我想限制 -- 在来自客户端的任何请求中的出现,但它应该允许 - 或 jjdfasd-dsfads-12321 字符串

简而言之,它下面的测试用例应该成功运行

import java.util.regex.Pattern;


public class RegExTest {

private static Pattern xssAttackPattern;

private static final String XSS_ATTACK_REGULAR_EXPRESSION1 = "-?[A-Za-z0-9,\\(\\)\\[\\]\\{\\}\"\\:./_\\s]*";


public static Pattern getXSSAttackPattern1() {
    xssAttackPattern = Pattern.compile(XSS_ATTACK_REGULAR_EXPRESSION1);
    return xssAttackPattern;
}

public static boolean hasXSSAttackOrSQLInjection1(String value) {

    if (getXSSAttackPattern1().matcher(value).matches()) {
        return true;
    }
    return false;
}



public static void main(String arg[]) {

    System.out.println(" :::::: Regular Expression ::::::");
    regexTest();

}

private static void regexTest() {

    String str1 = "-dsfdsfddsfd2112212s";
    String str2 = "--dsfdsfddsfd2112212s";
    String str3 = "-dsfdsfdd-sfd2112212s";
    String str4="http://rss.cnn.com/rss/edition_business.rss?id=121132511$@#$@$@#%242444+gfghgfhg";
    String str5="(.:[]{}";
    String str6="--";
    String str7="-";

    System.out.println("String::" + str1 + "::Result::"
            + hasXSSAttackOrSQLInjection1(str1));
    System.out.println("String::" + str2 + "::Result::"
            + hasXSSAttackOrSQLInjection1(str2));
    System.out.println("String::" + str3 + "::Result::"
            + hasXSSAttackOrSQLInjection1(str3));
    System.out.println("String::" + str4 + "::Result::"
            + hasXSSAttackOrSQLInjection1(str4));
    System.out.println("String::" + str5 + "::Result::"
            + hasXSSAttackOrSQLInjection1(str5));
    System.out.println("String::" + str6 + "::Result::"
            + hasXSSAttackOrSQLInjection1(str6));
    System.out.println("String::" + str7 + "::Result::"
            + hasXSSAttackOrSQLInjection1(str7));
}

}

4

1 回答 1

2

您当前的正则表达式匹配

  • 由单个-字符组成的字符串,或
  • 由一系列字母、数字和一些特殊字符组成的字符串,或
  • 一个空字符串

如果您想将其更改为-仅在字符串开头允许零个或一个破折号,请从表达式中删除OR字符|;如果您想在字符串中的任意位置最多匹配一个破折号,请将表达式更改为

[A-Za-z0-9,\\(\\)\\[\\]\\{\\}\"\\:./_\\s]*-?[A-Za-z0-9,\\(\\)\\[\\]\\{\\}\"\\:./_\\s]*

编辑 1:如果您需要避免两个连续的破折号,您可以将此表达式与否定的lookbehind一起使用:

([A-Za-z0-9,\\(\\)\\[\\]\\{\\}\"\\:./_\\s]|(?<!-)-)*

上面的(?<!-)-表达式部分匹配一个破折号,除非它前面有另一个破折号。

编辑 2:如果您有 10000+ 长度的字符串,则正则表达式解决方案不如负正则表达式解决方案好。与寻找相比,寻找并使用此表达式进行否定匹配myString.matches(positiveExpr)更有效。!myString.matches(negativeExpr)换句话说,您可以为不需要的字符串定义一个更简单的表达式,而不是指定定义所需字符串的表达式:

[^A-Za-z0-9,\\(\\)\\[\\]\\{\\}\"\\:./_\\s]|--

注意:清理字符串并不是避免 SQL 注入攻击的最佳方法;使用参数化语句是。

于 2012-04-30T10:22:10.000 回答