首先声明,我是数据库小白,以下分享只是个人学习的记录,大佬请绕道!
最近学习pqxx这个库时,看到文档里面解释的escap作用,感觉还不错,就拿来翻译一下,作为备忘,原文地址:https://libpqxx.readthedocs.io/en/6.4/a01477.html
字符串转义
(首先我得吐槽以下国内的那些机翻文档,把escap翻译成“逃逸”,真的误人子弟!)
写一个查询字符串很简单。但是有时候你需要向查询语句中传入变量:"SELECT id FROM user WHERE name = '" + name + "'".
但是上面的查询语句非常危险。你能看到这个bug么?如果name中包含了引号,则会引起SQL注入漏洞(SQL injection vulnerability ),用户可以输入很恶心的内容,例如:.'; DROP TABLE user
(会删除数据库中user表)。(后面就是废话了,不翻译了)
所以,你需要在插入name之前,要对name进行转义(escape)。这样,引号和其他特殊字符就会被标记为“这只是字符串中的一个字符,不是这个字符串的结尾”。
SQL注入
必须要了解一下什么时SQL注入漏洞,以及应该怎么阻止这些漏洞。例如你的程序使用了以下SQL语句:
TX.exec(
"SELECT number,amount "
"FROM accounts "
"WHERE allowed_to_see('" + userid + "','" + password + "')");
以上显示了登录的用户,才能查看账户的重要信息,userid 和 password 字符串是用户自己输入的变量。
现在,如果用户是知道(或可以猜到)这条 SQL 语句的大致形状的攻击者,想象他输入了以下密码:
x') OR ('x' = 'x
如果把上面的代码插入到 SQL 字符串中,则查询变为:
SELECT number,amount
FROM accounts
WHERE allowed_to_see('user','x') OR ('x' = 'x')
执行以上sql语句,allowed_to_see('user','x')
子语句就会被OR ('x' = 'x')
子语句屏蔽掉,永远返回为true。攻击者就可以看到数据库中所有账号!
使用escape函数
你可以用以下代码进行修正:
TX.exec(
"SELECT number,amount "
"FROM accounts "
"WHERE allowed_to_see('" + TX.esc(userid) + "', "
"'" + TX.esc(password) + "')");
现在,嵌入在攻击者字符串中的引号将被巧妙地转义,因此它们不能“突破”它们原本要进入的带引号的 SQL 字符串:
SELECT number,amount
FROM accounts
WHERE allowed_to_see('user', 'x'') OR (''x'' = ''x')
如果你仔细看,你会发现由于添加了转义字符(单引号在 SQL 中通过加倍转义),我们得到的只是一个看起来很奇怪的密码字符串——但 SQL 语句中没有变化。
网友评论