electron.js是一个运行时框架,它在设计之初就结合了当今最好的Web技术,核心是使用HTML、CSS、JavaScript构建跨平台的桌面应用。
作为一个跨平台的“集成框架”,它能轻松和多平台兼容。而所谓的“集成框架”也就是它将“Chromium”和“Node.js”很好的集成,并明确分工。
Electron负责硬件部分,“Chromium”和“Node.js”负责界面与逻辑,共同构成了成本低廉却高效的解决方案。
比如流行的VS Code,WhatsApp,WordPress等应用都是使用了electron框架来构建跨平台开发
特点如下:
1.摆脱了不同浏览器之间的差异和版本的限制
2.基于Node.js,有活跃的贡献者社区管理和第三方丰富的包支持
3.可以开发跨平台的桌面应用。只需要写一份代码,可以构建出三个平台的应用程序
1.摆脱浏览器的沙盒机制,可以访问操作系统层面的东西。
2.跨平台,前端人员能在不学习其他语言的情况下,快速构建跨平台,带来统一的用户体验
1.打包的APP太大,简单的应用多大几十兆
2.引入Node.js的API具备接触系统底层的能力,控制不当易引发安全风险,直接从对浏览器的影响提升为对系统的影响。
回顾以前的web开发,无论是HTML、CSS还是Java,都是运行在浏览器沙盒中的,无法越过浏览器的权限访问系统本身的资源,代码的能力被限制在了浏览器中。浏览器之所以这么做,为了安全的考虑。设想一下,使用浏览器的时候,会打开各样不同的网站,如果代码有能力访问并操作本地操作系统的资源,那将是可怕的事情。
但开发桌面应用程序,如果无法访问到本地的资源肯定是不行的。
而使用Electron架构的应用程序分成三个基础模块:主进程、渲染进程、进程间通信;
Electron将nodejs引入并作为主进程,可以访问和操作本地资源,使用原本在浏览器中不提供的高级API。同时主进程负责管理整个应用程序的生命周期以及所有渲染进程的创建和销毁。 在主进程中运行的脚本通过创建web页面来展示用户界面。它内置了完整的Node.js API,主要用于打开对话框以及创建渲染进程。此外,主进程还负责处理与其他操作系统交互、启动和退出应用程序。
渲染进程是应用程序中的浏览器窗口。与主进程不同,Electron可以有许多渲染进程,且每个进程都是独立的。由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个Electron 中的 web 页面运行在它自己的渲染进程中。正是因为每个渲染进程都是独立的,因此一个崩溃不会影响另外一个,这些要归功于Chromium的多进程架构。
在Electron项目开发中,resource\目录下的代码文件默认是明文可见的,如果没有对项目封装打包,就可以进行白盒审计,发现更多的问题,而如果只是使用npm执行asar对app.asar文件(resources目录里)合并归档,则会很容易被解包。而对Electron源码保护方案讨论由来已久。官方并没有打算提供解决方案。作者们认为,无论用什么形式去加密打包文件,密钥总归是需要放在包里。
因为asar只是对源码的合并归档,并不提供加密之类的操作。 通过asar e的命令,可以很简单地进行解压和得到源码。
//1.安装npm
//2.全局安装 asar
npm install asar -g
//3.解包
用asar命令解包:asar e app.asar app
由于electron框架开发出的应用,不只是一个浏览器。在Web浏览器中,基于安全策略考虑,web页面通常是在一个沙盒环境中运行的,不被允许去接触原生的资源。
然而在Electron中,允许页面(渲染进程)调用Node.js的API,原生具备操控系统底层的能力,所以页面可以与操作系统底层进行交互,如执行系统命令,那么DOM Based-XSS在electron就会提升为RCE,直接从对浏览器的影响提升为对系统的影响。
Electron是基于Chromium的内容模块实现的,但是从本质上来说它就不是一个浏览器。它可以给开发人员提供非常强大的功能,而且Electron的灵活性也可以有助于构建复杂的桌面应用程序。
所以,实际上Electron整合了Node.js,所以JavaScript可以直接访问操作系统并完全利用原生的桌面机制。
如:假设在使用electron开发的应用中发现某处DOM based XSS,那么直接就可以提升为RCE,如下
//要利用electron的xss,只需要引入nodejs自带的命令执行模块child_process即可
//Electron框架,Dom XSS->RCE,比如弹计算器
<img src="" onerror="require('child_process').exec('calc.exe')">
<img src=1 onerror=require('child_process').exec('calc.exe')>
<img/src="1"/onerror=eval(`require("child_process").exec("calc.exe");`);>
<img src=# onerror="require('child_process').exec('calc.exe',null);">
<img src=# onerror="require('electron').shell.openExternal('file:C:/Windows/System32/calc.exe')">
应用开发使用了Electron框架,且nodeIntegration默认值为True,说明开启了Node.js扩展,那就能够调用node.js模块从XSS到RCE, 只要不进行严格的过滤,就会造成rce
<img src=1 onerror="require('child_process').exec('calc.exe')">
注意:
Electron中使用了一个标记nodeIntegration用来控制页面对node的API的访问,只有nodeIntegration为true的时候,才可以使用如require,process这样的node API去访问系统底层资源。
1. 使用 DOMPurify 过滤 XSS Payload,或者 React JSX;
2. 谨慎开启nodeIntegration参数,如果开启一定要对用户可控输入点做好充分的过滤,如特殊字符实体编码。
可参考:https://www.electronjs.org/docs/latest/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content
3.可使用webpack类似的前端构建工具,对项目代码进行加密混淆
为了安全性,官方将 electron@v12.0.0 的 contextIsolation 的默认值改了。所以今后要在渲染进程里调用 require 的话,还需要加上 contextIsolation: false 。
防御Electron开发程序的逆向,从目前看方案比较有限,混淆后效果也不佳,和传统的二进制逆向相比,逆向难度不会太大。所以,electron比较适合拥抱开源生态的开发者,不适合个人及企业对保护源代码,保护自身的专利技术及知识产权的应用开发。
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/