Zapier Twilio credentials storage: how safe is that? - security

While creating a Twilio Zap (and others), we are required to provide the Account Sid and the Account Token for your existing Twilio account.
I suppose this is stored by Zapier somewhere (hopefully with reversible crypto), otherwise they cannot execute future requests. Does anybody know how safe is this? Have they published any information about how they protect this data?
EDIT
Well, nothing some googling couldn't help
https://zapier.com/help/data-privacy/
Yes, they encrypt the data with AES and store the keys separately. I guess there will always be the danger of data breaches, but that's the trade-off.
I just wonder why their own login credentials use SHA (with 1000 iterations), while I believe the most recommended would be bcrypt.

Zapier co-founder here, we've recently updated to use PBKDF2 with 10k iterations (the standard Django hashing scheme). We'll progressively update these from time to time as standards dictate.

Related

is electron's `safeStorage` for passwords and login credentials?

I need to store login credentials with electron js because it doesnt save them like all browsers. I have seen a lot of questions like this, but I never found a solution. I have seen in the electron docs about the safeStorage feature. is the it safe enough/good enough to store login credentials on the client side? if not what other tools are available to do that? I have heard about keytar but is it good?
The safeStorage api in electron exposes OS-level encryption/decryption using current user's secret key - please refer to electron source and chromium's os_crypt. On windows it utilizes DPAPI while on *nixes it uses whatever password manager the OS has as the documentation suggested.
is the it safe enough/good enough to store login credentials on the client side?
Depends, you should define "secure" first.
Ask yourself, should the same user allowed to read whatever value inside the encrypted text? A tech-literate person might write his own tools to decrypt things you store using that API you are out of luck. See this QA for further discussion.
if not what other tools are available to do that?
There are a lot of tools (and encryption algorithm) to encrypt stuff in nodejs. However, you have to remember an encryption require you to have a key of some sort and the key need to be protected too. Hence, try your best to avoid egg-chicken problem with your key of keys.
OS-based key storage avoids the key of keys problem by storing the "master key" in a way that only accessible using its API. At runtime, you can't retrieve the key at all, you just send a set of bytes for the OS to magically encrypt/decrypt. While at rest, the OS may rely on secure storage such as TPM (Trusted Platform Module).
is electron's safeStorage for passwords and login credentials?
Depends, if you are running a web service it is preferrable to not doing so. You should never dump end user's user name/password directly on a storage that you can't guarantee its safety by yourself (e.g. your server). You should, put an identifier which can be revoked or may expire at later date - token or cookies.
Imagine the trouble when your end user device get stolen. If it's a token/cookie, they can request you to revoke their access from that device - similar to "Log me out from all other device."
However, if its an in-situ application that authenticates to itself then its a fair game - though keep in mind about the first point. Its all down to your security model.

Application to Application authentication/access control without HTTPS

