// : ! function popup(msg: string): string { return "<p class=\"popup\">" + msg + "</p>"; }
或诸如此类:
// : ! function getName(login: string): string { return "SELECT name FROM users WHERE login = \"" + login + "\""; }
从那时起,我们学会了使用更安全的方法。
广泛使用的工具包括模板引擎和参数绑定。 如今,很少会发现危险的字符串连接。
在本文中,我想通过注入代码来分享我对攻击的看法。 显然,它们仍然是JavaScript中的威胁。

为了理解原因,我们将不成功的示例之一分解为更简单的片段。 像这样:
function f(userInput: A): A { const firstCommand: A = ...; const secondCommand: A = ...; return firstCommand.concat(userInput.concat(secondCommand)); }
显然, 通过引入代码来进行攻击的根本原因是计算机的命令和用户输入之间没有区别! 因此,攻击者可以输入将被进一步处理为代码的数据。
当然,正如我所说,有针对这种攻击的著名防御措施。 代替这个:
"SELECT name FROM users WHERE login = \"" + login + "\""
最好写这样的东西:
query("SELECT name FROM users WHERE login = :login", {login})
因此,
SELECT name FROM users WHERE login =:login
命令显然与{login}
数据分开。 同时,内部机制可确保准备好数据以供SQL查询使用。 转义引号和注入恶意代码将失败。但是,Web应用程序的开发正在蓬勃发展。 不仅越来越多地发现了这一点:
{ paramA: "the value of the A parameter", paramB: "the value of the A parameter", }
而且这个:
{ paramA: "the value of the A parameter", paramB: {$in: [ "the value of the B parameter", "the value of the C parameter", ]}, }
这两个选项之间的显着区别是,参数值是包含命令的对象!
假设值是从
userInput
读取的: { paramA: userInput.paramA, paramB: {$in: [ userInput.paramB[0], userInput.paramB[1], ]}, }
无需担心用户提供恶意字符串。 一切都将以安全的方式处理。
问题在于参数值不仅可以是简单的值(例如
the value of the A parameter
,而且可以是命令,例如{$in: ["B", "C"]}
。 用户可以通过各种方式发送请求,在解密后获得一个对象(表单,JSON或XML),因此可以通过注入来攻击代码。假设
userInput.paramA
为{$empty: false}
。 然后查询如下: { paramA: {$empty: false}, paramB: {$in: [ userInput.paramB[0], userInput.paramB[1], ]}, }
再次证明,对于计算机而言,可靠的命令与不可靠的用户输入是无法区分的。 直到现在,它不是关于可靠和不可靠的字符串,而是关于可靠和不可靠的对象。
为避免此问题,您应始终编写命令,以使用户无法接收到它们。 除其他外,这可以使用React和Snabbdom-Signature中使用的方法(这是一个防止注入虚拟DOM的小库)来实现,即标记
Symbol
命令的每个对象,使其无法通过网络发送。我承认,我本人经常想到,由于没有SQL数据库,或者如果我使用虚拟DOM,则通过注入代码进行的攻击不会威胁到我。 我错了!
LOOKING.HOUSE-该项目在40个国家/地区收集了150多个窥镜。 您可以快速执行host,ping,traceroute和mtr命令。