Showing posts with label xss. Show all posts
Showing posts with label xss. Show all posts

Friday, June 20, 2014

LinkedIn Stored XSS Vulnerability

TL;DR: I found a stored XSS on LinkedIn, that's all folks, nothing special.

----

I was invited to publish on LinkedIn.

I wondered how good is LinkedIn at multi-byte UTF-8 support (fixed some bugs recently in Liferay related to escaping and surrogate pairs) and noticed a strange thing.

When processing URLs, LinkedIn exchanges escaped characters with their unescaped form = removes the escaping.

" → "

Then it was easy to create some vectors to try the stored XSS:





----

Timeline:
June 17, 2014 10:43 PM CEST – Reported to Linkedin Security Team
June 17, 2014 11:09 PM CEST – ACKed they received it
June 18, 2014 01:04 AM CEST – Reproduced
June 19, 2014 04:12 AM CEST – Got email that it's fixed

----

After this I was a bit scared so I quickly looked also at other LinkedIn features that I use. And found another vulnerability in the feature I trust and would be a good victim for :/

But, for now, please stay tuned until they fix it. You know, I'm the white-hat = harmless ;)

Friday, February 14, 2014

How is it with URL encoding + XSS

Correct URLs


All URIs need to be encoded using percent encoding as specified in rfc3986.

URLs may consist of:
* reserved characters - when used with their special meaning: !*'();:@&=+$,/?#[]
* unreserved characters - don't need to be encoded: a-z A-Z 0-9 -._~
* any other characters must be encoded using %xx hex escaping sequence using UTF-8 bytes

This means:
http://example.com/příliš/žluťoučký;kůň=úpěl?ďábelské=ódy is a nice invalid URL.

Correct is:
http://example.com/p%C5%99%C3%ADli%C5%A1/%C5%BElu%C5%A5ou%C4%8Dk%C3%BD;k%C5%AF%C5%88=%C3%BAp%C4%9Bl?%C4%8F%C3%A1belsk%C3%A9=%C3%B3dy

Question: Are URLs in my web app broken?
Answer: Unless you always go with ASCII ... probably yes :)
Better answer: It doesn't matter, browsers are smart enough to correctly parse the simple ones

Semantics of URL parts

Important to know ⁉
  • URL = decode(encode(URL))
  • encode(URL) != encode(decode(encode(URL)))
Decoding depends on correct knowledge of the parts being encoded!
http://example.com/evaluate/3%2B2%2F5 ⇝ http://example.com/evaluate/3+2/5
http://example.com/evaluate/3%2B2/5 ⇝ http://example.com/evaluate/3+2/5
=> ENCODING is responsible to transfer the knowledge into correctly constructed URL
=> only then DECODING is able to correctly identify the parts

Exercise from [2]:
http://example.com/:@-._~!$&'()*+,=;:@-._~!$&'()*+,=:@-._~!$&'()*+,==?/?:@-._~!$'()*+,;=/?:@-._~!$'()*+,;==#/?:@-._~!$&'()*+,;=

The important are delimiters - reserved characters.

URLs & HTML = XSS ?


URLs in HTML = replace & for & But what about URLs and XSS?

Q: Can there be a XSS in URL? 
A: Inside not encoded URL ... YES!
Example URL: http://localhost/'"><img src=x onerror=alert(1)>
⇝ <a href="http://localhost/'"><img src=x onerror=alert(1)>">link</a>

Q: Can there be a XSS in correctly encoded URL?
A: Yes!
Example URL: http://localhost/'+alert(1)+'
Correctly encoded: http://localhost/'+alert(1)+'
<script>location.href='http://localhost/'+alert(1)+'';</script>

Summary

Q: Does it matter when I don't encode URLs using percent-encoding syntax?
A: Only when parts contain reserved characters.

=> ENCODE user-supplied parts of the URL

http://example.com/evaluate/ + encode("3+2/5") ⇝ http://example.com/evaluate/3%2B2%2F5

Q: Can there be a XSS in URL?
A: Yes.

