SQL注入生成的查询有多安全?

Iva*_*van 1 sql sql-server sql-injection node.js express

我正在尝试创建一个可以使用多个单词的搜索栏,但我担心SQL注入.

我使用节点快递故宫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 => {

    })
});
Run Code Online (Sandbox Code Playgroud)

搜索something to search将导致此查询:

SELECT * FROM table 
WHERE 
    name like '%something%'
    and name like '%to%'
    and name like '%search%'
Run Code Online (Sandbox Code Playgroud)

我自己尝试了一些SQL注入,但它们似乎都没有用.


注意:我知道我们应该始终使用输入.它适用于一个单词,但我不知道如何使用输入多个单词.例如:

new sql.ConnectionPool(db).connect().then(pool => {
        return pool.request()
        .input('input', '%'+criteria+'%')
        .query(query)
    })
Run Code Online (Sandbox Code Playgroud)

Tom*_*lak 5

答案是:这不安全.您的代码也完全没有什么可以使它安全.不要通过将用户提供的数据连接/插入到语句中来构建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)
    });
});
Run Code Online (Sandbox Code Playgroud)

(免责声明:代码未经测试,因为我现在没有可用的SQL Server,但您明白了.)