New issue
Advanced search Search tips

Issue 631847 link

Starred by 5 users

Issue metadata

Status: Fixed
Owner:
Closed: Sep 2017
Cc:
Components:
EstimatedDays: ----
NextAction: 2018-01-09
OS: All
Pri: 3
Type: Bug



Sign in to add a comment

Security: javascript URI pasting XSS protection bypass

Reported by a...@adamobeng.com, Jul 26 2016

Issue description

VULNERABILITY DETAILS
The 'javascript:' scheme is not stripped from pasted URIs if preceded by ASCII control characters, allowing an attacker to trick a user into executing javascript on any page (a so-called self-XSS attack, which has been used in the past to target Facebook amongst others).

Normally, upon pasting URIs which start with 'javascript:' into the Omnibox, the 'javascript:' scheme is stripped to prevent this (see  Issue 105295 ,  Issue 82181 , Revision 86525, Revision 111548).

VERSION
Chrome Version: 51.0.2704.103 stable
Operating System: OS X Yosemite 10.10.5 (14F1605)

REPRODUCTION CASE
1. Place the string'^@Ajavascript:alert("document.location")' (where the first character is an ASCII NUL) in your clipboard, e.g. from http://pastebin.com/i6LMCiG6. I can't write the actual string here because the bugtracker strips ASCII control characters(!)
2. Paste it into the Omnibox
3. Press Enter
4. See the popup with the URI of the page you were previously visiting
 
FURTHER DETAILS
- This works if the first character is any of 0x00 to 0x1f, or 0x7f.
- Also works if you right-click the Omnibox and press "Paste and Go".
- I think the bug is the result of an interaction between OmniboxView::SanitizeTextForPaste and ParseStandardURL. SanitizeTextForPaste removes the 'javascript:' scheme if the string begins with it: this doesn't happen if there is a leading control character. ParseStandardURL strips leading control characters from the scheme before the URL is evaluated, so the malicious URL is interpreted as a 'javascript:' URL.
- Safari and Firefox do not appear to be vulnerable.
 

Comment 1 by rickyz@chromium.org, Jul 26 2016

Components: UI>Browser>Omnibox
Labels: -Type-Bug-Security -Restrict-View-SecurityTeam Type-Bug
Status: Available (was: Unconfirmed)
Thanks for the detailed analysis! Marking as non-security because self-xss defenses are best-effort, but this does seems reasonable to fix. I've also opened up the bug so that more folks can see it.
Hmm.

It's not completely clear to me what the pasted string should be in this case.  Should we strip not only "javascript:" but all preceding characters?  I don't have an example but it worries me that this might become somewhat arbitrarily broad.

Comment 3 by a...@adamobeng.com, Jul 26 2016

Is there any way to use the URL parsing code to determine if it's a 'javascript:' URL? That way the paste-protection and scheme-detection would not have divergent implementations.
That'd be how we'd detect such a thing; the tricky bit is deciding what to strip out.  We can have an arbitrarily long string of control characters at the beginning; do we want XXXXXXXXXXXXXXXXXXXXXXXXjavascript:... to strip all the Xs?

Comment 5 by a...@adamobeng.com, Jul 27 2016

I see. Currently, for '    javascript:alert("document.location")', all the preceding spaces are stripped. So maybe match that behaviour?
We always strip leading and trailing whitespace on paste anyway, and whitespace around the URL doesn't change its meaning.  That seems less true for control characters.  What kinds of control characters are we talking about?  Just NUL or something else too?

Comment 7 by a...@adamobeng.com, Jul 27 2016

I think you also strip leading control characters from URLs with other schemas, like '^@^@^@http://google.com'. Perhaps this happens not on paste, but in DoExtractScheme?

It's not just NUL, I tested DEL, SOM and SI; I assume other non-whitespace control characters will be the same.
We strip during fixup, not during paste, so that if a user wanted to search for the input string, it would be possible to do so.  We intentionally don't do fixup during paste since that could (sometimes radically) change the pasted-in string; it's an aggressive transformation that assumes the user intended a navigation and tries hard to transform the input into one.

