body, td {
font-family: calibri;
font-size: 10pt;
}
演示
记得以前瞎鼓捣的时候,学过一个传说中的SQL注入万能字符串,是这个样子的' or '1'='1
先演示一下效果:
这是我们数据库中目前的存储的用户情况. 当然…明文存储密码是件非常值得鄙视的事情…
这是一个简单的登录界面. 正常情况下,我们如果输入的密码错误,会出现错误提示.
但是,如果我们在用户名后拼接一个传说中的万能字符串,或者直接使用万能字符串作为密码的话,就可以直接登录.会跳转到我写的一个简陋到令人发指的欢迎页面.
原因
很简单,看一下代码:
这里是关于数据库查询的代码,我们实际执行的那条sql语句是拼接出来的. String sql = "select * from user where username='"+username+"' and password='"+password+"'";
而从页面上拿到的用户名和密码就是两个文本框里输入的内容.
因此,如果我们将密码输入框里输入' or '1'='1
那么这条sql语句会变成这个样子: String sql = "select * from user where username='tom' and password='' or '1'='1'"
这种情况下where子句无论如何其结果都是true. 是可以正常通过认证的.
解决办法
最简单的解决办法就是使用PreparedStatement,先对sql语句进行预编译. 这种情况下就避免了字符串拼接的问题了.
当然也可以采用一些正则匹配去对输入做校验. 只不过…太多人遇到正则表达式都头疼,所以…还是用最简单的PreparedStatement吧…
%23%u6D45%u6790SQL%u6CE8%u5165%0A%0A%0A%23%23%u6F14%u793A%0A%u8BB0%u5F97%u4EE5%u524D%u778E%u9F13%u6363%u7684%u65F6%u5019%2C%u5B66%u8FC7%u4E00%u4E2A%u4F20%u8BF4%u4E2D%u7684SQL%u6CE8%u5165%u4E07%u80FD%u5B57%u7B26%u4E32%2C%u662F%u8FD9%u4E2A%u6837%u5B50%u7684%60%27%20or%20%271%27%3D%271%60%20%20%u5148%u6F14%u793A%u4E00%u4E0B%u6548%u679C%3A%0A%0A%21%5BAlt%20text%5D%28./1488365905231.png%29%0A%0A%u8FD9%u662F%u6211%u4EEC%u6570%u636E%u5E93%u4E2D%u76EE%u524D%u7684%u5B58%u50A8%u7684%u7528%u6237%u60C5%u51B5.%20%u5F53%u7136...%u660E%u6587%u5B58%u50A8%u5BC6%u7801%u662F%u4EF6%u975E%u5E38%u503C%u5F97%u9119%u89C6%u7684%u4E8B%u60C5...%0A%0A%21%5BAlt%20text%5D%28./1488365955854.png%29%0A%u8FD9%u662F%u4E00%u4E2A%u7B80%u5355%u7684%u767B%u5F55%u754C%u9762.%20%u6B63%u5E38%u60C5%u51B5%u4E0B%2C%u6211%u4EEC%u5982%u679C%u8F93%u5165%u7684%u5BC6%u7801%u9519%u8BEF%2C%u4F1A%u51FA%u73B0%u9519%u8BEF%u63D0%u793A.%20%0A%0A%21%5BAlt%20text%5D%28./1488366003424.png%29%0A%0A%u4F46%u662F%2C%u5982%u679C%u6211%u4EEC%u5728%u7528%u6237%u540D%u540E%u62FC%u63A5%u4E00%u4E2A%u4F20%u8BF4%u4E2D%u7684%u4E07%u80FD%u5B57%u7B26%u4E32%2C%u6216%u8005%u76F4%u63A5%u4F7F%u7528%u4E07%u80FD%u5B57%u7B26%u4E32%u4F5C%u4E3A%u5BC6%u7801%u7684%u8BDD%2C%u5C31%u53EF%u4EE5%u76F4%u63A5%u767B%u5F55.%u4F1A%u8DF3%u8F6C%u5230%u6211%u5199%u7684%u4E00%u4E2A%u7B80%u964B%u5230%u4EE4%u4EBA%u53D1%u6307%u7684%u6B22%u8FCE%u9875%u9762.%20%0A%0A%21%5BAlt%20text%5D%28./1488366121270.png%29%0A%0A%0A%23%23%u539F%u56E0%0A%0A%u5F88%u7B80%u5355%2C%u770B%u4E00%u4E0B%u4EE3%u7801%3A%0A%21%5BAlt%20text%5D%28./1488366199300.png%29%0A%0A%u8FD9%u91CC%u662F%u5173%u4E8E%u6570%u636E%u5E93%u67E5%u8BE2%u7684%u4EE3%u7801%2C%u6211%u4EEC%u5B9E%u9645%u6267%u884C%u7684%u90A3%u6761sql%u8BED%u53E5%u662F%u62FC%u63A5%u51FA%u6765%u7684.%0A%60String%20sql%20%3D%20%22select%20*%20from%20user%20where%20username%3D%27%22+username+%22%27%20and%20password%3D%27%22+password+%22%27%22%3B%60%0A%u800C%u4ECE%u9875%u9762%u4E0A%u62FF%u5230%u7684%u7528%u6237%u540D%u548C%u5BC6%u7801%u5C31%u662F%u4E24%u4E2A%u6587%u672C%u6846%u91CC%u8F93%u5165%u7684%u5185%u5BB9.%20%0A%u56E0%u6B64%2C%u5982%u679C%u6211%u4EEC%u5C06%u5BC6%u7801%u8F93%u5165%u6846%u91CC%u8F93%u5165%60%27%20or%20%271%27%3D%271%60%0A%u90A3%u4E48%u8FD9%u6761sql%u8BED%u53E5%u4F1A%u53D8%u6210%u8FD9%u4E2A%u6837%u5B50%3A%0A%60String%20sql%20%3D%20%22select%20*%20from%20user%20where%20username%3D%27tom%27%20and%20password%3D%27%27%20or%20%271%27%3D%271%27%22%60%0A%0A%u8FD9%u79CD%u60C5%u51B5%u4E0Bwhere%u5B50%u53E5%u65E0%u8BBA%u5982%u4F55%u5176%u7ED3%u679C%u90FD%u662Ftrue.%20%u662F%u53EF%u4EE5%u6B63%u5E38%u901A%u8FC7%u8BA4%u8BC1%u7684.%20%0A%0A%0A%23%23%u89E3%u51B3%u529E%u6CD5%0A%0A%u6700%u7B80%u5355%u7684%u89E3%u51B3%u529E%u6CD5%u5C31%u662F%u4F7F%u7528PreparedStatement%2C%u5148%u5BF9sql%u8BED%u53E5%u8FDB%u884C%u9884%u7F16%u8BD1.%20%u8FD9%u79CD%u60C5%u51B5%u4E0B%u5C31%u907F%u514D%u4E86%u5B57%u7B26%u4E32%u62FC%u63A5%u7684%u95EE%u9898%u4E86.%20%0A%0A%u5F53%u7136%u4E5F%u53EF%u4EE5%u91C7%u7528%u4E00%u4E9B%u6B63%u5219%u5339%u914D%u53BB%u5BF9%u8F93%u5165%u505A%u6821%u9A8C.%20%u53EA%u4E0D%u8FC7...%u592A%u591A%u4EBA%u9047%u5230%u6B63%u5219%u8868%u8FBE%u5F0F%u90FD%u5934%u75BC%2C%u6240%u4EE5...%u8FD8%u662F%u7528%u6700%u7B80%u5355%u7684PreparedStatement%u5427...%0A