前端开发如何防止逆向以及对策

Posted on

前端开发分析代码的途径最简单不过了,第一个途径是查看网页源代码,第二个途径是打开开发者工具审查元素。

防止查看源代码

现在网站的基本对策是禁用用户右键选项菜单来避免查看源代码。首先,源代码肯定是能查看到的。采取的措施也只不过是掩耳盗铃而已。解决对策也有很多,我随便说几个。

第一,针对Chrome浏览器,我们可以直接在地址栏里输入 view-source:https://www.google.com/ 这种方式来查看源代码。第二,我们可以使用其他工具,例如curl, wget来直接下载源代码。

这种是很初级的防范对策。

防止审查元素

现代化的前端开发,都是基于JS来渲染页面元素的,有时候我们查看源代码也只是看到了JS文件的引用。没有太大意义,所以需要浏览器渲染之后查看真正的DOM元素才有意义。这时候如何禁止审查元素就是另外一种对策了。 现在用来检测打开开发者工具主要是通过判断console.log的执行,因为不打开开发者工具的话console.log是不会执行的。所以有些网站就可以利用这个来阻止用户打开开发者工具审查元素和Debug代码。 下面给出一个例子来:

<script>
let el = new Image();
Object.defineProperty(el,'id',{get: function(){window.location.href="http://www.bimibimi.tv"}});
console.log(el);
</script>

这是一个非常巧妙的例子,当执行console.log输出Image元素的时候,比如会访问id属性,从而触发后面的重定向URL代码。所以表现就是用户试图打开开发者面板就会被自动定位到首页。

要破解这个的话,只能在页面执行之前注入代码修改Image函数的使用:

window.Image = function() {};
Object.defineProperty(window, "Image", { writable: false} );

通过注入上面的代码,来规避自动跳转到首页。如何注入呢? 就需要利用Chrome的扩展功能,详细代码请参照bimibimi-hack

总结

前端代码逆向和反逆向,永远没有银弹。只能说是提高逆向的门槛,但想完全防止是不可能的。如果自己编译一个浏览器,修改浏览器的默认行为的话,就没有不能调试的网站。

引用

Find out whether Chrome console is open

Source code of bimibimi.tv

tagged: frontend

前端部署之CDN的那些事情

Posted on

现在的前端开发主流是PWA,简而言之就是像App一样使用。基于PWA技术可以离线访问,并且可以添加程序到菜单里。离线技术使用的是比较成熟的Service Workers。但是配合CDN就有很多不得不注意的事情。

CDN部署静态资源

现代化前端开发主要是把CSS,JS,图片等静态资源放在CDN上有效提高载入速度。把静态HTML文件放在服务器上,有利于更新网站最新状态,例如进入维护状态,直接把静态HTML文件替换为维护页面即可。

同源策略问题

正常情况下,资源文件和主网站不在同一个域名下,例如主网站是icehoney.me,资源网站是static.icehoney.me。当然了,资源文件使用GET方法浏览器自动载入,没有任何问题。但是注册Service Worker的JS文件是不能放在CDN上的,因为这是官方的规定。个人理解是出于安全因素的考虑。所以我们在主服务器上不仅要放静态的HTML文件,还要放一个serive-worker.js文件。

SVG symbol的使用问题

现在前端的开发针对很多小图标,都是采用SVG的方式来引用。其中SVG symbol特别好用,可以在页面里嵌入一个inline的SVG,然后在其他对方使用<use>标签来引用。但是对于放在CDN上的SVG文件,不能直接使用下面的形式:

<use xlink:href="https://static.icehoney.me/icon.svg#china" />

如果引用CDN的SVG浏览器会报错,解决方案是使用svg-inline-loader,手动在文档里面注入SVG文件。document.body.insertAdjacentHTML 方法可以注入inline的SVG。

Workbox配置

首先,PWA项目的路由都是由前端来处理,所以我们需要使用navigateFallback保证不管导航到哪个路由都能映射到缓存的HTML文件。然后是使用runtimeCaching配置缓存服务器请求。

总结

由于Service Workers的导入使得CDN部署变得有些麻烦,不过这些问题好在都能找到解决方案。还有一点是Chrome的Network面板里的offline模式不能测试Service Workers的离线。需要自己手动拔网线才能测试。

引用

Is it possible to serve service workers from CDN/remote origin?

Workbox webpack Plugins

tagged: frontend

iOS12下Safari浏览器的BUG

Posted on

新时代的前端开发遇上新时代的IE6, 没错我说的就是苹果的Safari浏览器,当年谷歌抛弃WebKit内核自立门户真是正确的选择。Chrome有很好的bug反馈机制,而Safari要想反馈bug首先得成为苹果的付费开发者。

事件穿透

当我们遇到一个特殊需求,有两个绝对定位的DIV(position:absolute)。如果指定了z-index必然会有上下的层级关系,值大的在上面,值小的在下面。但是我们需要上面的DIV不接受任何的事件,由下层的DIV捕获事件并处理。这时候可以使用一个神奇的CSSpointer-events: none;来解决。只要给上层DIV指定了这个CSS属性,上层DIV就不会接收任何事件,相对的下层就可以收到所有事件的响应。

测试用Demo

为此,我专门在codepen写了一个demo。当然,这个CSS属性主流浏览器都已经支持了。但是当上层DIV里包含了一个iframe的时候,iOS12下的Safari表现就变得奇怪了,demo中,我在Back DIV里监听了touchstartclick事件,正常情况下两个事件都会触发,但是在有iframe的时候,safari只会触发touchstart事件。

解决方案

既然少触发了一个事件,那我们的解决方案就是模拟点击事件,不过代码中必须通过User-Agent限制执行的范围,否则造成其他浏览器双击就不好了。模拟事件很简单,自己新建一个事件,然后在指定的DOM上dispatchEvent就好了。但是针对input输入框,即使模拟了click事件也不能出发iOS打开键盘激活输入,解决办法就是如果在input元素触发的touchstart事件,就执行input.focus()。 这样就可以激活输入的键盘了,不过要注意的是只有touchstart可以触发,测试发现touchend并不能触发。

总结

iOS下的Safari浏览器有很多BUG,经常找BUG的我也算是有点经验。最重要的方法就是排除法,删除多余的DOM。缩小影响因子,最后确定原因。

引用

The stacking context

Creating and triggering events

tagged: safari