On the current project I'm working on, we have the following problem.
Our software is a Location Based Services platform and applications can connect and use our services through our exposed webservices using SOAP. Until now our platform was only used by internal applications, but now we would like to open it for third party applications. For that we need an authentication mechanism.
Because of our customers' infrastructure and load balancing solution, we cannot use HTTPS. The original idea was that applications can just use HTTPS and send the password we authenticate.
A solution would be the next:
The application has the password. The application generates a random string (salt) and creates a hash. Then the application creates an HTTP request sending the hash, the salt and a timestamp. This three is enough for us to authenticate, as we can generate the same hash and compare.
My problem is that for this we need to store the password in our database in clear text, because we need to do the same process using the given salt so we can compare the result and authenticate the application. Storing passwords in clear text is unacceptable.
Do you know about any authentication/access control mechanism that would fit this situation? Generally, do you know about any good books/sources about application authentication/access control mechanisms?
Any help is highly appreciated. Thanks in advance!
The application (client) can hash the password two times. Note that the server should generate the other random salt, not the client! Otherwise the attacker can log with this hash also. You can also make it safer by storing password specific salt in the database.
The protocol:
0) servers retrieves salt for that particular password from database, generates salt2, and sends both to the client
1) client sends hash(hash(password, salt), salt2, timestamp) and timestamp.
2) server retrieves hash(password, salt) from the database and compares.
Note that if you are on the network where attackers can not only sniff, but also modify the traffic, as Paulo pointed out, you should sign EVERY message: hash(hash(password, salt), salt2, timestamp, message) and check it at server. (E.g. for the case when the attacker could modify the message to contain delete command...)
Note that there is still a problem when user needs to SET/CHANGE the password safely. You cannot do it safely with just hash function over unsafe network, you need some kind of cipher/decipher.
Also note that the slower the hash function is, the safer (because of the dictionary attack). If you don't have access to special slow hash function, you may also call normal fast hash function 100000 times.
Instead of inventing your own solution, you should use an established one. SOAP has support for cryptographic authentication such as WS-Security - see Craig Forster's comment on this answer for suggestions.
The best choice in other cases is usually oauth; it provides both authorization and authentication, and deals with a lot of cryptographic issues that you're not likely to spot when building your own.
Using an authentication solution which does not contain an integrity check of the whole message (or stream) is insecure.
While the hashing solution originally proposed by Thomas T. (hash(hash(password, salt), salt2, timestamp), where hash(password, salt) is stored in the database, and salt2 is newly generated) makes sure than an attacker can't get the password (or any data which will be useful for logging in after the timestamp expires), it alone does not prevent an active attacker to hijack the session after the authentication, and send any SOAP requests wanted (and intercept the responses).
What would be needed here is some way to make sure that no data is changed. This is known as a message authentication code (MAC). The usual definition of a MAC includes some (shared secret) key and the message as input, and an authentication token as output.
The usual way to use this would be to do some authenticated key exchange at the beginning of the communication (using either a shared secret or some known public key), and then use a part of the now shared secret as the MAC key, which is then used to authenticate following messages.
(Doing this then essentially is a reinvention of SSL/TLS (or parts thereof), potentially doing the same mistakes again.)
If you have only one message to send, you can instead use the MAC as a kind of symmetric signature, using the password hash (salted and generated with a slow hash function) as a MAC key.
Another way to view this would be to take the message to authenticate as an input to the outer hash in Thomas T's authentication scheme. (Make sure to authenticate everything that is worth authenticating.)

Commonly used solutions for credential caching?

