这个由 SQL 注入生成的查询有多安全?
How safe is this generated query from SQL injection?
我正在尝试制作一个适用于多个单词的搜索栏,但我担心 SQL 注入。
我正在使用 node express 和 npm mssql 包。
这是获取条件、生成 SQL 并运行它的代码:
router
.get('/search/:criteria', function (req, res) {
var criteria = req.params.criteria;
var words = criteria.split(" ");
var x = ""
words.map(word => x += `name like '%${word}%' and `);
x = x.substring(0, x.length - 5); // Remove trailing 'and'
var query = `SELECT * FROM table WHERE ${x}`
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request().query(query)
}).then(result => {
})
});
搜索 something to search
将导致此查询:
SELECT * FROM table
WHERE
name like '%something%'
and name like '%to%'
and name like '%search%'
我自己尝试了一些 SQL 注射,但其中 none 似乎有效。
注意:我知道我们应该总是为此使用输入。它适用于一个词,但我不知道如何对多个词使用输入。例如:
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request()
.input('input', '%'+criteria+'%')
.query(query)
})
答案是:不安全。您的代码也完全没有采取任何措施来确保其安全。不要通过 concatenating/interpolating 用户提供的数据将 SQL 构建到语句中。
此外,您也不对 LIKE
本身进行任何转义,因此这同样不干净。
如果您需要动态 SQL,请使用预期的占位符数量构建准备好的 SQL 语句,然后 然后 将用户提供的值绑定到这些占位符.
router.get('/search/:criteria', (req, res) => {
const ps = new sql.PreparedStatement();
const sqlConditions = [];
const escapedValues = {};
// set up escaped values, safe SQL bits, PS parameters
req.params.criteria.split(" ").forEach((v, i) => {
const paramName = 'val' + i;
escapedValues[paramName] = v.replace(/[\%_]/g, '\$&');
sqlConditions.push(`name LIKE '%' + @${paramName} + '%' ESCAPE '\'`);
ps.input(paramName, sql.VarChar);
});
// build safe SQL string, prepare statement
const sql = 'SELECT * FROM table WHERE ' + sqlConditions.join(' AND ');
ps.prepare(sql);
// connect, execute, return
ps.execute(escapedValues).then(result => {
res(result)
});
});
(免责声明:代码未经测试,因为我现在没有 SQL 服务器可用,但你明白了。)
我正在尝试制作一个适用于多个单词的搜索栏,但我担心 SQL 注入。
我正在使用 node express 和 npm mssql 包。
这是获取条件、生成 SQL 并运行它的代码:
router
.get('/search/:criteria', function (req, res) {
var criteria = req.params.criteria;
var words = criteria.split(" ");
var x = ""
words.map(word => x += `name like '%${word}%' and `);
x = x.substring(0, x.length - 5); // Remove trailing 'and'
var query = `SELECT * FROM table WHERE ${x}`
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request().query(query)
}).then(result => {
})
});
搜索 something to search
将导致此查询:
SELECT * FROM table
WHERE
name like '%something%'
and name like '%to%'
and name like '%search%'
我自己尝试了一些 SQL 注射,但其中 none 似乎有效。
注意:我知道我们应该总是为此使用输入。它适用于一个词,但我不知道如何对多个词使用输入。例如:
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request()
.input('input', '%'+criteria+'%')
.query(query)
})
答案是:不安全。您的代码也完全没有采取任何措施来确保其安全。不要通过 concatenating/interpolating 用户提供的数据将 SQL 构建到语句中。
此外,您也不对 LIKE
本身进行任何转义,因此这同样不干净。
如果您需要动态 SQL,请使用预期的占位符数量构建准备好的 SQL 语句,然后 然后 将用户提供的值绑定到这些占位符.
router.get('/search/:criteria', (req, res) => {
const ps = new sql.PreparedStatement();
const sqlConditions = [];
const escapedValues = {};
// set up escaped values, safe SQL bits, PS parameters
req.params.criteria.split(" ").forEach((v, i) => {
const paramName = 'val' + i;
escapedValues[paramName] = v.replace(/[\%_]/g, '\$&');
sqlConditions.push(`name LIKE '%' + @${paramName} + '%' ESCAPE '\'`);
ps.input(paramName, sql.VarChar);
});
// build safe SQL string, prepare statement
const sql = 'SELECT * FROM table WHERE ' + sqlConditions.join(' AND ');
ps.prepare(sql);
// connect, execute, return
ps.execute(escapedValues).then(result => {
res(result)
});
});
(免责声明:代码未经测试,因为我现在没有 SQL 服务器可用,但你明白了。)