JumpCloud

Posted 6th May 2016, responsibly disclosed 10th February 2015.

This was fixed on the 13th February 2015.


If you have multiple servers, JumpCloud allows you to manage your accounts from a single website.

Unfortunately an attacker, with a bit of social engineering (e.g. asking the victim to view a website, while they were logged onto JumpCloud), would be able to login to any server that the victim has access to.

This was because the JumpCloud website allowed an attacker use a simple Cross Site Request Forgery (CSRF), so they could add their SSH key to the victims list of authorised SSH keys.

They also did not expire sessions for 24 hours, so the window of opportunity was quite large.

I discovered this vulnerability when helping them identify a different problem, where JavaScript code was being shown as an error message. During this debugging, the web browsers developer tools clearly showed my SSH key was being sent via a simple GET XMLHttpRequest to "/userconsole/api/sshkeys", with a "name" and "public_key" value.

As XMLHttpRequest can used from any website, and contain the cookies for that website (e.g. session cookies), it will be processed as normal. This is why you need to guard against CSRF attacks.

Typically CSRF attacks are prevented by generating a random key, putting it in a Cookie, and in the GET or POST request. The server can then check that they are the same, as any malicous website would not be able to create a GET or POST request without knowing the random key (as they cannot see the cookies).


JumpCloud have fixed this problem, and a secondary issue of using Google Charts to show a QR code for the TOTP key (please don't send this kind of sensitive information to a third party).

However, I still have concerns with the service...

For example, any servers that use JumpCloud will connect to JumpCloud to retrieve updated SSH Keys, but it also allows the owner to run arbitrary commands (via a process that runs under the root account). While this makes admin tasks easier, it also means any compromise of the JumpCloud service (or your account) will result in a complete compromise of every server that receives those commands.

Their documentation seems to imply that only the "client certificate" is verified by the JumpCloud server, with no indication that the server connected to a valid JumpCloud server (so with a bit of DNS manipulation, your server could connect to a malicious server, which will then tell it to run any commands it likes).

I also got the impression they aren't familiar with escaping variables before adding them to the DOM, which is fundamental to avoid Cross Site Scripting attacks (XSS):

showAlert('danger ', '<strong>' + err + '</strong> Please try again or contact support.');
showAlert('success', '<strong>Public SSH Key "' + name.text() + '" has been deleted.</strong>');

Considering they are already using jQuery, I proposed changing their showAlert function to something like:

window.showAlert = function (type, message, fadeDelay, modalScope) { var message_node = $('<strong>').text(message); ...