当只有数字输入时,我需要准备查询吗?

Do I need to prepare my queries when there's number input only?

我有一些与 MySQL 关联的 JS 应用程序。我对 MySQL 的了解有限,但我知道我不能将原始用户输入直接发送到数据库,所以我使用 ?像下面的代码,根据npm js's preparing queries.

connection.query('SELECT * FROM users WHERE id = ?', [userId], function (error, results, fields) {
  if (error) throw error;
  // ...
});

connection.query('UPDATE users SET foo = ?, bar = ?, baz = ? WHERE id = ?', ['a', 'b', 'c', userId], function (error, results, fields) {
  if (error) throw error;
  // ...
});

具有这些准备好的查询的其他应用程序工作正常。 (不过我不确定这是否足够)

但我有这个应用程序,它从用户输入(没有键盘输入)中获取订单,并将它们发送到数据库。所以用户的唯一输入是数字。 任何人都可以访问我的应用程序,并且我授予用户 SELECT、INSERT、DELETE。 我也应该 sanitize/prepare 查询这种情况吗?如果是这样,我应该使用什么方法呢?上述方式不适用于这些查询。


//When the user puts items in the cart, bring the equivalent product info by joining them with product info table
router.post("/", (req, res) => {
    const bodyData = req.body;
    db.query(
        `INSERT INTO cart_table (item_id) VALUES(${bodyData.id})`, (err, rows) => {
            db.query(
                `SELECT cart_table.id as order_id, item_name, item_price, item_category, count, product_info.id as id FROM product_info JOIN cart_table on product_info.id = cart_table.item_id where item_id = ${bodyData.id}`,
                (err, orderedItem) => {
                    res.json({ 'orderedItem': orderedItem[0] });
                }
            );
        }
    );
});

// When user clicks an item, add the selected item or increase selected item's quantity in cart table
router.put("/", (req, res) => {
    const bodyData = req.body;
    db.query(
        `UPDATE cart_table SET count = ${bodyData.count ? parseInt(bodyData.count) : "count+1"
        } WHERE item_id = ${bodyData.item_id}`,
        (err, rows) => {
            res.send({ status: 200 });
        }
    );
});

// When the user orders, insert cart items to the order table and empty the cart table.
router.post("/", (req, res) => {
    const bodyData = req.body;
    const values = bodyData.map(({count, id}) => `(${count === null ? 1 : count}, ${id})`).join(",");
    db.query(
        `INSERT INTO order_table (count, item_id) VALUES${values}`,
        (err, rows) => {
            const order_id_array = bodyData.map(({ order_id }) => `id = ${order_id}`).join(" or ");
            db.query(
                `DELETE FROM cart_table`
            );
            res.send({ status: 200 });
        }
    );
});

Http 请求可以被欺骗。也就是说,如果表单可以从浏览器发送请求,那么任何人都可以使用 curl 或另一个 http 客户端来创建具有不同请求主体的 POST 请求。所以你不能指望 id 是一个整数。

只需使用准备好的查询并将值作为参数,您就不必怀疑它是否安全。会的。

当您将变量与 SQL 语句组合时,养成始终使用准备语句的习惯是值得的。它减少了出错的可能性。它使您的代码更具可读性。

请记住,在专业公司中,很多时候您编写代码,然后在数月或数年后,其他人将接管维护代码的责任。您应该使您的代码尽可能清晰,不要回避最佳实践或编写过于聪明的代码。必须支持您的代码的人会怀着尊重和感激的心情说出您的名字。