What we'd need to do to address this is to try to do fixup inside OmniboxView::StripJavascriptSchemas(), look for the javascript scheme, map back to the character position in the original string, then strip.  My concern here is twofold: (1) maybe we'll strip something too aggressively, and (2) this could become a significant perf cost, especially if we need to run a full classifier pass and the input string has a bunch of copies of the scheme.
Cc: pkasting@chromium.org
Labels: OS-All Pri-3
NextAction: 2018-01-09
pkasting@ makes this sounds like icky code ("look for the javascript scheme, map back to the character position in the original string, then strip"), difficult to know exactly what to do ("we'll strip something too aggressively"), and a possible performance hit ("if we need to run a full classifier pass and the input string has a bunch of copies of the scheme").  I'm tentatively marking as will reassess this issue next year.

pkasting@ - what's wrong with stripping a pre-specified list of control characters from the beginning of the string on all pastes into the omnibox.  I saw your message
>>>
We intentionally don't do fixup during paste since that could (sometimes radically) change the pasted-in string; it's an aggressive transformation that assumes the user intended a navigation and tries hard to transform the input into one.
>>>
yet I find it hard to believe that anyone would expect the omnibox to do anything with control characters.
This is a pretty serious hole in our protections, and one not found in Edge or IE. 

The attacks that led to these protections were measured in thousands of users compromised per hour, and this is a trivial circumvention of the protections we built.

Today, we strip out whitespace on paste, and adding the ASCII control characters (0x00 to 0x19) to the set stripped seems like the right way to approach this.
 Issue 766010  has been merged into this issue.
Owner: elawrence@chromium.org
Status: Started (was: Available)
https://chromium-review.googlesource.com/c/chromium/src/+/673363
Project Member

Comment 13 by bugdroid1@chromium.org, Sep 22 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/35281b3ce9ad105652e0828a74fd78fbda77bf31

commit 35281b3ce9ad105652e0828a74fd78fbda77bf31
Author: Eric Lawrence <elawrence@chromium.org>
Date: Fri Sep 22 21:13:27 2017

Prevent smuggling of Javascript urls in Omnibox paste

Prevent circumvention of checks that ensure javascript:
URLs cannot be pasted in the omnibox by ensuring that
leading control and whitespace characters are trimmed.

Bug:  631847 
Test: components_unittests OmniboxViewTest.*
Change-Id: I74897e0e96e363f365c5c1e678820737063e7369
Reviewed-on: https://chromium-review.googlesource.com/673363
Reviewed-by: Mark Pearson <mpearson@chromium.org>
Commit-Queue: Eric Lawrence <elawrence@chromium.org>
Cr-Commit-Position: refs/heads/master@{#503853}
[modify] https://crrev.com/35281b3ce9ad105652e0828a74fd78fbda77bf31/components/omnibox/browser/omnibox_view.cc
[modify] https://crrev.com/35281b3ce9ad105652e0828a74fd78fbda77bf31/components/omnibox/browser/omnibox_view.h
[modify] https://crrev.com/35281b3ce9ad105652e0828a74fd78fbda77bf31/components/omnibox/browser/omnibox_view_unittest.cc

Labels: reward-topanel
Status: Fixed (was: Started)
Fixed.

While comment #1 argues that this shouldn't be considered a security vulnerability, given the severity and frequency of actual exploit via the Javascript-paste vector [1], I think we should consider this one for the VRP.

[1] https://blogs.msdn.microsoft.com/ieinternals/2011/05/19/socially-engineered-xss-attacks/, summarized in comment #10
Labels: -reward-topanel reward-0
Thanks for flagging, the panel declined to reward, given the amount of user interaction required.
It would be possible to reduce the amount of user interaction in the case where a user right-clicks or uses a keyboard shortcut to copy an innocent-looking URL from a page, by using javascript to make the object they actually click on contain one of these malicious URLs. Should I make a PoC?
I don't think any additional PoC is needed. 

"Hit CTRL+C, CTRL+L, CTRL+V, Enter to unlock your free Facebook credits" is probably the best you can do when you don't have the ability to run JavaScript (e.g. when you're posting malicious content on the victim page).

When you can run JavaScript (e.g. your own malicious site), you'd do:

"Click this button, then hit CTRL+L, Ctrl+V, Enter"; you make the button copy the attack text and then navigate to the victim site.
Or, if Javascript is allowed have a URL not within an <a> tag, and "if you can't click this URL, copy and paste it to the URL bar", and replace it on copy with a malicious link. Do you think the panel might reconsider, given that?
The NextAction date has arrived: 2018-01-09

Sign in to add a comment