Data encryption safe even with developer access - security

Suppose you have a server-client application.
Server keeps sensitive information that belongs to a Client.
Server will search some parameters in side the clients's sensitive information.
Thus server should decode the sensitive information with client control temporarily.
But server should not reveal the keys, by hacking it self.
I mean a developer should not try to change server sidde code and should not extract the client keys.
Is there really a way to do that?
Somewhat client permits server to decode sensitive information, but the keys instantly disappear and developer have no tricks to reveal this password?
The answer if exist, is valid also for an ideal secure cloud application. Developer or cloud hosting company should not access to decrypted information.
I am not optimistic, but worth to try asking.

So in a word no. This does not grant any security whatsoever, as you cannot trust the client. You even call out that the server will be controlled by the client temporarily, this is generally not a wise approach. Also, do not underestimate a bored developer, it is completely feasible to write some code and rip the keys. The key here is remembering that if someone has access to the box it is no longer your box.

In general, any client access to sensitive info on the server must require authentication of the client, so that you can verify that the client is exactly who he claims he his. The authentication typically involves sending a password, or some kind of authentication token (e.g., an encrypted shared secret) that was given to the client by the server through a secure channel.
As has been said many times, many ways, allowing client access to server data without proper and sufficient authentication means that you give up control of the server.

Related

How to store third-party credentials (no api, no OAuth) for automatic reuse?

