给 Cobra 增加 Node.js 源代码扫描规则

栏目: Node.js · 发布时间: 6年前

内容简介:但是 Cobra 目前基本没有专门针对 Node.js 的源代码扫描规则。以我上一篇文章分析 CVE-2017-16082 时使用的示例漏洞代码为例:这个代码中存在着明显的 SQL 语句拼接,有 SQL 注入风险,但是使用 Cobra 扫描会得到:

Cobra 是一款 源代码安全审计 工具,支持检测多种开发语言源代码中的 大部分显著 的安全问题和漏洞。

但是 Cobra 目前基本没有专门针对 Node.js 的源代码扫描规则。以我上一篇文章分析 CVE-2017-16082 时使用的示例漏洞代码为例:

const app = new Koa()
const client = new Client({
    user: "f1sh",
    password: "f1sh",
    database: "postgres",
    host: "127.0.0.1",
    port: 5432
})
client.connect()

app.use(async ctx => {
    ctx.response.type = 'html'

    let id = ctx.request.query.id || 1
    let sql = `SELECT * FROM "user" WHERE "id" = ${id}`
    const res = await client.query(sql)

    ctx.body = `<html>
                    <body>
                        <table>
                            <tr><th>id</th><td>${res.rows[0].id}</td></tr>
                            <tr><th>name</th><td>${res.rows[0].name}</td></tr>
                            <tr><th>score</th><td>${res.rows[0].score}</td></tr>
                        </table>
                    </body>
                </html>`
})

app.listen(3000)

这个代码中存在着明显的 SQL 语句拼接,有 SQL 注入风险,但是使用 Cobra 扫描会得到:

给 Cobra 增加 Node.js 源代码扫描规则

查看 Cobra 的 rules 文件夹下的扫描规则也可以发现,当前的 Cobra 只支持扫描 javaphp 中的 SQL 注入漏洞,而没有 Node.js 的对应规则。

那么我们何不自己动手添加呢?编写 Cobra 的扫描规则并不难,在 官方文档 中给了非常详细的说明和示例。

根据文档的说明和参考当前存在的规则,编写一个扫描 Node.js 中拼接 SQL 语句的规则如下:

<?xml version="1.0" encoding="UTF-8"?>

