Chromium Blog
News and developments from the open source browser project
Writing Extensions More Securely
Friday, July 22, 2011
Extensions are powerful pieces of software in modern browsers, and as such, you should help ensure that your extensions are not susceptible to security exploits. If an attacker manages to exploit a vulnerability in an extension, it’s serious business because they may gain access to the same privileges that the extension has.
The Chrome extensions system has a number of
built-in protections
to make it more difficult to introduce exploitable code, but certain coding patterns can still open up the risk of exploits like a cross-site scripting (XSS) attack. Many of these mistakes are common to web programming in general, so it wouldn’t be a bad idea to check out one of the
many
good
articles
on the net about XSS bugs. Here are some of our recommendations for writing healthier extensions.
Minimize your permissions
The most important thing to consider is whether you’re declaring the minimal set of permissions that you need to function. That way, if you do have a security bug in your code, the amount of permissions you’re exposing to the attacker is minimal as well. Avoid requesting
(*/*) permissions for hosts if you only need to access a couple, and don’t copy and paste your manifest from example code blindly. Review your manifest to make sure you’re only declaring what you need. This applies to permissions like tabs, history, cookies, etc. in addition to host permissions. For example, if all you’re using is
chrome.tabs.create
, you don’t actually need the tabs permission.
Use content_security_policy in your manifest
Starting in Chrome 14, we will begin supporting
Content Security Policy
in extensions via the
content_security_policy
manifest field. This allows you to control where scripts can be executed, and it can be used to help reduce your exposure to cross-site scripting vulnerabilities. For example, to specify that your extension loads resources only from its own package, use the following policy:
"content_security_policy": "default-src 'self'"
If you need to include scripts from specific hosts, you can add those hosts to this property.
Don’t use <script src> with an HTTP URL
When you include javascript into your pages using an HTTP URL, you’re opening your extension up to man-in-the-middle (MITM) attacks. When you do so in a content script, you have a similar effect on the pages you’re injected into. An attacker on the same network as one of your users could replace the contents of the script with content that they control. If that happens, they could do anything that your page can do.
If you need to fetch a remote script, always use HTTPS from a trusted source.
Don’t use eval()
The eval() function is very powerful and you should refrain from using it unless absolutely necessary. Where did the code come from that you passed into eval()? If it came from an HTTP URL, you’re vulnerable to the same issue as the previously mentioned <script> tag. If any of the content that you passed into eval() is based on content from a random web page the user visits, you’re vulnerable to escaping bugs. For example, let’s say that you have some code that looks like this:
function displayAddress(address) { // address was detected and grabbed from the current page
eval("alert('" + address + "')");
}
If it turned out that you had a bug in your parsing code, the address might wind up looking something like this:
'); dosomethingevil();
There’s almost always a better alternative to using eval(). For example, you can use JSON.parse if you want to parse JSON (with the added benefit that it runs faster). It’s worth the extra effort to use alternatives like this.
Don’t use innerHTML or document.write()
It’s really tempting to use innerHTML because it’s much simpler to generate markup dynamically than to create DOM nodes one at a time. However, this again sets you up for bugs in escaping your content. For example:
function displayAddress(address) { // address was detected and grabbed from the current page
myDiv.innerHTML = "<b>" + address + "</b>");
}
This would allow an attacker to make an address like the following and once again run some script in your page:
<script>dosomethingevil();</script>
Instead of innerHTML, you can manually create DOM nodes and use innerText to insert dynamic content.
Beware external content
In general, if you’re generating dynamic content based on data from outside of your extension (such as something you fetched from the network, something you parsed from a page, or a message you received from another extension, etc.), you should be extremely careful about how you use it. If you use this data to generate content within your extension, you might be opening your users up to increased risk.
You can also read a
few more
examples of the issues discussed here in our extension docs. We hope these recommendations help you create better and safer extensions for everyone.
Posted by Erik Kay, Software Engineer
Labels
$200K
1
10th birthday
4
abusive ads
1
accessibility
1
ad blocking
1
android
1
benchmarks
1
beta
14
billing
1
birthday
4
blink
1
browser
2
browser interoperability
1
capabilities
3
capable web
1
cds18
2
cds2018
1
chrome
11
chrome ads
1
chrome apps
3
chrome dev summit 2018
1
Chrome Frame
1
chrome web store
27
chromedevtools
1
chromeframe
3
chromeos
3
chromium
3
cloud print
1
coalition
1
coalition for better ads
1
dart
8
dashboard
1
day 2
1
design
1
devtools
12
discoverability
1
extensions
24
features
1
feedback
2
field data
1
frameworks
1
fund
1
funding
1
gdd
1
googlechrome
12
harmful ads
1
html5
11
incognito
1
javascript
3
lab data
1
lighthouse
1
linux
2
mac
1
mobile
2
na
1
native client
8
New Features
5
octane
1
open web
3
pagespeedinsights
1
performance
2
performance tools
1
play store
1
portals
1
progressive web apps
1
protection
1
pwa
1
releases
3
rlz
1
security
30
spdy
2
speed
1
ssl
2
store listing
1
subscription pages
1
tools
1
trusted web activities
1
twa
1
v8
6
web apps
1
web intents
1
web packaging
1
web.dev
1
webapi
1
webaudio
3
webgl
7
webkit
5
webmaster
1
webp
5
webrtc
4
websockets
5
webtiming
1
writable-files
1
Archive
2019
Feb
Jan
2018
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2017
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2016
Dec
Nov
Oct
Sep
Aug
Jun
May
Apr
Mar
Feb
Jan
2015
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2014
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2013
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2012
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2011
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2010
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2009
Dec
Nov
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2008
Dec
Nov
Oct
Sep
Feed
Google
on
Follow @ChromiumDev
Give us feedback in our
Product Forums
.