如何在MySQL的命令行shell界面中防止SQL注入?

时间:2010-12-15 14:06:58

标签: sql mysql linux shell sql-injection

我使用shell脚本与MySQL数据库进行通信。 MySQL支持将查询指定为shell参数,如下所示:

mysql my_db -B -N -e "select id from Table"

但是,如果我有一个参数,我想在查询中使用,我如何获得针对注入攻击的保护?

一种天真的方法是将变量值粘贴到请求中,但它不是很安全:

mysql my_db -B -N -e "select id from Table where name='$PARAM'"

是否有任何技巧或文档化的界面可以从命令行进行注入安全查询?

4 个答案:

答案 0 :(得分:6)

您可以对该值进行base64编码,然后在MySQL中对其进行base64解码。 MySQL中有UDF用于将Base64数据转换为通用数据。此外,大多数系统要么具有uuencode,要么使用base64编码数据的“base64”命令。

答案 1 :(得分:0)

只要您通过连接参数构建SQL,您的应用程序就可以成功进行SQL注入攻击(如您的示例所示)。维基百科上有一篇关于此内容的文章:http://en.wikipedia.org/wiki/SQL_injection

我怀疑你会想要使用文章中提到的mysql_real_escape_string函数编写一个unix过滤器来构建你的SQL查询。

考虑将SQL作为第一个参数传递,将变量作为后续参数传递,然后让它返回构造的SQL。如果您将过滤器命名为“blobbo”,则示例中的命令可能如下所示:

blobbo“从表中选择id,其中name =%s”$ PARAM

答案 2 :(得分:0)

您不仅要防止SQL注入,还要防止shell注入。您可能希望将查询(在清理任何动态部分之后)写入文件,然后将该文件重定向到mysql,而不是希望查询不会破坏shell。考虑:

PARAM="name'\"; rm -rf / ; echo 'pwn3d U"

成为

mysql my_db -B -N -e "select id from Table where name='name'"; rm -rf / ; echo 'pwn3d U'

或:

command 1: mysql my_db -B -N -e "select id from Table where name='name'"
command 2: rm -rf /
command 3: echo 'pwn3d U'

相反,做一些事情:

 cat <<EOT > query.sql
 select .... blah blaah blah .... sanitized query here
 EOT
 mysql my_db -B -N < query.sql

这将阻止任何用户指定的数据出现在shell命令本身中,从而防止至少一个级别的注入漏洞。但是,您仍然必须处理SQL注入问题。

答案 3 :(得分:0)

Sargun Dhillon的回答向我指出了正确的方向。不幸的是,在MySQL 5.6之前,FROM_BASE64不可用,所以我选择了UNHEX。

下面的脚本是一个从shell查询Redmine用户详细信息的示例。如果不受信任的用户有权访问此脚本,我仍然无法入睡,但在我的情况下它足够安全。 (它也仅限于字符串值,您不应该在查询中有问号,但这些限制对我来说没问题。)

#!/bin/bash

MYSQL_OPTS='--defaults-file=/etc/redmine/mysql.cnf'

mysql_query() {
  local db=$1
  local sql=$2
  shift 2 || return 1
  declare -a args=("$@")

  sql=${sql//[%]/%%}
  sql=${sql//[?]/UNHEX('%s')}
  for ((i=0; i<${#args[@]}; i++)); do
    args[$i]=$(echo -n "${args[$i]}" | hexdump -v -e '/1 "%02X"')
  done
  sql=$(printf "$sql" "${args[@]}")
  mysql $MYSQL_OPTS "$db" -e "$sql" || return $?
}

for u in "$@"; do
  mysql_query redmine 'select * from users where login=?\G' "$u" 
done

如果您发现我错过了任何SQL或Shell注入,请发表评论。