<cobra document="https://github.com/WhaleShark-Team/cobra">
    <name value="拼接SQL注入"/>
    <language value="javascript"/>
    <match mode="regex-only-match"><![CDATA[(['"`]\s*(select|SELECT|insert|INSERT|update|UPDATE|delete|DETELE)[^;]*?(\$\{(.+?)\}|['"`]\s*\+\s*[$\w]+))]]></match>
    <level value="8"/>
    <test>
        <case assert="true"><![CDATA[let sql = `SELECT * FROM "user" WHERE "id" = ${id}`]]></case>
        <case assert="false"><![CDATA[let sql = 'SELECT * FROM "user" WHERE "id" = 1']]></case>
        <case assert="true"><![CDATA[let sql = 'SELECT * FROM "user" WHERE "id" = ' + id]]></case>
        <case assert="true"><![CDATA[const result = await req.db.run(`UPDATE notes SET pinned = ${req.body.value}::boolean WHERE id = ${req.params.noteId}`);]]></case>
    </test>
    <solution>
        ## 安全风险
        拼接SQL语句存在SQL注入风险

        ## 修复方案
        - 已不再使用的功能,直接做下线处理
        - 引入安全组件
        - 代码层修复:尽量不要拼接SQL语句。如必要,需对用户可控的参数进行严格过滤
    </solution>
    <status value="on"/>
    <author name="f1sh" email="f1shunicorns@gmail.com"/>
</cobra>

规则的核心就是 <match> 标签中的正则表达式。

这个正则表达式分成三个部分,第一个部分

['"`]\s*(select|SELECT|insert|INSERT|update|UPDATE|delete|DETELE)

匹配的是 SQL 语句开头的关键字;第二个部分

[^;]*?

匹配的是 SQL 语句结束前的部分;第三个部分

(\$\{(.+?)\}|['"`]\s*\+\s*[$\w]+)

我匹配了 js 中两种字符串拼接的情况:

let sql = `SELECT * FROM "user" WHERE "id" = ${id}`
let sql = 'SELECT * FROM "user" WHERE "id" = ' + id

另外这里需要注意的地方是 Cobra 并没有使用 python 的 re 库来解析 <match> 中的正则表达式,而是使用的 grep 命令,并且没有使用 -i 参数,所以关键字的大小写敏感,得把关键字大小写的情况都写进去(或者手动给 grep 加上 -i 参数,在 cobra/engine.py 第317行)。

保存规则为 CVI-160005.xml ,再一次扫描之前的示例代码得:

给 Cobra 增加 Node.js 源代码扫描规则

这样就成功地给 Cobra 加上了 Node.js 源代码 SQL 注入风险扫描的规则。

我们还知道 CVE-2017-16082 这个漏洞的成因其实是传入 Function 这个类的最后一个参数可控,造成了代码注入,那么我们还可以写个规则来扫描 Function 代码注入风险:

<?xml version="1.0" encoding="UTF-8"?>

<cobra document="https://github.com/WhaleShark-Team/cobra">
    <name value="远程代码执行"/>
    <language value="javascript"/>
    <match mode="regex-only-match"><![CDATA[([^\w]Function\(.*?([$\w]+|(['"`].*?(\$\{(.+?)\}|['"`]\s*\+\s*[$\w]+).*?))\s*\))]]></match>
    <level value="10"/>
    <test>
        <case assert="true"><![CDATA[this.RowCtor = Function('parsers', 'rowData', ctorBody)]]></case>
        <case assert="true"><![CDATA[this.RowCtor = Function('parsers', 'rowData', 'var ' + ctorBody + ';')]]></case>
        <case assert="true"><![CDATA[this.RowCtor = Function('parsers', 'rowData', `var ${ctorBody};`)]]></case>
        <case assert="false"><![CDATA[var sum = new Function('a', 'b', 'return a + b');]]></case>
    </test>
    <solution>
        ## 安全风险
        代码注入(Code Injection) - Funtion()
        没有对用户输入的参数进行足够的过滤,可能导致攻击者传入的恶意代码执行。
        因此危险函数应该尽量避免在开发中使用。

        ## 修复方案
        不要把用户可控的参数带入 Function 的最后一个参数中,或者进行安全的过滤后再带入。
    </solution>
    <status value="on"/>
    <author name="f1sh" email="f1shunicorns@gmail.com"/>
</cobra>

这个规则匹配了 Function 类最后一个参数可控的三种情况:

this.RowCtor = Function('parsers', 'rowData', ctorBody)
this.RowCtor = Function('parsers', 'rowData', 'var ' + ctorBody + ';')
this.RowCtor = Function('parsers', 'rowData', `var ${ctorBody};`)

规则写好后,保存为 CVI-180002.xml ,再次扫描。但是这时会发现并没有扫描出 Function 代码注入风险,为什么呢?

我们运行 Cobra 时加上 -d 参数可以查看扫描时的 debug 信息:

给 Cobra 增加 Node.js 源代码扫描规则

给 Cobra 增加 Node.js 源代码扫描规则

可以看到其实是成功扫描出了 result.js 中存在漏洞的那一行代码了的,但是输出了:

[13:37:39] [DEBUG] Not vulnerability: Special File(特殊文件)

也就是说被当成了特殊文件,所以没有算作漏洞。

怎么样才会被当成特殊文件呢,在 Cobra 的源代码目录里全局搜索一下关键字 Special File

给 Cobra 增加 Node.js 源代码扫描规则

跟进 cobra/engine.py 第588行:

if self.is_special_file():
    logger.debug("[RET] Special File")
    return False, 'Special File(特殊文件)'

跟进 is_special_file() 函数,在同文件 493 行:

def is_special_file(self):
    """
    Is special file
    :method: According to the file name to determine whether the special file
    :return: boolean
    """
    special_paths = [
        '/node_modules/',
        '/bower_components/',
        '.min.js',
        '.log',
        '.log.',
        'nohup.out',
    ]
    for path in special_paths:
        if path in self.file_path:
            return True
    return False

可以看到在这个函数中维护了一个 special_paths ,当文件存在于 special_paths 中时就不会被当作漏洞。而我们扫描出存在漏洞的 result.js 正存在于 /node_modules/ 目录下,所以就没有被当作漏洞了。我们尝试把 /node_modules/special_paths 注释掉,然后再次扫描:

给 Cobra 增加 Node.js 源代码扫描规则

就可以正常扫描出漏洞风险了。

以这两条规则为例,我们就可以很轻易的写出一份针对 Node.js 各种漏洞风险的扫描规则库。

当然这两条规则还非常简陋,仅仅考虑了变量的简单的拼接和传入,并没有去检测拼接或传入进来的变量是否可控或经过了过滤。但 Cobra 最强大的一点就是:

对于OWASP Top 10的漏洞,Cobra通过预先梳理能造成危害的函数,并定位代码中所有出现该危害函数的地方,继而基于Lex(Lexical Analyzer Generator, 词法分析生成器)和Yacc(Yet Another Compiler-Compiler, 编译器代码生成器)将对应源代码解析为AST(Abstract Syntax Tree, 抽象语法树),分析危害函数的入参是否可控来判断是否存在漏洞(目前仅接入了PHP-AST,其它语言AST接入中)

我们可以参考 Cobra 的 PHP-AST ,给 Node.js 也加上 AST ,这样就可以更准确更灵活地扫描源代码中的漏洞。(挖坑待填)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective Java

Effective Java

Joshua Bloch / Addison-Wesley Professional / 2018-1-6 / USD 54.99

The Definitive Guide to Java Platform Best Practices—Updated for Java 9 Java has changed dramatically since the previous edition of Effective Java was published shortly after the release of Jav......一起来看看 《Effective Java》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具