=> ESCAPE user-supplied URLs based on the surrounding context (see OWASP cheet sheet)!

⇝ <a href="http&#x3a;&#x2f;&#x2f;localhost&#x2f;&#x27;&#x22;&#x3e;&#x3c;img&#x20;src&#x3d;x&#x20;onerror&#x3d;alert&#x28;1&#x29;&#x3e;">link</a>

<script>location.href='http\x3a\x2f\x2flocalhost\x2f\x27\x22\x3e\x3cimg\x20src\x3dx\x20onerror\x3dalert\x281\x29\x3e';</script>

Where to continue...


(for serious readers, ordered by simplicity)


Thursday, December 5, 2013

My XSS Locator / Vector

toString()+alert(/xss/)+function(){/*'+alert(/xss/)+'"+alert(/xss/)+"--></style><img src=x onerror=alert(/xss/)>*/}

URL Encoded:
toString()%2Balert(%2Fxss%2F)%2Bfunction()%7B%2F*%27%2Balert(%2Fxss%2F)%2B%27%22%2Balert(%2Fxss%2F)%2B%22--%3E%3C%2Fstyle%3E%3Cimg%20src%3Dx%20onerror%3Dalert(%2Fxss%2F)%3E*%2F%7D


Pros
  • Able to exploit most places (the list is below)
  • Trying not to break JavaScript syntax
  • Easy to identify the vulnerable field (e.g. alert(/userMiddleName/))

Cons - too long for values which have length limit



List of exploitable places:
  • JavaScript/DOM XSS
    • var x="asdf<%= xssLocator %>xxx";
    • var y='asdf<%= xssLocator %>xxx';
    • opener.<%= xssLocator %>(some, arguments);
    • element.html(xssLocatorInput.value);
  • CSS XSS:
    • <style>a:after { content: '<%= xssLocator %>';}</style>
  • HTML Attribute XSS:
    • <a href="#" alt="<%= xssLocator %>">test</a>
    • <a href='#' alt='<%= xssLocator %>'>test</a>
  • HTML Body and Comments XSS
    • <%= xssLocator %>
    • <!-- <%= xssLocator %> -->

Monday, November 19, 2012

How to correctly escape webapp output

1, Escaping must be performed in the last possible place = when writing HTML output


Only when writing a java variable content to the output stream we know if we write the content into a javascript variable, html attribute or as a plain text (html body).

2, Every variable of a String type deserves escaping. Don't escape output only in case you NEED to print HTML.


You may never know how a possibly malicious content got into your variable. It may be persistent
XSS from DB, session attribute, request parameter.

3, Use the right escaping for the right situation. 


See OWASP's XSS_Prevention_Rules_Summary


Side note: Don't mix URL encoding with URL escaping. 

See HTML appendix B.2.1 and B.2.2


URL encoding
Though there can be UTF-8 characters in the URL, URLs should be transmitted in US-ASCII encoding.

Valid URL follows percent encoding of characters, described in Percent encoding of URI characters.

When URL is not encoded, UTF-8 characters are translated into US-ASCII OOTB by browsers. But if you want to be sure (you can't lose here) you can use new java.net.URI().toASCIIString(). In javascript there is a similar function window.encodeURI().

What MUST BE encoded is a URL parameter name and value. It's confusing but to encode the parameter use java.net.URLEncoder.encode(). Javascript has better name: window.encodeURIComponent().

Don't use URL encoding to perform HTML escaping! (Yes, I've seen that :) )


URL escaping
Let's say we already have a valid (correctly encoded) URL which we want to write into HTML.

Then there are 2 important steps:
1, Ampersand character (&), which may be a part of URL, is used to prefix html entity references. When writing a valid HTML we should escape it the same way as any other ampersand you want to write there. Use ampersand entity: &amp;

2, To write safe HTML = to be sure that URL won't escape from HTML attributes or JavaScript variable (it is allowed to contain apostrophe character) it's good to escape the URL as described in  XSS_Prevention_Rules_Summary, not only the query string part.

When we don't have the URL properly encoded we must escape the whole URL - perform the step #2.