I have question about credential caching in applications. I've searched around on the net for solutions to this problem, but I haven't found anything (which is really surprising, since this is something that every Facebook, Twitter, and email client application has to deal with).
My question is this:
Let's say I'm building some simple Twitter client. I don't want to force the user to enter their password every time. How do most applications tackle this problem? At some point, the client needs to make an API call to authenticate (which includes the password, which is usually in plain text). However, saving the password in plain text somewhere not the correct solution, obviously. So, how do most apps do this safely? I suppose you could cache the password in a file or db if the password is encrypted, but then how do you safely store the decryption key? Or is it generated at runtime using unique information from the client machine as a seed?
Are there any resources (articles, books, etc.) that talk about this? How do most apps handle this?
Thanks!
Single-sign-on (SSO) setups accomplish what you describe typically by providing centralized methods to generate, distribute and validate a key using some type of session ID.
See for one method (used by StackExchange/StackOverflow):
http://openid.org/
Here's something I didn't know: This category of functionality is known as Federated Identity. For instance, our web system where I work offers (but doesn't require) Shibboleth. See here for a list of options:
http://en.wikipedia.org/wiki/Category:Federated_identity

How can you encrypt users' data server-side without ruining the experience?

Many users – myself included – would like the security of having everything they do on a web service encrypted. That is, they don't won't any one at the web service to be able to look at their: posts, info, tasks, etc...
This is also major complaint in this discussion of an otherwise cool service: http://news.ycombinator.com/item?id=1549115
Since this data needs to be recoverable, some sort of two-way encryption is required. But unless you're prompting the user for the encryption key on every request, this key will need to be stored on the server, and the point of encrypting the data is basically lost.
What is a way to securely encrypt user data without degrading the user experience (asking for some key on every request)?
-- UPDATE --
From #Borealid's answer, I've focused on two possibilities: challenge-response protocols, where no data (password included) is sent in the "clear", and non-challenge-response protocols, where data (password included) is sent in the "clear" (although over HTTPS).
Challenge-response protocols (specifically SRP: http://srp.stanford.edu/)
It seems that its implementation would need to rely on either a fully AJAX site or using web storage. This is so the browser can persist the challenge-response data during encryption and also the encryption key between different "pages". (I'm assuming after authentication is completed I would send them back the encrypted encryption key, which they would decrypt client-side to obtain the real encryption key.)
The problem is that I'm either:
fully AJAX, which I don't like because I love urls and don't won't a user to live exclusively on a single url, or
I have to store data encryption keys in web storage, which based on http://dev.w3.org/html5/webstorage/ will persist even after the browser is closed and could be a security vulnerability
In addition, as SRP takes more than one request ( http://srp.stanford.edu/design.html ), there needs to be some persistence on the server-side. This is just another difficulty.
Traditionally
If I'm ok transmitting passwords and data in the clear (although over HTTPS), then the client-side issues above are not present.
On registration, I'll generate a random unique encryption key for the user, and encrypt it using their password and a random salt.
In the database, I'll store the user's password hash and salt (through bcrypt), encrypted encryption key, encryption key salt, and encryption iv.
After an authentication, I'll also need to use their password to decrypt the encryption key so that they may view and enter new data. I store this encryption key only temporarily and delete it when they explicitly "log out".
The problems with this approach is that (like #Borealid points out) evil sysadmins can still look at your data when you are logged in.
I'm also not sure how to store the encryption keys when users are logged in. If they are in the same data store, a stolen database would reveal all data of those who were logged in at the time of theft.
Is there a better in-memory data store for storing these encryption keys (and challenge data during an SRP authentication)? Is this something Redis would be good for?
If the data need to be recoverable in the event of user error, you can't use something like a cookie (which could get deleted). And as you point out, server-side keys don't actually secure the user against malicious sysadmins; they only help with things like databases stolen offline.
However, if you're running a normal web service, you've already gotten pretty lucky - the user, in order to be unique and non-ephemeral, must be logged in. This means they go through some authentication step which proves their identity. In order to prove their identity, most web sites use a passed credential (a password).
So long as you don't use a challenge-response authentication protocol, which most web sites don't, you can use an encryption key derived from a combination of a server-side secret and the user's password. Store the encryption key only while the user is authenticated.
If you do this, the users are still vulnerable to sysadmins peeking while they're using the service (or stealing their passwords). You might want to go a step further. To go one up, don't send the password to the server at all. Instead, use a challenge-response protocol for authentication to your website, and encrypt the data with a derivative of the user's password via JavaScript before uploading anything.
This is foolproof security: if you try to steal the user's password, the user can see what you're doing because the code for the theft is right there in the page you sent them. Your web service never touches their data unencrypted. This is also no hindrance to the normal user experience. The user just enters their password to log in, as per normal.
This method is what is used by Lacie's storage cloud service. It's very well done.
Note: when I say "use foo to encrypt", I really mean "use foo to encrypt a secure symmetric key which is then used with a random salt to encrypt". Know your cryptography. I'm only talking about the secret, not the methodology.
None of those other solutions are going to maintain the feature set requested -- which specifically wants to preserve the user experience. If you look at the site referenced in the link, they email you a nightly past journal entry. You're not going to get that with JavaScript trickery per above because you don't have the browser to depend on. So basically this is all leading you down a path to a degraded user experience.
What you would want, or more precisely the best solution you're going to find in this space, is not so much what wuala does per above, but rather something like hush.com. The handling of user data needs to be done on the client side at all times -- this is generally accomplished via full client-side Java (like the Facebook photo uploader, etc), but HTML/JavaScript might get you there these days. JavaScript encryption is pretty poor, so you may be better off ignoring it.
OK, so now you've got client-side Java running a Journal entry encryption service. The next feature was to email past journal entries to users every night. Well, you're not going to get that in an unencrypted email obviously. This is where you're going to need to change the user experience one way or the other. The simplest solution is not to email the entry and instead to provide for instance a journal entry browser in the Java app that reminds them of some old entry once they get to the website based on a link in the daily email. A much more complex solution would be to use JavaScript encryption to decrypt the entry as an attachment inline in the email. This isn't rocket science but there is a fairly huge amount of trickery involved. This is the general path used by several web email encryption services such as IronPort. You can get a demo email by going to http://www.ironport.com/securedemo/.
As much as I'd love to see a properly encrypted version of all this, my final comment would be that journal entries are not state secrets. Given a solid privacy policy and good site security semantics, I'm sure 99% of your users will feel just fine about things. Doing all this right with true security will take an enormous amount of effort per above and at least some design/UE changes.
You should look into the MIT project CryptDB which supports querying an encrypted database using a subset of SQL. (see the forbes article, mefi thread, or Homomorphic encryption on wikipedia)
There is the Tahoe-LAFS project for cloud storage too, which conceivably could be leveraged into a fully anonymous social networking application, one day in the distant future.
If you want to perform computations on a server without even the server being able to see the data, you may be interested in knowing about fully homomorphic encryption. A fully homomorphic encryption scheme lets you perform arbitrary computations on encrypted data, even if you can't decrypt it. However, this is still a topic of research.
For now, I guess your best bet would be to encrypt all posts and assign meaningless (e.g. sequential) IDs to each one. For a more in-depth discussion of how to encrypt server-side data with today's technology, look up.

I need resources for API security basics. Any suggestions?

I've done a little googling but have been a bit overwhelmed by the amount of information. Until now, I've been considering asking for a valid md5 hash for every API call but I realized that it wouldn't be a difficult task to hijack such a system. Would you guys be kind enough to provide me with a few links that might help me in my search? Thanks.
First, consider OAuth. It's somewhat of a standard for web-based APIs nowadays.
Second, some other potential resources -
A couple of decent blog entries:
http://blog.sonoasystems.com/detail/dont_roll_your_own_api_security_recommendations1/
http://blog.sonoasystems.com/detail/more_api_security_choices_oauth_ssl_saml_and_rolling_your_own/
A previous question:
Good approach for a web API token scheme?
I'd like to add some clarifying information to this question. The "use OAuth" answer is correct, but also loaded (given the spec is quite long and people who aren't familiar with it typically want to kill themselves after seeing it).
I wrote up a story-style tutorial on how to go from no security to HMAC-based security when designing a secure REST API here:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
This ends up being basically what is known as "2-legged OAuth"; because OAuth was originally intended to verifying client applications, the flow is 3-parts involving the authenticating service, the user staring at the screen and the service that wants to use the client's credentials.
2-legged OAuth (and what I outline in depth in that article) is intended for service APIs to authenticate between each other. For example, this is the approach Amazon Web Services uses for all their API calls.
The gist is that with any request over HTTP you have to consider the attack vector where some malicious man-in-the-middle is recording and replaying or changing your requests.
For example, you issue a POST to /user/create with name 'bob', well the man-in-the-middle can issue a POST to /user/delete with name 'bob' just to be nasty.
The client and server need some way to trust each other and the only way that can happen is via public/private keys.
You can't just pass the public/private keys back and forth NOR can you simply provide a unique token signed with the private key (which is typically what most people do and think that makes them safe), while that will identify the original request coming from the real client, it still leaves the arguments to the comment open to change.
For example, if I send:
/chargeCC?user=bob&amt=100.00&key=kjDSLKjdasdmiUDSkjh
where the key is my public key signed by my private key only a man-in-the-middle can intercept this call, and re-submit it to the server with an "amt" value of "10000.00" instead.
The key is that you have to include ALL the parameters you send in the hash calculation, so when the server gets it, it re-vets all the values by recalculating the same hash on its side.
REMINDER: Only the client and server know the private key.
This style of verification is called an "HMAC"; it is a checksum verifying the contents of the request.
Because hash generation is SO touchy and must be done EXACTLY the same on both the client and server in order to get the same hash, there are super-strict rules on exactly how all the values should be combined.
For example, these two lines provides VERY different hashes when you try and sign them with SHA-1:
/chargeCC&user=bob&amt=100
/chargeCC&amt=100&user=bob
A lot of the OAuth spec is spent describing that exact method of combination in excruciating detail, using terminology like "natural byte ordering" and other non-human-readable garbage.
It is important though, because if you get that combination of values wrong, the client and server cannot correctly vet each other's requests.
You also can't take shortcuts and just concatonate everything into a huge String, Amazon tried this with AWS Signature Version 1 and it turned out wrong.
I hope all of that helps, feel free to ask questions if you are stuck.

Resources