从 0 开始入门 Chrome Ext 安全(一) -- 了解一个 Chrome Ext

做者:LoRexxar'@知道创宇404实验室
时间:2019年11月21日
原文:https://paper.seebug.org/1082/css

在2019年初,微软正式选择了Chromium做为默认浏览器,并放弃edge的发展。并在19年4月8日,Edge正式放出了基于Chromium开发的Edge Dev浏览器,并提供了兼容Chrome Ext的配套插件管理。再加上国内的大小国产浏览器大多都是基于Chromium开发的,Chrome的插件体系愈来愈影响着广大的人群。html

在这种背景下,Chrome Ext的安全问题也应该受到应有的关注,《从0开始入门Chrome Ext安全》就会从最基础的插件开发开始,逐步研究插件自己的恶意安全问题,恶意网页如何利用插件漏洞攻击浏览器等各类视角下的安全问题。chrome

第一部分咱们就主要来聊聊关于Chrome Ext的一些基础。json

获取一个插件的代码

Chrome Ext的存在模式相似于在浏览器层新加了一层解释器,在咱们访问网页的时候,插件会加载相应的html、js、css,并解释执行。api

因此Chrome Ext的代码也就是html、js、css这类,那咱们如何获取插件的代码呢?跨域

当咱们访问扩展程序的页面能够得到相应的插件id
16.png浏览器

而后咱们能够在https://chrome-extension-down... 中下载相应的crx包。安全

把crx更名成zip以后解压缩就能够了
17.pngcookie

manifest.json

在插件的代码中,有一个重要的文件是manifest.json,在manifest.json中包含了整个插件的各类配置,在配置文件中,咱们能够找到一个插件最重要的部分。网络

首先是比较重要的几个字段

  • browser_action
    这个字段主要负责扩展图标点击后的弹出内容,通常为popup.html
  • content_scripts
    matches 表明scripts插入的时机,默认为document_idle,表明页面空闲时
    js 表明插入的scripts文件路径
    run_at 定义了哪些页面须要插入scripts
  • permissions
    这个字段定义了插件的权限,其中包括从浏览器tab、历史纪录、cookie、页面数据等多个维度的权限定义
  • content_security_policy
    这个字段定义了插件页面的CSP
    但这个字段不影响content_scripts里的脚本
  • background
    这个字段定义插件的后台页面,这个页面在默认设置下是在后台持续运行的,只随浏览器的开启和关闭
    persistent 定义了后台页面对应的路径
    page 定义了后台的html页面
    scripts 当值为false时,background的页面不会在后台一直运行

在开始Chrome插件的研究以前,除了manifest.json的配置之外,咱们还须要了解一下围绕chrome创建的插件结构。

Chrome Ext的主要展示方式
browserAction - 浏览器右上角
18.png

浏览器的右上角点击触发的就是mainfest.json中的browser_action

"browser_action": {
      "default_icon": "img/header.jpg",
      "default_title": "LoRexxar Tools",
      "default_popup": "popup.html"
    },

其中页面内容来自popup.html

pageAction

pageAction和browserAction相似,只不过其中的区别是,pageAction是在知足必定的条件下才会触发的插件,在不触发的状况下会始终保持灰色。

19.png

contextMenus 右键菜单

经过在chrome中调用chrome.contextMenus这个API,咱们能够定义在浏览器中的右键菜单。

固然,要控制这个api首先你必须申请控制contextMenus的权限。

{"permissions": ["contextMenus"]}

通常来讲,这个api会在background中被定义,由于background会一直在后台加载。

chrome.contextMenus.create({
    title: "测试右键菜单",
    onclick: function(){alert('您点击了右键菜单!');}
});

https://developer.chrome.com/...

override - 覆盖页面

chrome提供了override用来覆盖chrome的一些特定页面。其中包括历史记录、新标签页、书签等...

"chrome_url_overrides":
{
    "newtab": "newtab.html",
    "history": "history.html",
    "bookmarks": "bookmarks.html"
}

好比Toby for Chrome就是一个覆盖新标签页的插件

devtools - 开发者工具
chrome容许插件重构开发者工具,而且相应的操做。
20.png

插件中关于devtools的生命周期和F12打开的窗口时一致的,当F12关闭时,插件也会自动结束。

而在devtools页面中,插件有权访问一组特殊的API,这组API只有devtools页面中能够访问。

chrome.devtools.panels:面板相关;
chrome.devtools.inspectedWindow:获取被审查窗口的有关信息;
chrome.devtools.network:获取有关网络请求的信息;
{
    // 只能指向一个HTML文件,不能是JS文件
    "devtools_page": "devtools.html"
}

21.png
https://developer.chrome.com/...

option - 选项

option表明着插件的设置页面,当选中图标以后右键选项能够进入这个页面。

22.png

{
    "options_ui":
    {
        "page": "options.html",
        "chrome_style": true
    },
}

omnibox - 搜索建议

在chrome中,若是你在地址栏输入非url时,会将内容自动传到google搜索上。

omnibox就是提供了对于这个功能的魔改,咱们能够经过设置关键字触发插件,而后就能够在插件的帮助下完成搜索了。

{
    // 向地址栏注册一个关键字以提供搜索建议,只能设置一个关键字
    "omnibox": { "keyword" : "go" },
}

这个功能经过chrome.omnibox这个api来定义。

