CSRF Exploit fix
Review Request #13 - Created Oct. 19, 2008 and submitted
Information | |
---|---|
Bogdan-Cristian Tătăroiu | |
infoarena | |
Reviewers | |
hackers | |
Revisions 910, part of 912, 915, 916, 927, 928, 932, 933
Review request changed
Change Summary:
- Fixed bug which made blog page actions not work. - Differentiate between nontextblock controllers (such as account) and special textblock controllers (such as blog). In the previous patch, images could not be attached from blog pages. I think this should be the final change :) -- Bogdan
Description: |
|
||||||
---|---|---|---|---|---|---|---|
Diff: |
Revision 2 (+166 -104) |
I've been thinking about this for a while. My musings go beyond CSRF exploits, notably to XSS exploits also. I also took the time to rant about browsers. Please bear with me. I think we can split the discussion in three parts: 1) Never change server state on GET requests. (A more fancy way of saying it, courtesy of HTTP/1.1 RFC2616 Section 9, is "GET requests should be idempotent.") This is standard HTTP practice but we don't always obey. For example, we should never logout or delete wiki pages (!!!) by simply following a link. All such controllers must be guarded against GET requests. This small fix will get rid of various nasty exploits, such as embedding an image with source '/logout' or writing a dishonest link such as 'Naked pictures of me!':problema/adunare?action=attach-del&file=... As you can see, the problem is not that we allow people to create links to "unsafe" actions. Such actions should not exist in the first place. 2) Don't host (i.e., serve) active content... or at least try not to. It may surprise you, but this is so hopeless that it breaks my heart and makes me cry. "Active" content basically means whatever is not 100% completey static and safe. Famous examples: shockwave flash, javascript, vbscript, and java applets. However, PDF files were also rather unsafe until Adobe fixed their plugin. In general, there are many browser plugins out there that run active content, and the usual security policy, if any, is that the container has access to the website that it was downloaded from. One way to exploit this: create your own website, say evil.com, embed a SWF file hosted on infoarena.ro as wiki page attachment. Then, lure infoarena admins to visit evil.com. Your SWF can start sending malicious POST requests to infoarena.ro using admin privileges. Bummer! Of course, you only have to write proper HTTP headers (Content-type: application/octet-stream; Content-disposition: attachment; force-download, etc.) to solve this. That's great! Except browsers are stupid and broken. Some IEs will ignore your force-download directives for <EMBED> or <OBJECT> tags. In the end, your only hope to avoid XSS exploits is to not host active content at all. One way to do this is to only allow certain MIME types when people upload attachments. That's great, and it kind of works! However, you've just entered the land of MIME magic idiosyncrasies! It turns out lots of image formats allow you to embed arbitrary blobs. For example, you can embed a full fledged java applet (JAR) inside a GIF image. Your Java run-time is smart enough to ignore gazillions of petabytes at the beginning of your file until it finds a JAR header. Then it starts reading the applet. Yey! Ask for "GIFAR attack" from your favourite search engine. The same goes for some IE versions. Try serving a "Content-type: text/plain" file that starts with "<html>". IE really likes chewing HTML, and will parse whatever walks and quacks like HTML, regardless of your MIME type indications. Should I mention charset encoding attacks? I'll stop short of it for the moment. It seems rather to completely avoid CSRF/XSS attacks. However, we could surely use some decent protection along the lines of my rant. I think content-type restrictions and content-disposition headers would do just fine. Additionally, we could ban attachment downloads with HTTP Referer outside infoarena domains; I think we already do that. All else failing, in backup we trust. 3) Write a decent url-mapper, maybe inspired by RoR's Routes module (http://wiki.rubyonrails.org/rails/pages/Routes). PHP has some kind of callback mechanism, and anonymous functions, so we could use those. The URL mapper should be unit-testable and should allow one to deny requests if they don't match the expected HTTP method (GET/POST). I only write this because you tried to move some stuff from index.php. I figured you are interested in a better design than the current one. :) The following line 3 annotations are rather useless. It's clear we need a completely different fix for this. :)
-
/trunk/common/string.php (Diff revision 2) -
Evil space. :)
-
/trunk/www/config.php (Diff revision 2) -
I don't think these belong here, in www/config.php.
-
/trunk/www/wiki/MyTextile.php (Diff revision 2) -
Evil tab. :)
Review request changed
Change Summary:
Reverted changes to index.php, moved IA_CONTROLLERS back to index.php. Remove IA_NONTEXTBLOCK_CONTROLLERS check in MyTextile.php -- Bogdan
Diff: |
Revision 3 (+28 -8) |
---|
Review request changed
-
/trunk/common/string.php (Diff revision 4) -
I suspect starts_with("john", 0) evaluates true, courtesy of PHP type coercion. This is bad behaviour since it's hard to make sure you're always passing strings, rather than integers or bools. Either coerce rterm to string or log fatal error message.
-
/trunk/common/string.php (Diff revision 4) -
Same as above. ends_with("john", 0) probably evaluates true.
-
/trunk/www/wiki/MyTextile.php (Diff revision 4) -
This comment line seems out of place now. Maybe it should precede the if (!external-image) code path below.
-
/trunk/www/wiki/MyTextile.php (Diff revision 4) -
just plot/
-
/trunk/www/wiki/MyTextile.php (Diff revision 4) -
This code path is about rewriting `src` such that it points to the image resampling controller. It seems a bit misleading to have it depend on !$allow. Either $allow is a bad name or ignore $allow completely when branching. This is more about coding style, not correctness.
-
/trunk/www/wiki/MyTextile.php (Diff revision 4) -
. :)