Bargate is a web application that lets users access their files on SMB/CIFS servers within the corporate network. It thus connects to SMB/CIFS servers on behalf of the user and authenticates on their behalf as well. To do this it needs their password each time the user loads the page and thus connects to the back end SMB server.
The existing design
The existing security design of Bargate is predicated on the belief that the server should not be trusted to store the user’s password. If it stores the user’s password then any break in to the server / web application could obtain the list of stored user’s passwords. Encrypting them, whilst making an attack slightly more difficult, doesn’t solve the underlying problem since the application will need to have the decryption key stored on it in order to use them. An attacker could steal both in nearly all circumstances.
Bargate thus stores the passport in the user’s session which is client side (stored in cookies). It is encrypted first using AES 256-bit CFB, then put in the session, and the session is signed by itsdangerous before being put into a cookie for the user. The encryption/decryption key for the AES 256-bit step is stored in the Bargate configuration.
The danger in this design is:
- The encrypted password is sent across the network on every request (even if it is over SSL)
- The encrypted password is stored in the cookie and thus on a myriad of end user devices, for perhaps up to 30 days (depending on session lifetime)
- If an attacker gains access to the ENCRYPT_KEY (stored on the server) it can decrypt any password stored on any end user device, and gets the user’s actual password
This design was chosen of course because storing the password on the server, with or without encryption, is even worse. It would also mean any flaws in Bargate to allow attackers to steal a user’s session would work without without first having to first compromise the end user’s device as is the case today. Today if there are any flaws like that in the code they are innocuous as the attacker won’t have the encrypted password, and thus won’t be able to access any systems.
The new design
What we want to achieve is quite simple:
- The bargate server, if attacked, can’t be used to steal user passwords (i.e. don’t store users passwords in plain text and don’t store them encrypted if the encryption key is known by the application)
- The end user device, if attacked, can’t be used to get the user password or even the encrypted password
- The user’s password or encrypted password should not be sent over the wire on every request, only at log on time
The password of course has to be stored somewhere, but it does not have to be stored in plain text, and the place where it is stored does not have to have the encryption key. That is how it works today – its stored on the client which doesn’t have the encryption key – but this has several downsides. Instead the new Bargate authentication system will store the password encrypted on the server, but encrypted with a key stored in the user’s session, thus reversing the design.
- Passwords are no longer encrypted using the same encryption key for every user, each session has a unique encryption key.
- The end user device does not store the password in any form, which allows the deploying company/group/user to focus on server security rather than end user device security (especially important in the age of BYOD).
- Attacking the end user’s device gives the attacker no useful information. If you get access to the per-user/session encryption key stored on the client this key only decrypts an encrypted password the client never has and never will have.
- The encrypted password is not sent over the network on each request
- The decryption key sent over the network on each request is itself encrypted by a key known only by the server, so it is useless to an attacker eavesdropping on the connection (if they had broken TLS).
The new design in detail
- The end user logs into Bargate by sending their username and password over TLS
- Bargate checks the username and password via LDAP, Kerberos or “SMB”
- Bargate generates a 32-byte (256-bit) session encryption key for the user
- Bargate encrypts the user’s password using the session encryption key and stores it on the server (most likely in Redis with an expiration)
- Bargate encrypts the session encryption key using ENCRYPT_KEY (a bargate config option) and stores it in the user’s session. Bargate does not store the session encryption key any longer.
- The user’s browser saves the encrypted decryption key in the browser’s cookie storage
- The user’s browser is redirected to view a file server
- The user’s browser presents the encrypted decryption key to the server as a cookie over TLS
- Bargate decrypts the decryption key using ENCRYPT_KEY
- Bargate uses the resulting decryption key to decrypt the password stored in Redis
- Bargate uses the decrypted password to authenticate to the SMB server on the user’s behalf
Remaining attack vectors
There are two remaining attack vectors.
- Session hijacking
- An attacker can still take session cookies off a client and then use them. This threat is reduced with TLS and http only cookies, but an attacker could still get to them. This is a generic problem with web applications however. Adding restrictions to lock sessions to an IP address is an option, but can be disruptive and is of limited benefit.
- Attacker with access to both the server and client
- If the attacker has compromised both ends, well, you know, game’s over anyway.