【electron】【附排查清单】记录一次逆向过程中,fetch无法请求http的疑难杂症(net::ERR_BLOCKED_BY_CLIENT)

▒ 目录 ▒

    • [🛫 导读](#🛫 导读)
    • [1️⃣ Adblock等插件拦截](#1️⃣ Adblock等插件拦截)
    • [2️⃣ 【失败】Content-Security-Policy](#2️⃣ 【失败】Content-Security-Policy)
    • [3️⃣ 【失败】https vs http](#3️⃣ 【失败】https vs http)
      • [webPreferences & allowRunningInsecureContent](#webPreferences & allowRunningInsecureContent)
      • disable-features
    • [4️⃣ 【失败】检测fetch](#4️⃣ 【失败】检测fetch)
    • [5️⃣ 【失败】使用axios](#5️⃣ 【失败】使用axios)
    • [6️⃣ 【成功】require('http')](#6️⃣ 【成功】require('http'))
    • [7️⃣ 【完美解决】取消webRequest.onBeforeRequest](#7️⃣ 【完美解决】取消webRequest.onBeforeRequest)
    • [🛬 文章小结](#🛬 文章小结)
    • [📖 参考资料](#📖 参考资料)

🛫 导读

需求

逆向某electron应用,需要在其中执行http请求,结果返回错误net::ERR_BLOCKED_BY_CLIENT,为了解决该问题,又遇到无数其它问题,特此记录,以敬后效。

开发环境

版本号 描述
文章日期 2023-11-07
操作系统 Win10 - 22H2 19045.3570
示例工作目录 J:\_ALL\JOB\sw\_nginx\map-ys 执行json-server服务器

1️⃣ Adblock等插件拦截

搜索net::ERR_BLOCKED_BY_CLIENT,网上给出最多的结论就是各种插件拦截。可是小编用的软件,在dev tools中很明显没有加载任何插件。

也查了很多dev tools选项,修改后都没有解决问题。

2️⃣ 【失败】Content-Security-Policy

紧接着,查到的就是CORS(Cross-Origin Resource Sharing),也就是传说中的跨域问题。

启动服务器json-server

这里先说下,小编用的是json-server搭建的服务器,启动命令为:json-server -p 16010 db.json -s .
请求的js语句为fetch('http://127.0.0.1:16010/posts')

html中的meta字段

参考文章《MDN:CSP https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP》,我们可以知道,html中的meta会设置CSP,目标应用的内容如下:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' 'unsafe-eval' * blob: data:">

我们可以看出,它并不包含目标地址127.0.0.1:16010,于是执行了下述两种尝试:

  1. 将目标请求地址给它加上去,如下所示:
    <meta http-equiv="Content-Security-Policy" content="default-src 'self' 127.0.0.1 http://127.0.0.1:16010 127.0.0.1:16010 'unsafe-inline' 'unsafe-eval' '*' * https: http: blob: data:">
  2. 删除上述meta项。
    重新编译打包后测试,依然不能成功。

3️⃣ 【失败】https vs http

目标electron应用本身需要请求https,小编请求的是http,于是猜测应用对http做了限制。

于是增加了下面两次尝试,均以失败告终。

webPreferences & allowRunningInsecureContent

参考文章《electron配置允许跨域(前端解决方案) https://blog.csdn.net/sinat_39826352/article/details/108537797

将main.js中,所有的webPreferences对象增加下面属性。

javascript 复制代码
new BrowserWindow({
	webPreferences:{//网页功能的设置
	  // nodeIntegration: true,//是否集成node
	  // devTools:false,//是否开启 DevTools
	  webSecurity: false, //是否禁用同源策略(上线时删除此配置)
	  allowRunningInsecureContent: true,
	  // ...
	}
}

disable-features

添加命令行

javascript 复制代码
	//解决10.X版本跨域不成功问题(上线删除)
	app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors');

4️⃣ 【失败】检测fetch

fetch被魔改了

执行fetch,发现该命令如下,指向某函数,说明被魔改了。

正常的fetch应该如下所示:
ps: bh.fetch是小编备份的一个fetch代码,为native code

将fetch被赋值的地方注释掉,依然无法访问。

5️⃣ 【失败】使用axios

虽然上面修正了fetch,但是依然担心fetch有问题,于是乎,尝试用第三方库axios测试。

插入axios库

在本地任意找一份node_modules\axios\dist\browser\axios.cjs,将代码添加到目标进程的render中(如:app-bundle.js),这样我们就可以使用axios了,不过依然返回net::ERR_BLOCKED_BY_CLIENT错误。

6️⃣ 【成功】require('http')

从上面的各种尝试中,我们可以看出,通过浏览器js各种失败,那么通过nodejs呢。

require加载模块,发现可以加载http模块,使用下面代码请求,终于可以请求到数据了。
不过该方案太过繁琐,继续分析吧

js 复制代码
var http = require('http');
 
function post(action,send,callback){
	var options = {
	  hostname: '127.0.0.1',
	  port: 16010,
	  path: action,
	  method: 'POST',
	  headers: {
		'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'/* ,
		'Content-Length': send.length */
	  }
	};
	var req = http.request(options, function (res) {
		// console.log('STATUS: ' + res.statusCode);  
		// console.log('HEADERS: ' + JSON.stringify(res.headers));  
        // 定义了一个post变量,用于暂存请求体的信息
		var body="";
		res.setEncoding('utf8');
        // 通过res的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
		res.on('data', function (chunk) {
			// console.log('BODY: ' + chunk);
            body += chunk;
		});
        // 在res的end事件触发后,通过JSON.parse将post解析为真正的POST请求格式,然后调用传递过来的回调函数处理数据
		res.on('end', function(){
			// console.log("body = "+body);
			var json = JSON.parse(body);
			callback(json);
		});
	});
	req.on('error', function (e) {
	  console.log('problem with request: ' + e.message);
	});
	req.write(send);
	req.end();
}
post('/posts', '{"id":3}', ()=>{})

7️⃣ 【完美解决】取消webRequest.onBeforeRequest

还是从httphttps思考,为什么唯独http无法访问,难道是electron中有代码拦截了http请求?

  • 使用其它electron应用,http可以正常访问。更加确信猜想。
  • 在electron应用的主进程代码中,搜索http关键字,找到如下代码,注释掉居然真的可以访问了。
js 复制代码
function blockHttpRequests() {
	// 注释掉
	return;
	var e;
	i()
	  .session.fromPartition(
	    (e = g.windowOptions.webPreferences.partition) !== null &&
	      e !== void 0
	      ? e
	      : ""
	  )
	  .webRequest.onBeforeRequest({ urls: ["http://*/*"] }, (e, t) => {
	    t({
	      cancel:
	        e.webContents && e.webContents.getURL().startsWith("file://"),
	    });
	  });
 }

🛬 文章小结

文章中的每一次尝试都有大量的知识点,每次都查了大量的文章。

electron很复杂,尤其是像本次遇到的问题,可以通过多种方式实现,所以我们需要一次次的尝试,排除错误答案,最终找到正确的解决方案。

📖 参考资料

相关推荐
会飞的鱼先生20 分钟前
javascript中Cookie、BOM、DOM的使用
前端·javascript·chrome
一抓掉一大把1 小时前
MiniExcel模板填充Excel导出
开发语言·javascript·ecmascript
Jiaberrr1 小时前
uniapp 安卓 APP 后台持续运行(保活)的尝试办法
android·前端·javascript·uni-app·app·保活
不老刘1 小时前
uniapp+vue3实现CK通信协议(基于jjc-tcpTools)
前端·javascript·uni-app
vanora11112 小时前
Vue在线预览excel、word、ppt等格式数据。
前端·javascript·vue.js
溪饱鱼2 小时前
React源码阅读-fiber核心构建原理
前端·javascript·react.js
xiaogg36783 小时前
网站首页菜单顶部下拉上下布局以及可关闭标签页实现vue+elementui
javascript·vue.js·elementui
胡gh3 小时前
JS面向对象程序设计(OOP)与原型机制,到底是如何一步步走向实用的
javascript
猫头虎3 小时前
[特殊字符]解决 “IDEA 登录失败。不支持早于 14.0 的 GitLab 版本” 问题的几种方法
java·ide·网络协议·http·https·gitlab·intellij-idea
有梦想的攻城狮3 小时前
从0开始学vue:pnpm怎么安装
前端·javascript·vue.js