I've read several Stack Overflow threads, I still can't decide what is the best option for my case. And the most secure one.
Here is the story. My webapp is to help users automatically get an overview of some of their data available in some third-party website. I need to store for each user some third-party credentials. Each night or so, my server will connect to the third-party services on the users' behalf and retrieve the required data.
Most of those third-party sites do not implement any API or OAuth mechanism, so I was thinking to do some web scraping.
I've read in many places that storing the credentials in the DB is not a good idea - especially because my app needs access to the password (so it has to be encrypted in such a way I can easily reuse it).
So, I have two options left:
Whenever I access (via webscraping) the third-party service, I store on the server the cookies issued by that service, for future reuse. I encrypt them and keep them encrypted in a DB, and decrypt them only when I need them. The problem is that the cookie can be denied or expired after a while, and so the automatic process wouldn't work any more.
I store the credentials in the environment variables. I will be on Node.js and Heroku. That's an idea I found in another SO thread. But I'm wondering about the security of this idea. Is it really safe? No one can access them but me? And what about if I reach many users. Like 1000 users, with 10 services. That's 10000 credentials to store in the env variables. That doesn't seem like a good idea.
I found two interesting questions on Stack Overflow but they don't fit 100% with my use case.
Security model: log in to third-party site with user's credentials (that gave me the idea in point 1)
Rails storing third party credentials.. Anyone know best practice? (gave me the idea in point 2).
I add another answer because maybe this one will do the trick for you.
You said the main goal of your website is to have an overview of third party applications. But what if instead of updating this overview every night, you update it when the user logs in ? It changes everything, because you could use the user's password (of your website) as master password to encrypt (using AES) all the others.
If you do that, the communications between your server and the clients have to be encrypted with SSL pinning, because an attacker could perform a MITM, get the master password and all the others stored in the DB... (Even if in practice it's very hard because you need to hack the client AND the server)
Storing a lot of data that changes and grows in environment variables will never be practical, no matter if it's secure or not so this is pretty much out of the question, unless if you have a small fixed number of users.
Not storing credentials in the database is a very good advice, but the cookies are credentials and even if you store them encrypted, your app needs to be able to encrypt it to use it. (This is unlike the situation with verifying passwords of your users when you don't need to ever encrypt them, you only need to see if the provided passwords hash to the same values that you have stored).
This is a hard problem because to make it work you need to have some form of credentials (whether those are passwords or cookies) stored and ready to be used unencrypted (even if they are stored encrypted, you need to store the keys to encrypt it as well).
Also, what you are trying to do can be illegal. Mayke sure that you follow the TOC of every service that you're using or otherwise you may face legal trouble.
Plan for the attacker gaining admin access to the server. Your site will be very attractive to attackers, kind of a one-stop-shop for user credentials so you will need very good security of the login credentials.
There are more than two options for storing the credentials:
Use an HSM for the storage or individual credential encryption keys.
Keep the credentials on another dedicated server with no Internet access, 2-factor authentication and limit admin personal. Rate limit the access to this server and add rate alarms. Access this server on a per user credential basis over a non-Internet connection. The credentials will only be available to the Internet connected server in memory as used, not at-rest in a file.
Storing users credentials in a reversible way looks like a terrible idea anyway. But if you really want to store them, I suggest you to use the environment variables solution. But you can improve it. To limit the amount of data you store and don't have 1000000 variables as you said, you can just store an AES encryption key, store all credentials in a DB encrypted with this key, and you just have to get this key (which is in memory) and decrypt the DB. But there is another problem with this solution. As I said, this is stored in RAM memory, so it's not persistent, imagine your server has to reboot for X or Y reason... You will lose the AES key and also the credentials of your users... Moreover, if the attacker performs a memory dump, he will have access to the AES key...
I think the better idea is to store the cookies (in an encrypted way) and when this one expires, you alert the user (by mail, phone, notifications, ...) and ask him to fill his credentials again. But it's not a perfect solution ! Indeed the cookies are a type of credentials and shouldn't be stored either...

Server to server authentication basics

While I understand the various options available for server to server authentication between REST services, I could use some clarification on the security implications of each approach.
I want a service to verify that a request received does originate from a legitimate calling remote service. No interactive users involved, assume the request happens as the calling service starts up. The three approaches usually mentioned are:
Use a fake user account and authenticate the client against the existing auth system
Use a shared secret / API key and sign the request
Use a client certificate (verifying the server is not a priority) 3.
The part I am missing is that it seems that all three methods depend entirely on the calling service's host (the client in the call) not being compromised. In the first approach this would give away the fake user password, but in the two other approaches an attacker could obtain the shared secret or the client certificate and impersonate the calling server just as easily as with approach number 1... so in what respect are 2 & 3 considered more secure?
If the host is compromised, the game is already over. You cannot hope to use network security techniques to provide guarantees about the end systems, that is not what they're meant for. Consider passwords, for example. When a user types in a password, the guarantee you have is that the entity that entered the password knows the password, that's all. Designing to be secure against compromised hosts is like trying to build a password scheme that only authorizes you if you're the real person - you're expecting a guarantee that the mechanism is not built to provide.
If you want to check the calling server is not compromised you might want to use TPM based verification of the calling server in case the machines have TPMs on them. Once it has been verified that it is not compromised any of the above 3 methods would be secure.(ref: http://en.wikipedia.org/wiki/Trusted_Platform_Module)

Ensuring Client / Server Authentication without credentials

I am looking into ways of securing the channel between my client apps and the server.
I have a rich desktop client (win) and mobile client connecting to a webservice, exchanging data.
Using SSL certificates, server and clients may trust each other. On the secured connection i can exchange username and password and therefore authenticate the user.
However i have certain circumstances where a user must connect to the server via any of the two methods without his credentials but only a literal, like say, a license plate number.
I really want to make sure that in this case i ONLY allow client connects from devices i am sure i know, since there is no further checks on the authentication and a license plate number would be a pretty common literal.
How can i ensure that only "devices" which are known to my server, can interact with my server?
If you want to authenticate the device, you'll need to find a way for the device to prove what it is, without disclosing its secret.
A system similar to a number plate would be quite easy to spoof, for anyone in a position to see that number. Depending on how much control you have on this device, you might not be able to hide it, even if the connection to your server is secured with SSL/TLS.
A potential way to do this would be to use a cryptographic hardware token (or smart card). Some of these tokens can be configured to hold a certificate and private key, with the ability to use the private key without being able to export that private key. The cryptographic operations (signing and decryption) happen on the token itself.
You can use these to perform client-certificate authentication to your server. In this case, you would know that the client has that token. This could work on the condition that you know the CAs were issued its certificates only for key pairs in such tokens: there will be a cost in administering the CA to handle this.
This would at least allow you to tie the authentication to a particular token. Whether you can integrate this with your overall device depends on the kind of device you have.
Please check if TLS Pre-Shared Keys (RFC 4279) can be used for your scenario.

Security practices for internal web application

I am a developer working on an internal web-based application, and I have been given responsibility to make sure the system is secure. I have no experience in this area, but I still want to do the best job I can: I'm in the middle of reading OWASP's guide (http://surfnet.dl.sourceforge.net/project/owasp/Guide/2.0.1/OWASPGuide2.0.1.pdf), but there is a lot of information to process, and unfortunately deadlines are deadlines.
Can the knowledgeable users here at Stack Overflow please poke holes in my design and show me where my understanding is lacking? If the entire idea is fundamentally flawed, knowing that would be appreciated, too. Thanks for any input.
This application is hosted internally, and should not be visible at all externally, even though it is accessed over our wireless networks. I trust our network engineers to handle this, though.
The users of this application are only a subset of all the employees in this corporate environment. In addition, even authorized users should be limited to only the information pertaining to them (which is largely an application-level concern, but I want to make sure exploits are not possible).
Security Framework for Internal Web Application (by a newbie)
All communication with the web server is done over HTTPS connections.
Logging in
User enters name and password, which are POSTed over an HTTPS connection
If the name and password are correct, generate a token, and store it in a cookie. Also store the cookie in the database for future lookup. The token should have an expiration date and is associated with only the user that generated it.
Requests
Check that the token supplied is still valid (not expired)
Check that the token is valid for the user making the request
If everything checks out, refresh the token's validity for another 30 minutes (or so)
Otherwise, deny access
That sounds good.
The token can either be a signed expiration date (signed with a private key stored on the server) or a sequence of cryptographically secure random bytes which is stored in a database.
Unless the token is specific to an IP address, everything must be done over SSL.
Independently of authentication, you'll also need to look out for SQL injection, CSRF, XSS, and other security holes.
Important consideration: The entire session has to be over SSL. Firesheep has demonstrated quite clearly that being able to sniff cookies (by being on the same network as the victim) leaves your users open to session hijacking.
Security is more than just logging in. You'll want to read up on SQL Injection and Cross-Site Scripting Attacks, on the very least (the two most common attacks against web-applications).
Look into CSRF attacks. They bypass cookie checks and company firewalls.

How can I encrypt a user's password in Silverlight?

I have a Silverlight 3 app which connects to a server to perform various actions. My users log in using Forms Authentication but the actions they request are run on the server using the AppPool account so when they go in the audit logs they're recorded against the AppPool account. PCI DSS regulations now require that the user's own ID is in the audit logs which means the action must be taken using the user's creds. Now, I can save the user's creds when they log on and submit them with each request and the actions being taken by the server can use those creds. But the PCI regs say that if creds are saved they must be encrypted (to avoid someone taking a memory dump of the PC and getting the password).
The only way I can see of doing this is to get a public key from the server and encrypt the password with it, then submit the encrypted password and decrypt it on the server using the private key. But Silverlight doesn't have asymmetric cryptography.
I guess I'm too close to the problem and there must be another solution but I can't see what it is. Can anyone help?
CLARIFICATIONS
It's an internal application. Up until now, I've been using IIS Forms AuthN over SSL to Active Directory - I'm not worried about protecting the password in transit, just whilst it's held in memory on the client. As I understand it, because I'm using Forms Authentication, impersonation is not possible on the server unless I use LogonUser, which means I need the password on the server, so I need to transmit it each time, so I need to hold it in the client, in memory, until the app closes.
Are you saying you need to store the password for re-use in the silverlight app? If you are concerned about the password appearing in memory un-encrypted then Silverlight then I think you're in trouble.
The .NET framework does have a SecureString class for exact purpose you outline.
Unfortunately the Silverlight version of the framework does not have this class. Hence even if you were to keep the logical storage of the password encrypted at some point your code would need to decrypt it before using it. At the point there is memory allocated containing the string in unencrypted form.
I don't know much about Forms authentication but if you can map the User principle to a domain user (which you seem to indicate you need) then you will want to use impersonation when running your code on the server.
Alternatively stop using Forms authentication and use Windows integrated authentication where you definitely can use impersonation server-side.
Encryption should never be used for passwords. When you encrypt something then it follows there should be a way to decrypt it. One way hashes should always be used for passwords. md5 and sha1 have been proven to be far too weak for any secuirty system.
Sha256 should be used, and in silverlight this library will take care of it:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256%28VS.95%29.aspx
In fact storing passwords using "encryption" is recognized by the vulnerability family CWE-257. The use of a message digest is the ONLY way to safely store passwords. I didn't just make this up, this is coming from NIST. There are many other vulnerabilities that come up when storing passwords. Here is THE LIST that NIST has put together:

Resources