notifications - 提醒

notifications表明右下角弹出的提示框

chrome.notifications.create(null, {
    type: 'basic',
    iconUrl: 'img/header.jpg',
    title: 'test',
    message: 'i found you!'
});

23.png

权限体系和api

在了解了各种型的插件的形式以后,还有一个比较重要的就是Chrome插件相关的权限体系和api。

Chrome发展到这个时代,其相关的权限体系划分已经算是很是细致了,具体的细节能够翻阅文档。

https://developer.chrome.com/...

抛开Chrome插件的多种表现形式不谈,插件的功能主要集中在js的代码里,而js的部分主要能够划分为5种injected script、content-script、popup js、background js和devtools js.

  • injected script 是直接插入到页面中的js,和普通的js一致,不能访问任何扩展API.
  • content-script 只能访问extension、runtime等几个有限的API,也能够访问dom.
  • popup js 能够访问大部分API,除了devtools,支持跨域访问
  • background js 能够访问大部分API,除了devtools,支持跨域访问
  • devtools js 只能访问devtools、extension、runtime等部分API,能够访问dom
JS 是否能访问DOM 是否能访问JS 是否能够跨域
injected script 能够访问 能够访问 不能够
content script 能够访问 不能够 不能够
popup js 不可直接访问 不能够 能够
background js 不可直接访问 不能够 能够
devtools js 能够访问 能够访问 不能够

一样的,针对这多种js,咱们也须要特殊的方式进行调试

  • injected script: 直接F12就能够调试
  • content-script:在F12中console选择相应的域

    24.png

  • popup js: 在插件右键的列表中有审查弹出内容
  • background js: 须要在插件管理页面点击背景页而后调试

通讯方式

在前面介绍过各种js以后,咱们提到一个重要的问题就是,在大部分的js中,都没有给与访问js的权限,包括其中比较关键的content script.

那么插件怎么和浏览器前台以及相互之间进行通讯呢?

- injected-script content-script popup-js background-js
injected-script - window.postMessage - -
content-script window.postMessage - chrome.runtime.sendMessage chrome.runtime.connect chrome.runtime.sendMessage chrome.runtime.connect
popup-js - chrome.tabs.sendMessage chrome.tabs.connect - chrome.extension. getBackgroundPage()
background-js - chrome.tabs.sendMessage chrome.tabs.connect chrome.extension.getViews -
devtools-js hrome.devtools.inspectedWindow.eval - chrome.runtime.sendMessage chrome.runtime.sendMessage

popup 和 background

popup和background两个域互相直接能够调用js而且访问页面的dom。

popup能够直接用chrome.extension.getBackgroundPage()获取background页面的对象,而background能够直接用chrome.extension.getViews({type:'popup'})获取popup页面的对象。

// background.js
function test()
{
    alert('test');
}

// popup.js
var bg = chrome.extension.getBackgroundPage();
bg.test(); // 访问bg的函数
alert(bg.document.body.innerHTML); // 访问bg的DOM

popupbackground 和 content js

popupbackground 和 content js之间沟通的方式主要依赖chrome.tabs.sendMessagechrome.runtime.onMessage.addListener这种有关事件监听的交流方式。

发送方使用chrome.tabs.sendMessage,接收方使用chrome.runtime.onMessage.addListener监听事件。

chrome.runtime.sendMessage({greeting: '发送方!'}, function(response) {
    console.log('接受:' + response);
});

接收方

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
    console.log(request, sender, sendResponse);
    sendResponse('回复:' + JSON.stringify(request));
});

injected script 和 content-script

因为injected script就至关于页面内执行的js,因此它没权限访问chrome对象,因此他们直接的沟通方式主要是利用window.postMessage或者经过DOM事件来实现。

injected-script中:

`window.postMessage({"test": 'test!'}, '*');

content script中:

window.addEventListener("message", function(e)
{
    console.log(e.data);
}, false);`

popupbackground 动态注入js

popupbackground没办法直接访问页面DOM,可是能够经过chrome.tabs.executeScript来执行脚本,从而实现对页面DOM的操做。

要注意这种操做要求必须有页面权限

"permissions": [
        "tabs", "http://*/*", "https://*/*"
    ],

js

// 动态执行JS代码
chrome.tabs.executeScript(tabId, {code: 'document.body.style.backgroundColor="red"'});
// 动态执行JS文件
chrome.tabs.executeScript(tabId, {file: 'some-script.js'});

chrome.storage

chrome 插件还有专门的储存位置,其中包括chrome.storage和chrome.storage.sync两种,其中的区别是:

  • chrome.storage 针对插件全局,在插件各个位置保存的数据都会同步。
  • chrome.storage.sync 根据帐户自动同步,不一样的电脑登录同一个帐户都会同步。

插件想访问这个api须要提早声明storage权限。

总结

这篇文章主要描述了关于Chrome ext插件相关的许多入门知识,在谈及Chrome ext的安全问题以前,咱们可能须要先了解一些关于Chrome ext开发的问题。

在下一篇文章中,咱们将会围绕Chrome ext多个维度的安全问题进行探讨,在现代浏览器体系中,Chrome ext到底可能会带来什么样的安全问题。

re

https://www.cnblogs.com/liuxi...
https://developer.chrome.com/...

本文由 Seebug Paper 发布,如需转载请注明来源。

相关文章
相关标签/搜索