MyBB Community Forums

Full Version: Cross Site Request Forgeries (CSRF)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
This problem is not exclusive to MyBB, other forums suffer from it as well. However, it has not been used in any large-scale hacks yet, so it is not that well known.

An example of how CSRF works:
  • Bad guy creates a .htaccess file in his site ( e.g., http://bad.guy.ws ) :
    Redirect 302 /a.jpg http://your.forum.here/newthread.php?subject=V14GR4&message=CH34P V|4GRA H3R3!!&submit=1&action=new_thread&fid=2
  • Bad guy comes to your forum and posts an innocent-looking post including
    [img ]http://bad.guy.ws/a.jpg[/ img]
    in it.
  • Every view of this post spawns a new thread in your forums telling you about Cheap Viagra, "posted" by the user viewing the post.

Of course, a real bad guy might just change that redirect url into one that adds his user to the admin usergroup, deletes a random post, simulates a visit to his site (to spin up hit counters) or whatever he wants!

Issues (as I understand them):
  • Bad: There is no alt text provided for user-posted images, so compliant browsers will not even display anything out of ordinary. IE, however, will show a red [X] instead of an image. Oh the irony. Adding an alt-text would be at least an indication that an image is missing... Which can be due to various reasons, however, not only CSRF.
  • Good to know: On MySQL 5 in Strict mode, long requests fail since MySQL refuses to truncate the url to fit in the sessions.location column, which is VARCHAR(150) . Older versions happily truncate the data instead of erroring out the request. However, MyBB doesn't work properly with MySQL 5.
  • Bad: Requests that are refused due to insufficient user rights (e.g., a query that edits the user in ACP when the viewing user hasn't logged into ACP) die silently, and don't show any indication of failure.
  • Good: If your ACP is under .htpasswd or similar protection, and you aren't logged in, a CSRF targeting your ACP will create a prompt asking you to log in, thus alerting you to the problem. Don't log in, obviously.
  • Bad: The bad guy is not limited to .htaccess 302, he can even set up that directory to execute png files as php, imagination is the limit. It's basically a GET request to his site, which he can process how he pleases.
  • Bad: The attack works even if he posts the image in some other forum, all those visitors viewing his post would still "post" at your forum, albeit most likely as guests, since there is no guarantee they are registered in your forum.
  • Good: Requiring your forum url as a referer can prevent the last issue. (Mind the privacy-lovers with blank referers, though.)
  • Good: Requiring POST and not GET for any sensitive pages can somewhat reduce the problem, at least to my knowledge, however, some experts tend to disagree. I am not aware of any redirection method which would force a browser to POST the stuff with the correct session identification. (A quick GREP says MyBB only enforces POST for "deletepost", nowhere else.)
  • Good: You can reduce the risk significantly by adding a hidden input "token" set to some session-specific value, and refusing potentially exploitable requests without it.

(I was going to create a proof-of-concept to add to my rep here with each view, but the admins disabled the rep system. Heh.)

Credits: http://ha.ckers.org/ - basic CSRF / XSS info.
MyBB 1.2 covers the following:

- Full MySQL 5 compatibility
- Admin CP can't be targetted due to it using session IDs in the URLs and a valid session is required to do anything
- POST requests are only accepted for the "do_" actions
Well, that's why you should accept certain input only from POST. (i.e. $_POST for post and $_GET for get or at least different variables for each kind of data). IPB should be affected by this as well since they merge the POST and GET array into one input variable.

Quote:Good: Requiring your forum url as a referer can prevent the last issue. (Mind the privacy-lovers with blank referers, though.)
I am not 100% sure but I think mod_rewrite carries on the original referer (the topic/post where the image was added to), and that's what is displayed as the referrer. So this won't work!

Quote:Good: You can reduce the risk significantly by adding a hidden input "token" set to some session-specific value, and refusing potentially exploitable requests without it.
Yeah... that's cool and even prevents bots. BTW, if you just can differentiate between POST and GET requests and expect most input to come from POST, then you're safe enough. Well, using such a way, the hackers cannot force user into sending a POST request.

The GET request works because it's forcing a browser redirect. Even though an [R] directive isn't added over there, it's meant to do a browser redirect and since MyBB doesn't differentitates between GET and POST (I am not sure, so please correct me if i am wrong.. Well, at least it's true for IPB), it gets executed without a problem.

Yes, Chris is right about the different system of Admin CP.


To MyBB Developers:
Please either use $_SERVER['REQUEST_METHOD'] to check for POST method on posting and replying pages or use the posting hash, or at best start using $mybb->input_get and $mybb->input_post as necessary instead of merging GET and POST variables in one array.

Edit: I just noticed 1.2 includes posting hash, is it a new addition after this topic was posted?
Asad_Niazi Wrote:
Quote:Good: Requiring your forum url as a referer can prevent the last issue. (Mind the privacy-lovers with blank referers, though.)
I am not 100% sure but I think mod_rewrite carries on the original referer (the topic/post where the image was added to), and that's what is displayed as the referrer. So this won't work!
By "last issue", I meant the issue right above that one, the one about this working even when the post is not in your forum, but somewhere else. The "somewhere else" would be carried over as the referer in that case.

Asad_Niazi Wrote:To MyBB Developers:
Please either use $_SERVER['REQUEST_METHOD'] to check for POST method on posting and replying pages or use the posting hash, or at best start using $mybb->input_get and $mybb->input_post as necessary instead of merging GET and POST variables in one array.

Edit: I just noticed 1.2 includes posting hash, is it a new addition after this topic was posted?

Posthash is an old feature, it is used for attachment management afaik. But I don't see the point in splitting the input into _get and _post, I think a per-session(per-user even, for when a valid session expires while someone is typing up a copy of The Great Expectations into the New Thread box) token paired with the simple check of $mybb->request_method is sufficient, or at most simply not importing $_GET into input when parsing a POST request. For the moment, I've implemented Chris's suggestion as a plugin for global_start:
 if(substr($mybb->input['action'], 0, 3) === 'do_' && $mybb->request_method !== 'post')
 {
	redirect($mybb->settings['bburl']);
 }

Btw, as I mentioned, this is not limited to newreply/newthread, it basically allows any action to be carried out, including, for example, moderation.php?action=stick&tid=11634 (which, btw, doesn't have a do_stick right now) or a redirect to www.crapsite.info to boost his advert income.
Asad, as mentioned by Chris, MyBB 1.2 does indeed check if the request method is post before changing anything.
Asad_Niazi Wrote:To MyBB Developers:
Please either use $_SERVER['REQUEST_METHOD'] to check for POST method on posting and replying pages or use the posting hash, or at best start using $mybb->input_get and $mybb->input_post as necessary instead of merging GET and POST variables in one array.

Edit: I just noticed 1.2 includes posting hash, is it a new addition after this topic was posted?

Yes, we use $_SERVER['REQUEST_METHOD'] ($mybb->request_method)
Dcoder Wrote:But I don't see the point in splitting the input into _get and _post
I suggested so that certain input is accepted only from $_POST superglobal. The point is, the input will only be accepted via POST and thus preventing any issues. Well, there's a reason some web applications are using POST for most of the actions, and some even for logout (arggh, it can get really annoying if a user forwards it to logout link!). But yeah, we can ofcourse check for request_method instead of separating the variables, but it is good to have them separated as input can be differentiated on per request basis.

Requiring session IDs in the url could be annoying but relying on POST for most of the actions won't be that annoying. Or we can embed n require a session id wherever there's an action that needs to be performed with GET request.

BTW, MyBB's logout link is safe enough with the user id requirement Smile ..

Peter Wrote:Asad, as mentioned by Chris, MyBB 1.2 does indeed check if the request method is post before changing anything.
Glad to know that Smile ..
Forgive me if I am wrong but can't the img tag also be cleaned better to check for an actual image? I would think that easier to fix.

I remember when img bbcodes were exploited for sql injection....easily fixed then.
labrocca Wrote:Forgive me if I am wrong but can't the img tag also be cleaned better to check for an actual image? I would think that easier to fix.

I remember when img bbcodes were exploited for sql injection....easily fixed then.

The problem with that is it can be an actual image when posting and the hacker can put in place a redirect later on. Checking all images of the topic on each load isn't realistic as that will put on huge strain on the servers.
Asad_Niazi Wrote:The problem with that is it can be an actual image when posting and the hacker can put in place a redirect later on. Checking all images of the topic on each load isn't realistic as that will put on huge strain on the servers.
And then there's the fact you can't really tell whether or not it is a proper image, I think.
Pages: 1 2