我有一个数据库脚本,当给定一个ID,姓氏和名字时,它会搜索重复的ID。这是它的肉和土豆:
PSQL="psql -p $PGPORT -h $DBHOST -d $DB -tAc "
DUP_ID=$($PSQL "SELECT id FROM inmate WHERE id NOT SIMILAR TO '(0*)${1}' AND lastname ILIKE '${_LNAME}' AND firstname ILIKE '${_FNAME}' LIMIT 1")
效果很好,除非最后一个名字或名字中有撇号,例如“O'Neil”。我试图逃避任何'with'的例子,但还没有成功。我花了一整天的时间搜索论坛,并尝试了不同的变化,但它仍然不会在每个'前面添加\。
这是我到目前为止所得到的:
local _LNAME=`echo "${2}" | sed "s/'/\\\'/g"`
local _FNAME=`echo "${3}" | sed "s/'/\\\'/g"`
echo -e $_LNAME
echo -e $_FNAME
# Output
O'Neil
Robert
一如既往,提前谢谢!
答案 0 :(得分:2)
QUERY=(
SELECT id FROM inmate WHERE
id NOT SIMILAR TO "'(0*)$1'" AND
lastname ILIKE "'$_LNAME'" AND
firstname ILIKE "'$_FNAME'" LIMIT 1
)
psql -p $PGPORT -h $DBHOST -d $DB -tAc "${QUERY[*]}"
答案 1 :(得分:1)
这是传递复杂命令的错误方法:
PSQL="psql -p $PGPORT -h $DBHOST -d $DB -tAc "
相反,使用数组:
single_quote="'"
escaped_single_quote="\\'"
quoted_fname=${1//$single_quote/$escaped_single_quote}
quoted_lname=${2//$single_quote/$escaped_single_quote}
psql=( psql -p "$PGPORT" -h "$DBHOST" -d "$DB" -tAc )
dup_id=( "${psql[@]}" "SELECT id FROM ... WHERE ... '${quoted_lname}'" )
...然后使用"${dup_id[@]}"
运行您的命令将保护您免受shell注入错误。 不保证可以保护您免受SQL注入攻击(有太多的方法来执行这些攻击,并且数据库在字符集转换方面有太多的特性,信任简单的基于字符替换的转义这里用来反对恶意数据),但是,这就是为什么那些关心正确性或安全性的人会使用支持绑定参数的语言 - 一组bash不是成员 - 来生成SQL查询。
另请参阅BashFAQ #50和freenode.org #bash频道wiki中的BashWeaknesses页面 - 后者明确地将SQL生成称为bash不适合的任务。