ZBLOG

blob请求的响应是JS代码,如何动态HOOK这份JS代码中的fetch请求,我只能在上游服务器的HTML响应中进行注入。如何对blob也生效

要在上游服务器的HTML响应中注入代码,以动态HOOK通过blob: URL返回的JS代码中的fetch请求,需要分步骤解决几个关键问题。以下是详细方案:


1. 核心思路

由于blob: URL生成的JS代码在独立上下文中执行,直接通过HTML注入的脚本无法直接修改其行为。需通过以下方式间接拦截:

  • 重写原生API:在全局作用域中劫持fetch,确保后续动态加载的JS代码(包括blob:中的代码)都使用被Hook的版本。
  • 监听DOM变化:通过MutationObserver捕获动态创建的<script>标签或blob:资源加载事件。

2. 具体实现步骤

(1) 在HTML注入阶段重写全局API

<script>
// 保存原生fetch引用
const nativeFetch = window.fetch;

// 劫持fetch
window.fetch = function(...args) {
    console.log('Intercepted fetch:', args);
    // 在此可修改请求参数或响应
    return nativeFetch.apply(this, args)
        .then(response => {
            // 可选:修改响应内容
            return response;
        });
};

// 劫持XMLHttpRequest(如需覆盖XHR请求)
const nativeXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(...args) {
    console.log('Intercepted XHR:', args);
    nativeXHROpen.apply(this, args);
};
</script>

(2) 监听动态脚本加载

若目标JS代码通过<script>标签动态插入(例如通过blob: URL),需监听DOM变化:

const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
            if (node.tagName === 'SCRIPT' && node.src.startsWith('blob:')) {
                // 拦截blob脚本的内容(需进一步处理)
                interceptBlobScript(node);
            }
        });
    });
});

observer.observe(document.documentElement, {
    childList: true,
    subtree: true
});

function interceptBlobScript(scriptNode) {
    // 方案1:阻止原始脚本执行,替换为自定义逻辑
    scriptNode.remove();
    
    // 方案2:获取blob内容并修改(需借助URL.createObjectURL)
    fetch(scriptNode.src)
        .then(res => res.text())
        .then(jsCode => {
            const modifiedCode = jsCode.replace(/fetch\(/g, 'window.hookedFetch(');
            const blob = new Blob([modifiedCode], { type: 'application/javascript' });
            const newScript = document.createElement('script');
            newScript.src = URL.createObjectURL(blob);
            document.body.appendChild(newScript);
        });
}

(3) Service Worker全局拦截(高级方案)

若条件允许,可通过Service Worker拦截所有网络请求(包括blob:上下文中的请求):

// 注册Service Worker(需HTTPS环境)
navigator.serviceWorker.register('/sw.js').then(() => {
    console.log('SW registered');
});

// sw.js文件内容
self.addEventListener('fetch', (event) => {
    if (event.request.url.startsWith('https://api.example.com')) {
        event.respondWith(
            fetch(event.request)
                .then(response => modifyResponse(response))
    }
});

注意:Service Worker对blob:请求的拦截能力有限,通常仅适用于同源HTTP(S)请求。


3. 限制与注意事项

  1. CSP限制:若目标网站设置了严格的Content Security Policy,可能阻止内联脚本或动态代码执行。
    • *绕过方案*:尝试匹配CSP的非ce哈希值或通过服务器代理响应。
  2. 沙盒环境:某些框架(如Chrome扩展)会隔离执行环境,需使用特定API通信。
  3. 性能影响:频繁Hook可能引发性能问题,建议仅在调试时启用。

4. 验证是否生效

在浏览器开发者工具中检查:

  • window.fetch.toString()确认是否被重写。
  • Network面板观察请求是否被拦截。

如果仍有未拦截的请求,可能是由于JS代码使用了闭包内的原生fetch副本。此时需结合AST解析或更复杂的运行时注入技术(如Proxy链)。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23199

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?