Open mytac opened 5 years ago
不知道大家有没有这样的体验,当你专心浏览网站内容的时候,会从右下角弹出小广告,当你点击关闭的时候,又会跳转到另外的链接,你以为是网站搞的鬼,但你尝试去联系管理员时,人家表示不背这个锅。其实这背后是你的网络运营商在借刀杀人~
市面上常见的运营商劫持主要是http劫持,https劫持和dns劫持。我们经常看到的右下角弹小广告的一般是http劫持,如果将http转为https可以减少被运营商劫持的机率,但也可能会被伪造证书,仍然会被劫持。所以我们需要在自己的程序中设置一个监听器来监控dom中劫持插入的脚本。
需要在运营商插入非法代码之前监听dom变动,以下的例子只检查<script>标签。
<script>
主要使用html5的一个特性MutationObserver来观察dom变动,注意兼容性,如果你不打算兼容ie浏览器,MutationObserver是最好的选择。
MutationObserver
const observer = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; const isSupportObserver = !!observer if (isSupportObserver) { console.info('The preventor is running...') new observer((records) => { // ....这里处理dom变动 }).observe(watchNode, { childList: true, attributes: true }) } else { console.error('Your platform is not supported with "window.MutationObserver",please update.') }
经过上面的步骤,我们得到了网页中所有的<script>,之后筛选得到运营商注入的脚本信息,进行下一步操作。(你可以设置白名单,根据白名单进行过滤,设置白名单的过程这里不具体展开了,详见文章后面的完整代码。)
records.forEach(record => { const addedNodes = Array.from(record.addedNodes) addedNodes.forEach((node) => { if (node.tagName && ~filterTagList.indexOf(node.tagName.toLowerCase())) { const isInWhiteList = whiteRegList.some((reg) => reg.test(node.src)) if (!isInWhiteList) { badInjections.push({ badNode: node, badSource: node.src }) } } }) })
我们在上一步得到的运营商注入的非法脚本,需要进行拦截和处理,最后发给运营商或举报到工信部。(注意这里,在head头部同步插入的脚本无法被监听到)。
badInjections.forEach(({ badNode, badSource }) => { badNode.remove(); // 移除非法注入节点 console.warn(`The source "${badSource}" is invalid,removed it already.`) })
class HijackPreventor { constructor(watchNode = Array.from(document.getElementsByTagName('body'))[0],report=()=>{}) { this.whiteList = [] this.whiteRegList = [] this.filterTagList = ['script'] this.report = report this.setObserver(watchNode) } /** * 设置域名白名单 * @param {Array|String} list */ setWhilteList(item) { if (item instanceof Array) { this.whiteList = item } else if (typeof item === 'string') { this.whiteList.push(item) } else { console.error('[HijackPreventor]: Please set an Array or String type parameter to "setWhilteList" ') return; } this.whiteRegList = this.whiteList.map(wl => new RegExp('/.+?\/\/' + wl + '|\/\/' + wl + '|.+?\.' + wl + '|^' + wl) ) } /** * 挂载dom监听器 * @param {Node} node */ setObserver(watchNode) { const observer = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; const isSupportObserver = !!observer if (isSupportObserver) { console.info('[HijackPreventor]: The preventor is running...') new observer((records) => { this.filterSafeScript(records) }).observe(watchNode, { childList: true, attributes: true }) } else { console.error('[HijackPreventor]: Your platform is not supported with "window.MutationObserver",please update.') } } /** * 获取非法注入 * @param {Node} records */ filterSafeScript(records) { const { filterTagList, whiteRegList } = this let badInjections = [] records.forEach(record => { const addedNodes = Array.from(record.addedNodes) addedNodes.forEach((node) => { if (node.tagName && ~filterTagList.indexOf(node.tagName.toLowerCase())) { const isInWhiteList = whiteRegList.some((reg) => reg.test(node.src)) if (!isInWhiteList) { badInjections.push({ badNode: node, badSource: node.src }) } } }) }) this.handleBadInjections(badInjections) } /** * 处理非法注入 * @param {Array} badInjections */ handleBadInjections(badInjections) { badInjections.forEach(({ badNode, badSource }) => { badNode.remove(); // 移除非法注入节点 console.warn(`[HijackPreventor]: The source "${badSource}" is invalid,removed it already.`) }) this.report(badInjections) } /** * 模拟插入script,用来测试 * @param {Node} appendNode */ mockHijack(appendNode = document.getElementsByTagName('body')[0]) { const node = document.createElement("script"); node.src = 'https://cdn.bootcss.com/zepto/1.0rc1/zepto.min.js' appendNode.appendChild(node) } }
按下图方法投诉到工信部,一步到位!
不知道大家有没有这样的体验,当你专心浏览网站内容的时候,会从右下角弹出小广告,当你点击关闭的时候,又会跳转到另外的链接,你以为是网站搞的鬼,但你尝试去联系管理员时,人家表示不背这个锅。其实这背后是你的网络运营商在借刀杀人~
市面上常见的运营商劫持主要是http劫持,https劫持和dns劫持。我们经常看到的右下角弹小广告的一般是http劫持,如果将http转为https可以减少被运营商劫持的机率,但也可能会被伪造证书,仍然会被劫持。所以我们需要在自己的程序中设置一个监听器来监控dom中劫持插入的脚本。
思路
需要在运营商插入非法代码之前监听dom变动,以下的例子只检查
<script>
标签。step1.挂载dom监听器
主要使用html5的一个特性
MutationObserver
来观察dom变动,注意兼容性,如果你不打算兼容ie浏览器,MutationObserver
是最好的选择。step2.处理dom变动,进行白名单筛选
经过上面的步骤,我们得到了网页中所有的
<script>
,之后筛选得到运营商注入的脚本信息,进行下一步操作。(你可以设置白名单,根据白名单进行过滤,设置白名单的过程这里不具体展开了,详见文章后面的完整代码。)step3.处理运营商非法注入
我们在上一步得到的运营商注入的非法脚本,需要进行拦截和处理,最后发给运营商或举报到工信部。(注意这里,在head头部同步插入的脚本无法被监听到)。
完整代码
举报方法
按下图方法投诉到工信部,一步到位!
参考链接