节点mssql包似乎删除了部分查询,为什么会这样?

Node mssql package seems to drop part of query, why is this the case?

提问人:Biiblebrox 提问时间:8/7/2023 最后编辑:Biiblebrox 更新时间:8/8/2023 访问量:51

问:

我有一个与 Microsoft SQL Server 数据库交互的 Typescript 应用程序,并且我正在使用节点包与它交互(准确地说,我正在使用该包版本中的连接池,该版本允许连接多个数据库):mssql

import * as sql from "@cityssm/mssql-multi-pool";
import mssql from 'mssql';

我有以下创建动态查询的函数:

function assembleInOutQuery(from: string, to: string, accounts: string[]): string {
    const base = `--sql
    SELECT 
        beleg AS receiptId,
        "index",
        fhaben,
        text,
        konto AS account,
        amount AS value,
        date
    FROM dbo.Buchung 
    WHERE date >= '${from}' AND date <= '${to}' AND `
    let accString = `(konto = ${accounts.shift()}`
    for (const acc of accounts) {
        accString = accString + ` OR konto = ${acc}`
    }
    accString = accString + ")"
    return base + accString
}

此代码生成有效的查询,因为帐户始终包含至少一个值。但是,当通过节点包执行时,它会产生错误的输出,因为 中的第一个值总是被忽略。由于这个问题,我不得不将其更改为以下函数以产生预期的行为,但是这不是一个非常好的解决方案,因为它只是规避了问题而不是解决问题:mssqlaccounts

function assembleInOutQuery(from: string, to: string, accounts: string[]): string {
    let query = `SELECT 
        beleg AS receiptId,
        "index",
        fhaben,
        "text",
        konto AS account,
        amount AS "value",
        date
    FROM dbo.Buchung 
    WHERE (date >= '${from}' AND date <= '${to}') AND (konto = '0'`
    for (const acc of accounts) {
        query = `${query} OR konto = '${acc}'`
    }
    query = `${query});`
    return query
}

我必须包含该部分,因为查询的这一部分似乎已被删除。无论我是将这部分条件放在 WHERE 子句的前面,还是在检查日期之后,我约束的“konto”的第一个值总是被丢弃。有没有人能解释为什么会发生这种情况?(konto = '0'

我无法在 Microsoft SQL Server Management Studio 中重现此行为,因为查询完全按照编写方式执行。我检查了该函数的输出,并在 Microsoft SQL Server Management Studio 中执行了它,它在该工作室中运行没有问题并生成了预期的输出。当使用包在应用程序内部执行时,需要添加该部件才能使输出符合预期。mssql(konto = '0'

这可能是由于某些内部 SQL 注入保护阻止了查询的某些部分的执行?

如果有人对我如何改进上述方法以更好/更安全的方式生成动态查询有任何建议,我也将不胜感激。

谢谢

sql-server typescript sql-injection node-mssql

评论

0赞 Bagus Tesa 8/7/2023
你有没有看到那根绳子跑完后的样子?assembleInOutQuery
0赞 Biiblebrox 8/8/2023
@BagusTesa,我已经检查了该函数的输出,并在 SQL Server Managment Studio 中运行了它Microsoft其中原始查询完全按预期运行。只有在通过 mssql 包执行时,查询的某些部分似乎才会被忽略。
1赞 Panagiotis Kanavos 8/8/2023
你需要虚拟人的原因,是因为代码反复附加。如果没有虚拟子句,你最终会得到无效的子句。这与SQL注入保护无关konto = '0'OR konto = '${acc}'(OR konto ='blah' OR )
0赞 Biiblebrox 8/8/2023
@PanagiotisKanavos我更准确地编辑了这个问题,因为你的答案似乎不是我正在寻找的原因
0赞 Nick.Mc 8/8/2023
我建议你把问题分开,真正弄清楚是驱动程序在做这件事还是你的动态查询代码(我强烈怀疑这是你的dynamc查询代码)。例如,捕获动态生成的查询。现在硬编码并通过驱动程序提交它,我敢打赌它只是完全运行您提交的内容。

答: 暂无答案