-
Notifications
You must be signed in to change notification settings - Fork 27.5k
fix(security): do not auto-bootstrap when loaded from an extension. #15346
Conversation
LGTM |
@@ -1602,6 +1622,11 @@ function angularInit(element, bootstrap) { | |||
} | |||
}); | |||
if (appElement) { | |||
if (!isAutoBootstrapAllowed) { | |||
console.error('Angular: disabling automatic bootstrap. <script> protocol indicates an ' + | |||
'extension, document.href does not match.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document.location.href
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -1602,6 +1622,11 @@ function angularInit(element, bootstrap) { | |||
} | |||
}); | |||
if (appElement) { | |||
if (!isAutoBootstrapAllowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check could be moved at the top (unless we expect anyone to load angular via resource:
/chrome-extension:
in a non-extention page and bootstrap it manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't do this intentionally - otherwise you'll get an error message even if you intend to manually bootstrap by calling angular.bootstrap
. Which I guess is a legit use case, if somebody does inject Angular in the page but also controls it to call angular.bootstrap
(not a security issue because they can already execute JS in the page in that case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I thought it might be intentional. I don't expect anyone to be loading angular over resource:
on non-extension pages, but you never know 😃
Hm...so, if it is a supported usecase (loading angular.js over resource:
on non-extension pages), isn't this chage breaking? In that case, we should have a breaking change notice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading angular.js over resource:
from a non-extension page is not supported, and not a use case (that's almost certainly a security exploit, which is why this change is blocking it). I don't think we need to document that.
However, for the rare case where a web page really actually wants to load via resource://
, it still can, by embedding an appropriate angular.bootstrap
call. If you can embed JS into the hosting page, you can do evil things anyway, so that's not a security boundary. This behaviour is easy to implement, doesn't do harm or lower security (it should, at least...), and overall seems fine.
A secondary effect is that the console spam only triggers if the user actually has an ng-app
in their app, so it's more precise, which I think is a good thing.
So I don't think we need to document anything. Most users will never notice this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I don't think we need to document anything. Most users will never notice this.
This should be documented, assuming that most users won't notice it means that when someone does notice it, there is no help available on how to go about making it work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mmccallum - feel free to send in a PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mmccallum FWIW, when auto bootstrap gets disabled, Angular prints out a pretty clear message in the console.
Extension URIs (`resource://...`) bypass Content-Security-Policy in Chrome and Firefox and can always be loaded. Now if a site already has a XSS bug, and uses CSP to protect itself, but the user has an extension installed that uses Angular, an attacked can load Angular from the extension, and Angular's auto-bootstrapping can be used to bypass the victim site's CSP protection. Notes: - `isAutoBootstrapAllowed` must be initialized on load, so that `currentScript` is set correctly. - The tests are a bit indirect as reproducing the actual scenario is too complicated to reproduce (requires signing an extension etc). I have confirmed this to be working manually.
b5e6da4
to
ca88480
Compare
@@ -97,6 +97,9 @@ | |||
NODE_TYPE_DOCUMENT, | |||
NODE_TYPE_DOCUMENT_FRAGMENT | |||
*/ | |||
/* global | |||
console |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can avoid this by accessing console
off window
(not sure what is better).
@@ -1602,6 +1622,11 @@ function angularInit(element, bootstrap) { | |||
} | |||
}); | |||
if (appElement) { | |||
if (!isAutoBootstrapAllowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I thought it might be intentional. I don't expect anyone to be loading angular over resource:
on non-extension pages, but you never know 😃
Hm...so, if it is a supported usecase (loading angular.js over resource:
on non-extension pages), isn't this chage breaking? In that case, we should have a breaking change notice.
var docLoadProtocol = document.location.protocol; | ||
if ((scriptProtocol === 'resource:' || | ||
scriptProtocol === 'chrome-extension:') && | ||
docLoadProtocol !== scriptProtocol) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we do allow auto bootstrap if the protocol of the document matches that of the script?
Why is that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because that's the intended use case - an extension that has a page (within the extension) that loads angular, and contains ng-app
. We could disable that, but if we support auto bootstrap, I think we should support it within extensions, shouldn't we?
@@ -1602,6 +1622,11 @@ function angularInit(element, bootstrap) { | |||
} | |||
}); | |||
if (appElement) { | |||
if (!isAutoBootstrapAllowed) { | |||
window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' + | |||
'an extension, document.location.href does not match.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel that this message could be clearer or that it should link to a webpage/issue that explains what is happening?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a suggestion? This should really only happen when somebody tries to exploit the security hole, so I'm not too worried about usability here. I don't think we need docs or a website.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it shouldn't block merging this.
Extension URIs (`resource://...`) bypass Content-Security-Policy in Chrome and Firefox and can always be loaded. Now if a site already has a XSS bug, and uses CSP to protect itself, but the user has an extension installed that uses Angular, an attacked can load Angular from the extension, and Angular's auto-bootstrapping can be used to bypass the victim site's CSP protection. Notes: - `isAutoBootstrapAllowed` must be initialized on load, so that `currentScript` is set correctly. - The tests are a bit indirect as reproducing the actual scenario is too complicated to reproduce (requires signing an extension etc). I have confirmed this to be working manually. Closes #15346
Extension URIs (`resource://...`) bypass Content-Security-Policy in Chrome and Firefox and can always be loaded. Now if a site already has a XSS bug, and uses CSP to protect itself, but the user has an extension installed that uses Angular, an attacked can load Angular from the extension, and Angular's auto-bootstrapping can be used to bypass the victim site's CSP protection. Notes: - `isAutoBootstrapAllowed` must be initialized on load, so that `currentScript` is set correctly. - The tests are a bit indirect as reproducing the actual scenario is too complicated to reproduce (requires signing an extension etc). I have confirmed this to be working manually. Closes angular#15346
Extension URIs (`resource://...`) bypass Content-Security-Policy in Chrome and Firefox and can always be loaded. Now if a site already has a XSS bug, and uses CSP to protect itself, but the user has an extension installed that uses Angular, an attacked can load Angular from the extension, and Angular's auto-bootstrapping can be used to bypass the victim site's CSP protection. Notes: - `isAutoBootstrapAllowed` must be initialized on load, so that `currentScript` is set correctly. - The tests are a bit indirect as reproducing the actual scenario is too complicated to reproduce (requires signing an extension etc). I have confirmed this to be working manually. Closes angular#15346
Extension URIs (`resource://...`) bypass Content-Security-Policy in Chrome and Firefox and can always be loaded. Now if a site already has a XSS bug, and uses CSP to protect itself, but the user has an extension installed that uses Angular, an attacked can load Angular from the extension, and Angular's auto-bootstrapping can be used to bypass the victim site's CSP protection. Notes: - `isAutoBootstrapAllowed` must be initialized on load, so that `currentScript` is set correctly. - The tests are a bit indirect as reproducing the actual scenario is too complicated to reproduce (requires signing an extension etc). I have confirmed this to be working manually. Closes angular#15346
Extension URIs (
resource://...
) bypass Content-Security-Policy in Chrome andFirefox and can always be loaded. Now if a site already has a XSS bug, and uses
CSP to protect itself, but the user has an extension installed that uses
Angular, an attacked can load Angular from the extension, and Angular's
auto-bootstrapping can be used to bypass the victim site's CSP protection.
Notes:
isAutoBootstrapAllowed
must be initialized on load, so thatcurrentScript
is set correctly.
complicated to reproduce (requires signing an extension etc). I have confirmed
this to be working manually.