Over the last year we have been putting increasing focus and dev time on security in Unimus. This culminated with a full pentest of the Unimus API and the Unimus web GUI a couple of months ago. In this post, we want to share the pentest results with you - as per our full transparency policy.
In summary, we are quite happy with the outcome, and the state of security in Unimus. With only a single high severity issue discovered (which has already been fixed), and a few other lower severity issues present, this is a very positive result.
With Unimus being an on-premise application - where each customer's (your) instance and data is completely separate from others and you are in complete control of access to your instance; any issues and their potential impact are greatly mitigated as well.
Let's look at the discovered results in more details...
High severity issues
Starting with the biggest issue - post-auth XSS injection in the Unimus GUI. An authenticated attacker could inject XSS code in multiple places in Unimus. This is definitely a major issue, however Unimus being on-premise, and injection being possible only from a properly authenticated account are mitigating factors.
As we mentioned above, this has already been fixed in the 2.2.3 release, and we highly recommend all customers upgrade to this release.
Medium severity issues
There are a few medium severity issues in both the API and the web GUI. We plan to tackle these issues one-by-one over the rest of the year. Here are our notes on the individual issues.
B1) Insecure Direct Object Reference (IDOR) in the Unimus API
This simply means that the API (APIv2 specifically) uses database IDs as object identifiers in API calls. We have already migrated to using UUIDs in APIv3, so this issue will be completely gone once APIv2 is fully replaced by APIv3.
B2) No expiration on JWT tokens for the Unimus API
All API tokens currently have infinite lifetime. We will introduce a new option to limit lifetime of API tokens (you will still have the option to create "infinite" tokens if you wish).
This will be a new optional checkbox during API token creation, which will allow you to set a "Lifetime" for a token.
B3) Session fixation allows theft of session cookie in special cases in the Unimus web GUI
In special cases, the session auth cookie could be stolen - and allow the attacker to hijack the authenticated user's session. This is difficult to pull off, and requires access to the user's local PC / cookie storage. As such, this is not high severity - since if the attacker has full access to the user's PC, all bets are off anyway.
There are some technical challenges in our web GUI framework which make this a bit difficult to fix - but we will be put time into research later in the year to see if we can improve our session handling.
B4) Response time based account enumeration allows to find valid application login names in the Unimus web GUI
This is a fun one - an attacker can differentiate between valid and invalid usernames based on the time it takes Unimus to return a failed auth response. This is because for invalid usernames, cryptography (hashing) on the provided password is not performed, and as such invalid username handling is faster.
In theory, an attacker can fire tons of auth requests with random usernames, and the "slow" (in relative terms) auth failures are likely to be valid usernames.
Here are examples of how this looks:
|Response time (ms)
As you can see, there is still jitter, but a pattern is definitely distinguishable. Unimus being on-premise is again a huge mitigation factor here however - as you are in full control over who can access your instance. Using external auth (like Radius or LDAP) will also make this attack unfeasible.
We are currently debating on how to approach this, as solutions for this are not as straight-forward as they might seem.
Low severity issues
C1) No Function Limiting in the Unimus API
This simply means that there is no request rate limiting in the Unimus API. If you want to implement request limits, we would highly recommend doing so on a front-end proxy server (such as an NGINX server acting as a reverse proxy).
C2) Invalid Credential UUID Accepted For Delete in the Unimus API
The APIv3 allows you to call delete methods with any strings in the "uuid" field and will return a HTTP 200 response. If the submitted value is not a valid and existing UUID, nothing will however happen. We will implement input validation and return a proper error HTTP response code if the submitted value is not in the UUID format.
C3) Missing Lock Out in the Unimus API
This is related to C1 - in that the Unimus API will allow any number of requests without throttling, whether the submitted request does or does not have a valid token.
As with C1, this can be taken care of on the front-end proxy server (such as an NGINX server acting as a reverse proxy).
C4) No account lock out policy allows password guessing attacks in the Unimus web GUI
The Unimus web GUI allows an unlimited number of auth attempts. We are conflicted on whether we should add a lockout mechanism - since Unimus is on-premise and you have control over who can access your Unimus instance. We know login lockouts can cause a lot of frustration...
Either way, Unimus does already have notifications and logging on invalid login attempts. We highly recommend either setting up alarms on logs, or enabling our built-in failed login notifications, so you are informed if someone is trying to break in to your Unimus instance.
Like we mentioned in the Overview, we are happy that our focus on security over the last year lead to good pentest results. Going forward, we plan to resolve the outstanding issues as described above for each, and we are going to keep treating security as one of the fundamental priorities in Unimus.
If you are interested in full pentest reports rather than the summaries (or you need them for compliance), please feel free to reach out to us.
We hope this was an interesting read, should you have any questions, please feel free to post in the Support section of our forums.