在Java中清理字符串

10

是否有任何函数或库可用于清理用户输入。例如,如果用户输入名为baily's的文本,则应在发送到mysql查询之前转义'。同样,我应该能够过滤空字符和\n、\t、\r等。就像在PHP中我们有mysql_real_escape_string($input),在Java中有没有类似的东西?


如果您使用ORM层(这在Java中是常见的做法)或者仅使用带有命名或枚举参数的语句,那么SQL参数的转义将会自动完成。只要您不手动将字符串连接起来构建查询,您就应该是安全的。 - aroth
5个回答

11

在Java中,通常不需要手动执行此操作。

相反,您将使用PreparedStatement并通过显式的setString()setObject()方法传递任何参数到SQL语句中。

这样JDBC驱动程序将处理它(根据DB的不同,可能通过执行必要的转义或将SQL语句单独发送给参数来完成)。

例如,您的代码可能如下所示(使用prepareStatement()):

Connection c = ...; // get Connection from somehwere
PreparedStatement stmt = c.prepareStatement("SELECT * FROM BOOKS WHERE TITLE = ?");
stmt.setString(1, userInput);
ResultSet result = stmt.executeQuery();

4

2
简短回答是,除非针对“干净”的非常特定的定义,否则不行。目前,您必须使用特定于语言的解决方案——对于SQL,只需使用预处理语句。
更长的回答是,最近有关于自动字符串消毒器的工作,该消毒器可以安全且正确地将纯文本内容合并到其他语言中的内容中。
在像SoyGojQuery的模板语言中,存在用于HTML的自动上下文自动转义器,以及cTemplates、clearsilver等变体。
正在进行研究,以便将其普遍化,以便可以轻松地扩展到其他语言。我正在研究的一个想法是,采用描述目标语言(例如SQL)的注释语法,并找出需要对可以填充用户数据的空洞进行转义的方法。
给定以下类似的语法,其中包括注释,显示数据结构如何映射到语言中的子字符串:
JSONValue            := JSONNullLiteral
                      | JSONBooleanLiteral
                      | JSONObject
                      | JSONArray
                      | JSONString
                      | JSONNumber                                    ;
JSONObject           := @KeyValueMap ([{] JSONMemberList? [}])        ;
JSONMemberList       := JSONMember ([,] JSONMemberList)?              ;
JSONMember           := @Key JSONString [:] @Value JSONValue          ;
JSONNullLiteral      := @ValueNull "null"                             ;
JSONBooleanLiteral   := @ValueFalse "false" | @ValueTrue "true"       ;
JSONArray            := @List("[" (JSONValue ([,] JSONValue)*)? "]")  ;
JSONString           := @String ([\"] JSONStringCharacters? [\"])     ;
JSONNumber           := @Number (Sign? (Mantissa Exponent? | Hex))    ;
JSONStringCharacters := JSONStringCharacter JSONStringCharacters?     ;
JSONStringCharacter  := @Char ([^\"\\\x00-\x1f])
                      | JSONEscapeSequence                            ;
JSONEscapeSequence   := "\\" @Char [/\\\"]
                      | @Char{[\x08]} "\\b"
                      | @Char{[\x0c]} "\\f"
                      | @Char{[\x0a]} "\\n"
                      | @Char{[\x0d]} "\\r"
                      | @Char{[\x09]} "\\t"
                      | @Char ("\\u" @Scalar (hex hex hex hex))       ;
Mantissa             := (Integer ([.] Fraction?) | [.] Fraction)      ;
Exponent             := [Ee] Sign? decimal+                           ;
Integer              := [0] | [1-9] [0=9]*                            ;
Fraction             := [0-9]+                                        ;
Hex                  := [0] [Xx] hex+                                 ;
Sign                 := [+\-]                                         ;

我们可以构建一个如下所示的状态机:

enter image description here

这段文字描述了将事件序列(开始、开始对象、开始键、字符“x”等)转换为指令,以便将字符编码到缓冲区中。通过这种状态机,我们还可以生成通用指令跟踪,用于生成编码器的有效代码,并希望能够执行上下文分析算法,以确定何时应使用哪些编码器。
如果成功,它将使得将类似SQL、HTML等语言中的内容自动安全地组合到通用编程语言中变得容易。通过对语言定义进行微调,允许execute_query找到程序员指定内容和注入内容之间的边界,在execute_query("SELECT * FROM Table WHERE ID=$ID")中自动转义注入的内容,我们可以使该习惯用语按照程序员的意图正常运行。

2
你应该使用 PreparedStatement 并使用 setString 函数设置 $input 的值。
使用 PreparedStatement 的原因是每个数据库可能需要转义不同的内容。这种复杂性被隐藏在由数据库供应商提供的 PreparedStatement 的具体实现中。

1

你使用的转义符号取决于你想要在哪个系统中使用该字符串。如果你使用MySQL,你需要进行不同的转义,而如果你想在JavaScript代码中使用该字符串,则需要进行其他的转义。

因此,为了回答你的问题,我们需要知道你想如何转义你的字符串。很有可能在将字符串用于数据库上下文之前,你并不需要对其进行转义。例如,如果你使用prepared queries,则不需要转义你的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接