Wednesday, May 18, 2011

Invisible arbitrary CSRF file upload in


Basic upload form in was vulnerable to CSRF. Visiting a malicious page while being logged in to (or using 'keep me signed in' feature) allowed attacker to upload images or videos on user's behalf. These files could have all the visibility / privacy settings that user can set in Basic Upload form. Uploading files did not require any user intervention and/or consent.

Described vulnerability has been quickly fixed by team.

The exploit is an example of using my HTML5 arbitrary file upload method.


Vulnerability description basic upload form displayed on submits a POST request with multipart/form-data MIME type (standard HTTP File Upload form).
Basic File Upload Form
This request looks like this:
POST /photos/upload/transfer/ HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv: Gecko/20110419 Ubuntu/10.04 (lucid) Namoroka/3.6.18pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pl,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: BX=somecookies&b=3&s=rv; localization=en-us%3Bus%3Bpl; current_identity_provider_name=yahoo;; cookie_session=session-id-here
Content-Type: multipart/form-data; boundary=---------------------------410405671879807276394827599
Content-Length: 29437

Content-Disposition: form-data; name="done"

Content-Disposition: form-data; name="complex_perms"

Content-Disposition: form-data; name="magic_cookie"

Content-Disposition: form-data; name="file1"; filename="0011.jpg"
Content-Type: image/jpeg

Content-Disposition: form-data; name="tags"

Content-Disposition: form-data; name="is_public_0"

Content-Disposition: form-data; name="safety_level"

Content-Disposition: form-data; name="content_type"

Content-Disposition: form-data; name="Submit"


On line 11 there are some cookies, there is also a magic_cookie form field which looks like an anti-CSRF token. However, it was not verified properly. Changing the value or removing magic_cookie field still resulted in successful file upload.

To make things worse, uses persistent cookie BX for 'keep me signed in' feature. Sending POST request to not require an active session set up beforehand. If BX cookie is present, will silently sign the user in while processing the request. Therefore all accounts using 'keep me signed in' feature were potential targets of described attack.


Malicious page with this HTML code:
<form enctype=multipart/form-data action="" method="post">
<input type=hidden name=is_public_0 value=1>
<input type=file name=file1>
<input type="submit">
<!-- no magic_cookie here, still works -->
was able to submit a file to on logged in user's behalf, because the browser would attach the Flickr cookies to the request, and Flickr had no way of distinguishing it from a legitimate request (a classic CSRF vulnerability).

Above technique required user to manually choose the file from his HDD. However, using my HTML5 arbitrary file upload method a malicious page was able to construct the raw multipart/form-data request in Javascript and send it quietly without user interaction. In the demo video, a button press is required, but this is only for presentational purposes. File upload can be triggered automatically on page load.

As a result, visiting malicious page in browsers supporting CORS requests as per specification (Firefox 4, Chrome) while using 'keep me signed in' feature (or having an active session) resulted in uploading images and videos chosen by attacker to photostream (with visibility settings, tags etc. chosen by the attacker).

Exemplary exploit code is here.


As of today, fixed the issue and contacted me to confirm the fix - all within a few hours since notifying, great work guys! Now magic_cookie value is checked upon processing the upload request.


17.05.2011 - vulnerability discovered
18.05.2011 - vendor notified
18.05.2011 - vendor responded, fix released

2 comments: said...

Even Flickr has CSRFed but in such basic feature.? I don't get it. No mercy Koto for this kind of ignorance, no more, please :)

Mohammad teimori Pabandi said...

So what about cross-domain ajax?

Here you're sending ajax request to upload on flickr (in the github link), how's that possible?