2

There is a peice of software i am using at work that has several components to it, lets call them the server and agents.

the server runs an api over https that the agents use to communicate with it.

the server can be cloud hosted or locally hosted.

the entire api is accessible without any authentication process by providing the guid for a given agent in the header of the request. the api is also available for non agents to use (though the published functionality available is slightly different its the same api with no special restrictions to identify if its an agent or just random http request from anyone)

these guids are not visible in the web front end of the server application, nor in the gui for the agent application. and the agent is not going to be running on user machines - more like IT staff only accessed vms.

the api allows extraction of passwords and other data that is stored encrypted on the db. depending on how much you trust this software you may store some very powerful credentials in there.

the guids appear to be .net generated using version 4 i think its called (sorry i have limited security knowledge) as in the first character of the third grouping is a 4 when in the MS format, i don't see any any code in the db to create the guids and its a asp.net web app that hosts the api.

calls to the api don't appear to be rate limited, even for multiple not authorised requests, there appears to be no subnet or ip address filtering going on - apparently not even on the cloud instance (though again i am no security person, maybe i am on a watch list now and everything i send them is treated differently)

these guids are stored unencrypted in the server application DB.

i raised this with the vendor as a ticket and they basically say its as per design, and to their credit they investigated this VERY fast (given the apparent size of the company).

am i crazy in thinking this is very bad?

Seems like now anyone with db access, agent access or network hardware access now has the ability to get whatever they want. also a momentary failing of https traffic for some reason (e.g. you use the cloud instance and for a short period of time someone manages to man-in-the-middle you) and until you delete those agents you are wide open. without even logging of access to extract credentials? - at least from me as the clients perspective i don't see it (other than if i went to look at IIS logs on a local instance i guess).

Apparently the guids cannot be predicted (as in i cannot register a bunch of agents with the cloud instance and predict what the next customers guid will be) but it seems weird that if i authenticate with the api the one time access token i get is many times more complicated that a guid but is only valid for that session, while the guid lasts basically forever.

You can divide agents up logically to restrict what data they have access to, something which has all of sudden become very significant now that i have found this potential hole, so maybe its just on me to make the business aware of this etc?

Maybe there is just no way round this issue for this type of application, i have never written anything like this. but at the very least i would expect some attempt at tightening this restriction

  • restrict use of this key to known ip addresses (or at least generate a warning when ip addresses change or make it an option)
  • only use the key in initial handshake then use a token from there on in so not all traffic is vulnerable
  • maybe create a new one of these keys each time the agent successfully connects to the server

i don't know, as i said i have never written a server-agent type application, maybe i am just naive?

  • One bit I'm confused about: how do you know that the GUIDs are stored unencrypted in the database? Are you able to read the list of GUIDs out of the database somehow? Or does the API properly silo you to only reading your own data? – Conor Mancone Oct 11 at 12:23
  • This became obvious consuming the api and doing some debugging. I installed our dev and test environments so i have db access and can see the keys. If they have it in the cloud instance the same then they are one un traceble step from their admins being able to read customer credentials including windows logins. Hopefully this is not the case – gordon Oct 11 at 14:24
2

When wondering whether a certain security measure is sufficient, the question is: what threat should it be protecting against? Or, seen from the attacker's side: what does it not protect against?

A version 4 GUID is some 120 bits of randomness. Assuming that their code uses a CSPRNG for generating these GUIDs, this is perfectly unpredictable. Without any other knowledge, an attacker could never guess this token. You would have to find some other vulnerability (thereby getting access to an existing token) in order to impersonate someone.

Does that mean this is perfectly secure? Is this the best possible system? No, that is not the case.

As you mentioned, the tokens are long-lived. If the token is obtained by an attacker at any point in time, the attacker will have indefinite access until the attacker is detected and the token revoked (removed from the database of valid tokens). This is already better than a system like JWT, where tokens can't be revoked and some hybrid system of short-lived access tokens and long-lived refresh tokens has to be used. But what about using a shorter-lived token here as well? Those are great, but you have to consider: how does a legitimate user obtain a new token once the old one expired? Whatever the answer is: could an attacker do the same thing? You would have to require some extra confirmation that an attacker can't do. Typical examples are email confirmation or a cookie that is only set in the browser of the user. Similarly, 2-factor authentication could be used.

To prevent anyone with read-only access to the table of valid tokens to escalate their privileges to that of a valid user, hashing can be used. Since the GUIDs are (assumed to be) strong by themselves, this can be as simple as applying a single round of SHA-256 to it (no salt or pepper needed). If an attacker now has read-only access to the table of valid tokens, they would have to crack the ~120-bit token before being able to obtain the GUID that they can use to make requests. Cracking a 120-bit token is impossible for the foreseeable future.

Against TLS failing, one would basically be implementing a variant of TLS on top of the existing TLS: if TLS fails, but you still want all the guarantees of TLS (non-replayability, integrity, confidentiality), you are basically reinventing TLS. Given the sensitivity of this system (you mention "the api allows extraction of passwords"), defense in depth might make sense, but it does feel like overkill with a potential for crypto soup (might introduce other vulnerabilities as well as giving a false sense of security).

In conclusion, I don't see an immediate issue with this system. Some hardening can be applied (hashing the tokens in the database, two-factor authentication), but this doesn't sound inherently vulnerable to me. Secret tokens for API access are common practice. To get unauthorized access to the authenticated API calls, it seems that one would have to find and leverage other vulnerabilities first.

  • (thanks, cant upvote :) )..I had thought there were some base level difficulties in making a system like this secure. would there be a scale of application that you would insist on this improving on? i am super reluctant to give details, but lets say millions of installs at large scale orgs, probably holding very powerful credentials in many cases? though they could be adding security layers themselves – gordon Oct 11 at 10:18
  • .. e.g. now they say its by design i will be proposing firewall rules etc. to help mitigate this – gordon Oct 11 at 10:20
  • @gordon If I understand you correctly, you're asking for what they could do to improve security. One example would be adequate logging and perhaps automatically flagging suspicious events, but general hardening recommendations is a super broad question and the answer depends on circumstances and details that you apparently can't give. (If you want to talk more privately, feel free to send me an email -- see my profile for the address and PGP key.) – Luc Oct 11 at 10:30
  • UUIDv4 is generated randomly and should, in theory, be unpredictable. However, it's probably unwise to assume that the library you used to generate your UUIDv4 used a properly seeded CSPRNG. For all we know, the library might have done something like rng.seed(unix_timestamp_in_second()), which might look random on cursory investigation but is actually quite predictable. – Lie Ryan Oct 11 at 12:56
  • Afaik the default guid.newguid with modern .net is pretty good in meeting standards etc, but i dont really know anything. – gordon Oct 11 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.