[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [WEB SECURITY] Universal XSS with PDF files: highly dangerous
- From: "Amit Klein" <aksecurity@xxxxxxxxx>
- Subject: Re: [WEB SECURITY] Universal XSS with PDF files: highly dangerous
- Date: Thu, 4 Jan 2007 08:27:40 +0200
------=_Part_2952_7901821.1167892060620
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
It seems that I forgot all about Flash when I wrote that (the irony...). The
solution I proposed is not secure enough as-is. It is trivial to write a SWF
object that will request file.pdf?token_query=123 and add a "Cookie:
token_cookie=123". This is discussed in yours truly's "Forging HTTP request
headers with Flash" (http://www.securityfocus.com/archive/1/441014) and in
Rapid7's "Rapid7 Advisory R7-0026 - HTTP Header Injection Vulnerabilities in
the Flash Player Plugin" (http://www.rapid7.com/advisories/R7-0026.jsp).
Even adding cryptographic secret, time-based entropy or use counter doesn't
help - all this can be circumvented by a server script on the attacker's
site preparing the HTTP request and communicating it in real-time to the SWF
object at the victim's browser.
The solution I could come up with is to tie X to the IP address of the
client. Yes, I know - it's ugly, and it doesn't work 100% of the cases. But
you stand nothing to lose if you simply fall back to the "save to disk"
option, suggested by an anonymous SlashDot submitter (
http://it.slashdot.org/comments.pl?sid=214868&threshold=1&commentsort=0&mode=thread&cid=17450834
).
So the more secure solution, as I see it, is as following:
Apply only for PDF resources:
IF the URL doesn't contain token_query, then:
calculate X=encrypt_with_key(server_time, client_IP_address)
redirect to file.pdf?token_query=X with Set-Cookie: token_cookie=X to
expire at server_time+10sec.
ELSE IF the URL contains token_query, and token_query==token_cookie and
decrypt(token_query).IP_address==client_IP_address and
decrypt(token_query).time>server_time-10sec
serve the PDF resource as an in-line resource
ELSE
serve the PDF resource as a "save to disk" resource via a proper choice
of the Content-Type header (and/or an attachment, via Content-Disposition).
Hopefully this should work. But it's definitely less elegant than the
original (flawed) suggestion.
-Amit
On 1/3/07, Amit Klein <aksecurity@gmail.com> wrote:
>
> Amit Klein wrote:
> > pdp (architect) wrote:
> >> I will be very quick and just point to links where you can read about
> >> this issue.
> >>
> >> It seams that PDF documents can execute JavaScript code for no
> >> apparent reason by using the following template:
> >>
> >>
> >>
> http://path/to/pdf/file.pdf#whatever_name_you_want=javascript:your_code_here
> >>
> >>
> >> You must understand that the attacker doesn't need to have write
> >> access to the specified PDF document. In order to get an XSS vector
> >> working you need to have a PDF file hosted on the target and that's
> >> all about it. The rest is just a matter of your abilities and desires.
> >>
> > Amazing, and kudos to Sven Vetsch who found this.
> >
> Oops, seems that the credit went to the wrong guy. Actual credit go to
> Stefano Di Paola, with contributions from Giorgio Fedon (IE Dos, UXSS
> Analysis) and Elia Florio (Poc and Code Execution analysis).
>
> BTW, one way to mitigate this is for the server, upon receiving a
> request to file.pdf (without a valid query+cookie pair, see below), to
> redirect it to file.pdf?token_query=X (where X is an unpredictable, high
> entropy string) accompanied with a Set-Cookie header for a cookie named
> say "token_cookie" with value X and short expiration period (e.g. 10
> seconds). The browser will then respond with a request to
> file.pdf?token_query=X with Cookie token_cookie=X. At this point, if the
> server receives token_query==token_cookie, the server knows this is a
> legit request (i.e. without fragment), and it can safely serve the PDF
> resource.
>
> I suppose this can be implemented easily as an Apache module/ISAPI/NSAPI
> filters.
>
> -Amit
>
>
> ----------------------------------------------------------------------------
> The Web Security Mailing List:
> http://www.webappsec.org/lists/websecurity/
>
> The Web Security Mailing List Archives:
> http://www.webappsec.org/lists/websecurity/archive/
> http://www.webappsec.org/rss/websecurity.rss [RSS Feed]
>
>
------=_Part_2952_7901821.1167892060620
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
<div>It seems that I forgot all about Flash when I wrote that (the irony...). The solution I proposed is not secure enough as-is. It is trivial to write a SWF object that will request file.pdf?token_query=123 and add a "Cookie: token_cookie=123". This is discussed in yours truly's "Forging HTTP request headers with Flash" (
<a href="http://www.securityfocus.com/archive/1/441014">http://www.securityfocus.com/archive/1/441014</a>) and in Rapid7's "Rapid7 Advisory R7-0026 - HTTP Header Injection Vulnerabilities in the Flash Player Plugin" (
<a href="http://www.rapid7.com/advisories/R7-0026.jsp">http://www.rapid7.com/advisories/R7-0026.jsp</a>). </div>
<div>Even adding cryptographic secret, time-based entropy or use counter doesn't help - all this can be circumvented by a server script on the attacker's site preparing the HTTP request and communicating it in real-time to the SWF object at the victim's browser.
</div>
<div> </div>
<div>The solution I could come up with is to tie X to the IP address of the client. Yes, I know - it's ugly, and it doesn't work 100% of the cases. But you stand nothing to lose if you simply fall back to the "save to disk" option, suggested by an anonymous SlashDot submitter (
<a href="http://it.slashdot.org/comments.pl?sid=214868&threshold=1&commentsort=0&mode=thread&cid=17450834">http://it.slashdot.org/comments.pl?sid=214868&threshold=1&commentsort=0&mode=thread&cid=17450834
</a>).</div>
<div> </div>
<div>So the more secure solution, as I see it, is as following:</div>
<div> </div>
<div>Apply only for PDF resources:</div>
<div> </div>
<div>IF the URL doesn't contain token_query, then:</div>
<div> calculate X=encrypt_with_key(server_time, client_IP_address)</div>
<div> redirect to file.pdf?token_query=X with Set-Cookie: token_cookie=X to expire at server_time+10sec.<br> </div>
<div>ELSE IF the URL contains token_query, and token_query==token_cookie and decrypt(token_query).IP_address==client_IP_address and decrypt(token_query).time>server_time-10sec</div>
<div> serve the PDF resource as an in-line resource</div>
<div> </div>
<div>ELSE</div>
<div> serve the PDF resource as a "save to disk" resource via a proper choice of the Content-Type header (and/or an attachment, via Content-Disposition).</div>
<div> </div>
<div>Hopefully this should work. But it's definitely less elegant than the original (flawed) suggestion.</div>
<div> </div>
<div>-Amit</div>
<div> </div>
<div><br> </div>
<div><span class="gmail_quote">On 1/3/07, <b class="gmail_sendername">Amit Klein</b> <<a href="mailto:aksecurity@gmail.com">aksecurity@gmail.com</a>> wrote:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">Amit Klein wrote:<br>> pdp (architect) wrote:<br>>> I will be very quick and just point to links where you can read about
<br>>> this issue.<br>>><br>>> It seams that PDF documents can execute JavaScript code for no<br>>> apparent reason by using the following template:<br>>><br>>><br>>> <a href="http://path/to/pdf/file.pdf#whatever_name_you_want=javascript:your_code_here">
http://path/to/pdf/file.pdf#whatever_name_you_want=javascript:your_code_here</a><br>>><br>>><br>>> You must understand that the attacker doesn't need to have write<br>>> access to the specified PDF document. In order to get an XSS vector
<br>>> working you need to have a PDF file hosted on the target and that's<br>>> all about it. The rest is just a matter of your abilities and desires.<br>>><br>> Amazing, and kudos to Sven Vetsch who found this.
<br>><br>Oops, seems that the credit went to the wrong guy. Actual credit go to<br>Stefano Di Paola, with contributions from Giorgio Fedon (IE Dos, UXSS<br>Analysis) and Elia Florio (Poc and Code Execution analysis).<br>
<br>BTW, one way to mitigate this is for the server, upon receiving a<br>request to file.pdf (without a valid query+cookie pair, see below), to<br>redirect it to file.pdf?token_query=X (where X is an unpredictable, high<br>
entropy string) accompanied with a Set-Cookie header for a cookie named<br>say "token_cookie" with value X and short expiration period (e.g. 10<br>seconds). The browser will then respond with a request to<br>file.pdf
?token_query=X with Cookie token_cookie=X. At this point, if the<br>server receives token_query==token_cookie, the server knows this is a<br>legit request (i.e. without fragment), and it can safely serve the PDF<br>resource.
<br><br>I suppose this can be implemented easily as an Apache module/ISAPI/NSAPI<br>filters.<br><br>-Amit<br><br>----------------------------------------------------------------------------<br>The Web Security Mailing List:
<br><a href="http://www.webappsec.org/lists/websecurity/">http://www.webappsec.org/lists/websecurity/</a><br><br>The Web Security Mailing List Archives:<br><a href="http://www.webappsec.org/lists/websecurity/archive/">http://www.webappsec.org/lists/websecurity/archive/
</a><br><a href="http://www.webappsec.org/rss/websecurity.rss">http://www.webappsec.org/rss/websecurity.rss</a> [RSS Feed]<br><br></blockquote></div><br>
------=_Part_2952_7901821.1167892060620--
Brought to you by http://www.webappsec.org
Search this site
|