Related
I'd like to use Windows.Security.Credentials.PasswordVault in my desktop app (WPF-based) to securely store a user's password. I managed to access this Windows 10 API using this MSDN article.
I did some experiments and it appears that any data written to PasswordVault from one desktop app (not a native UWP app) can be read from any other desktop app. Even packaging my desktop app with Desktop Bridge technology and thus having a Package Identity does not fix this vulnerability.
Any ideas how to fix that and be able storing the app's data secure from other apps?
UPDATE: It appeared that PasswordVault adds no extra security over DPAPI. The case is closed with a negative result.
(this is from what I can understand of your post)
There is no real way of preventing data access between desktop apps when using these kind of API's http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx tells more about it. You'd probably just want to decrypt your information.
memory access restriction is difficult, code executed by the user is always retrievable by the user so it would be difficult to restrict this.
have you considered using the Windows Data Protection API :
https://msdn.microsoft.com/en-us/library/ms995355.aspx
grabbed straight from the source
DPAPI is an easy-to-use service that will benefit developers who must provide protection for sensitive application data, such as passwords and private keys
WDPAPI uses keys generated by the operating system and Triple DES to encrypt/decrypt your data. Which means your application doesn't have to generate these keys, which is always nice.
You could also use the Rfc2898DeriveBytes class, this uses a pseudo-random number generator to decrypt your password. It's safer than most decrypters since there is no practical way to go back from the result back to the password. This is only really useful for verifying the input password and not retrieving it back again. I have never actually used this myself so I would not be able to help you.
https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v=vs.110).aspx
see also this post which gives a way better explanation than I can.
How to securely save username/password (local)?
If I misunderstood the question in some way, tell me, I will try to update the answer.
NOTE that modern/metro apps do not have this problem, although they still are accessible in other ways.
The hard truth is that storing a password in a desktop application, 100% securely is simply not possible. However, you can get close to 100%.
Regarding your original approach, PasswordVault uses the Credential Locker service which is built into windows to securely store data. Credential Locker is bound to the user's profile. Therefore, storing your data via PasswordVault is essentially equivalent to the master password approach to protecting data, which I talk about in detail further down. Only difference is that the master password in that case is the user's credentials. This allows applications running during the user's session to access the data.
Note: To be clear, I'm strictly talking about storing it in a way that allows you access to the plain text. That is to say, storing it in an encrypted database of any sort, or encrypting it yourself and storing the ciphertext somewhere. This kind of functionality is necessary in programs like password managers, but not in programs that just require some sort of authentication. If this is not a necessity then I strongly recommend hashing the password, ideally per the instructions laid out in this answer by zaph. (Some more information in this excellent post by Thomas Pornin).
If it is a necessity, things get a bit more complicated: If you want to prevent other programs (or users I suppose) from being able to view the plaintext password, then your only real option is to encrypt it. Storing the ciphertext within PasswordVault is optional since, if you use good encryption, your only weak point is someone discovering your key. Therefore the ciphertext itself can be stored anywhere. That brings us to the key itself.
Depending on how many passwords you're actually trying to store for each program instance, you might not have to worry about generating and securely storing a key at all. If you want to store multiple passwords, then you can simply ask the user to input one master password, perform some salting and hashing on that, and use the result as the encryption key for all other passwords. When it is time for decryption, then ask the user to input it again. If you are storing multiple passwords then I strongly urge you to go with this approach. It is the most secure approach possible. For the rest of my post however, I will roll with the assumption that this is not a viable option.
First off I urge you not to have the same key for every installation. Create a new one for every instance of your program, based on securely generated random data. Resist the temptation to "avoid having to store the key" by having it be generated on the fly every time it is needed, based on information about the system. That is just as secure as hardcoding string superSecretKey = "12345"; into your program. It won't take attackers long to figure out the process.
Now, storing it is the real tricky part. A general rule of infosec is the following:
Nothing is secure once you have physical access
So, ideally, nobody would. Storing the encryption keys on a properly secured remote server minimizes the chances of it being recovered by attackers. Entire books have been written regarding server-side security, so I will not discuss this here.
Another good option is to use an HSM (Hardware Security Module). These nifty little devices are built for the job. Accessing the keys stored in an HSM is pretty much impossible. However, this option is only viable if you know for sure that every user's computer has one of these, such as in an enterprise environment.
.Net provides a solution of sorts, via the configuration system. You can store your key in an encrypted section of your app.config. This is often used for protecting connection strings. There are plenty of resources out there on how to do this. I recommend this fantastic blog post, which will tell you most of what you need to know.
The reason I said earlier not to go with simply generating the key on the fly is because, like storing it as a variable in your code, you rely exclusively on obfuscation to keep it secure. The thing about this approach is that it usually doesn't. However, sometimes you have no other option. Enter White Box cryptography.
White box cryptography is essentially obfuscation taken to the extreme. It is meant to be effective even in a white-box scenario, where the attacker both has access to and can modify the bytecode. It is the epitome of security through obscurity. As opposed to mere constant hiding (infosec speak for the string superSecretKey approach) or generating the key when it is needed, white box cryptography essentially relies on generating the cipher itself on the fly.
Entire papers have been written on it, It is difficult to pull off writing a proper implementation, and your mileage may vary. You should only consider this if you really really really want to do this as securely as possible.
Obfuscation however is still obfuscation. All it can really do is slow the attackers down. The final solution I have to offer might seem backwards, but it works: Do not hide the encryption key digitally. Hide it physically. Have the user insert a usb drive when it is time for encryption, (securely) generate a random key, then write it to the usb drive. Then, whenever it is time for decryption, the user only has to put the drive back in, and your program reads the key off that.
This is a bit similar to the master password approach, in that it leaves it up to the user to keep the key safe. However, it has some notable advantages. For instance, this approach allows for a massive encryption key. A key that can fit in a mere 1 megabyte file can take literally billions of years to break via a brute force attack. Plus, if the key ever gets discovered, the user has only themselves to blame.
In summary, see if you can avoid having to store an encryption key. If you can't, avoid storing it locally at all costs. Otherwise, your only option is to make it as hard for hackers to figure it out as possible. No matter how you choose to do that, make sure that every key is different, so even if attackers do find one, the other users' keys are safe.
Only alternative is to encrypt password with your own private key stored somewhere in your code. (Someone can easily disassemble your code and get the key) and then store encrypted password inside PasswordVault, however the only security you have is any app will not have access to password.
This is dual security, in case of compromised machines, attacker can get access to PasswordVault but not your password as they will need one more private key to decrypt the password and that will be hidden somewhere in your code.
To make it more secure, if you leave your private key on your server and expose an API to encrypt and decrypt password before storing in Vault, will make it most secure. I think this is the reason people have moved on to OAuth (storing OAuth token in PasswordVault) etc rather then storing password in vault.
Ideally, I would recommend not storing password, instead get some token from server and save it and use that token for authentication. And store that token in PasswordVault.
It is always possible to push the security, with miscellaneous encryption and storage strategies. Making something harder is only making the data retrieval longer, never impossible. Hence you need to consider the most appropriate level of protection considering execution cost x time (human and machine) and development cost x time aspects.
If I consider strictly your request, I would simply add a layer (class, interface) to cipher your passwords. Best with asymmetrical encryption (and not RSA). Supposing the other softs are not accessing your program data (program, files OR process), this is sufficient. You can use SSH.NET (https://github.com/sshnet/SSH.NET) to achieve this quickly.
If you would like to push the security and give a certain level of protection against binary reverse-engineering (including the private key retrieval), I recommend a small (process limited) encrypted VM (like Docker, https://blogs.msdn.microsoft.com/mvpawardprogram/2015/12/15/getting-started-with-net-and-docker/) based solution such as Denuvo (https://www.denuvo.com/). The encryption is unique per customer and machine based. You'll have to encapsulated you c# program into a c/c++ program (which acts like a container) that will do all the in-memory ciphering-deciphering.
You can implement your own strategy, depending on the kind of investment and warranty you require.
In case your program is a backend program, you can pick the best strategy (the only I really recommend) of all which is to store the private key at the client side, public key at backend side and have local deciphering, all transmitted password would be hence encrypted. I would like to remark that password and keys are actually different strategies to achieve the same goal: checking if the program talks to the right person without knowing the person's identity; I mean this: instead of storing passwords, better store directly public keys.
Revisiting this rather helpful issue and adding a bit of additional information which might be helpful.
My task was to extend a Win32 application that uses passwords to authenticate with an online service with a "save password" functionality. The idea was to protect the password using Windows Hello (UserConsentVerifier). I was under the impression that Windows surely has something comparable to the macOS keychain.
If you use the Windows Credential Manager APIs (CredReadA, CredWriteA), another application can simply enumerate the credentials and if it knows what to look for (the target name), it will be able to read the credential.
I also explored using DPAPI where you are in charge of storing the encrypted blob yourself, typically in a file. Again, there seems to be no way (except obfuscation) to prevent another application from finding and reading that file. Supplying additional entropy to CryptProtectData and CryptUnprotectData again poses the question of where to store the entropy (typically I assume it would be hard-coded and perhaps obfuscated in the application: this is security by obscurity).
As it turns out, neither DPAPI (CryptProtectData, CryptUnprotectData) nor Windows Credential Manager APIs (CredRead, CredWrite) can prevent another application running under the same user from reading a secret.
What I was actually looking for was something like the macOS keychain, which allows applications to store secrets, define ACLs on those secrets, enforce biometric authentication on accessing the secret, and critically, prevents other applications from reading the secrets.
As it turns out, Windows has a PasswordVault which claims to isolate apps from each other, but its only available to UWP apps:
Represents a Credential Locker of credentials. The contents of the locker are specific to the app or service. Apps and services don't have access to credentials associated with other apps or services.
Is there a way for a Win32 Desktop application to access this functionality? I realize that if a user can be brought to install and run a random app, that app could probably mimic the original application and just prompt the user to enter the secret, but still, it's a little disappointing that there is no app-level separation by default.
Can UUID on database level be used as a security measure instead of a true rights control?
Consider a web application where all servlets implements "normal" access control by having a session id connected to the user calling it (through the web client). All users are therefore authenticated.
The next level of security needed is if a authenticated user actually "owns" the data being changed. In a web application this could for example be editing some text in a form. The client makes sure a user, by accident, doesn’t do something wrong (JavaScript). The issue is of course is that any number of network tools could easily repeat the call made by the browser and, by only changing the ID, edit a different row in the database table behind the servlet that the user does not "own".
My question is if it would be sufficient to use UUID's as keys in the database table and thereby making it practically impossible to guess a valid ID (https://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates)? As far as I know similar approaches is used in Google Photos (http://www.theverge.com/2015/6/23/8830977/google-photos-security-public-url-privacy-protected) but I'm not sure it is 100% comparable.
Another option is off cause to have every servlet verify that the user is only performing an action on its own data, but in a big application with 200+ servlets and 50-100 tables this could be a very cumbersome task where mistakes could easily happen. In my mind this weakens the security far more, but I'm not sure if that is true.
I'm leaning towards the UUID solution, but I'm also curious if there are other obvious approaches to this problem that I ought to consider.
Update:
I should probably have clarified that my plan would be to use UUIDv4 which is supposed to be random. I know that entropy comes in to play here in regards to how random the UUID's actually are, but as far as I have read then Java (which is the selected platform/language) uses SecureRandom which is supposed to be "cryptographically strong" (link).
And in that case wiki states (link):
In other words, only after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%.
Using UUIDs in this manner has two major issues:
If there are no additional authentication methods, any attacker could simply guess UUIDs until they find one belonging to someone else. Google Photos doesn't need to worry about this as much, because they only use UUIDs to obfuscate publicly-shared photo views; you still need to authenticate to modify the photos. This is especially dangerous because:
UUIDs are intended to be unique, not random. There are likely to be predictable patterns in your UUIDs that an attacker would be able to observe and take advantage of. In addition, even without a clear pattern, the number of UUIDs an attacker needs to test to find a valid one swiftly decreases as your userbase grows.
I will always recommend using secure, continuously-checked authentication. However, if you have a fairly small userbase, and you are only using this to obfuscate public data access, then using UUIDs in this manner might be alright. Even then, you should be using actual random strings, and not UUIDs.
Another option is off cause to have every servlet verify that the user
is only performing an action on its own data, but in a big application
with 200+ servlets and 50-100 tables this could be a very cumbersome
task where mistakes could easily happen. In my mind this weakens the
security far more, but I'm not sure if that is true.
With a large legacy application adding in security later is always a complex task. And you're right - the more complicated an application, the harder it is to verify security. Complexity is the main enemy of security.
However, this is the best way to go rather than by trying to obscure insecure direct object reference problems.
If you are using these UUIDs in the query string then this information within URLs may be logged in various locations, including the user's browser, the web server, and any forward or reverse proxy servers between the two endpoints. URLs may also be displayed on-screen, bookmarked or emailed around by users. They may be disclosed to third parties via the Referer header when any off-site links are followed. Placing direct object references into the URL increases the risk that they will be captured by an attacker. An existing user of the application that then has their access revoked to certain bits of data - they will still be able to access this data by using a previously bookmarked URL (or by using their browser history). Even where the ID is passed outside of the URL mechanism, a local attacker that knows (or has figured out) how your system works could have purposely saved IDs just for the occasion.
As said by other answers, GUIDs/UUIDs are not meant to be unguessable, they are just meant to be unique. Granted, the Java implementation does actually generate cryptographically secure random numbers. However, what if this implementation changes in future releases, or what if your system is ported elsewhere where this functionality is different? If you're going to do this, you might as well generate your own cryptographically secure random numbers using your own implementation to use as identifiers. If you have 128bits of entropy in your identifiers, it is completely infeasible for anyone ever to guess them (even if they had all of the world's computing power).
However, for the above reasons I recommend you implement access checks instead.
You are trying to bypass authorisation controls by hoping that the key is unguessable. This is a security no-no. Depending on whom you ask, they may refer to it as an insecure direct object reference or a violation of the complete mediation principle.
As noted by F. Stephen Q, your assumption that UUIDs are unique does not imply that they are not predictable. The threat here is that if a user knows a few UUIDs, say his own, does that allow him to predict other peoples' UUIDs? This is a very real threat, see: Cautionary note: UUIDs generally do not meet security requirements. Especially note what the UUID RFC says:
Do not assume that UUIDs are hard to guess; they should not be used as
security capabilities (identifiers whose mere possession grants
access), for example.
You can use UUIDs for keys, but you still need to do authorisation checks. When a user wants to access his data, the database should identify the owner of the data, and the server logic needs to enforce that the current user is the same as the database claims the owner is.
I'm going to build a website for file manipulations. The idea is that the user will manage to upload his files to the website, and click the "manipulate" button, then he will get the resulted file. Also the user will have to pay in accordance with the amount of files he's trying to manipulate.
The code for the file manipulation is already written in JAVA.
The thing is, some of these files will probably be truly sensitive and private, so users will not be delighted to upload to my site over the internet.
I thought about making a local version of the website, and let the user download it (the local version) to his computer (and the only access the internet will be for the payment action).
But there seem to be two problems:
When i'll decide to change anything in my website, it will not affect the local users.
The local site will be very easy to "crack" in order not to pay...
This is my first website,
do you have any suggestions of how to solve one of these 2 problems?
Thanks!
Concerning question
(1) you would have to implement some update mechanism, for example your "local web site" (which might be a .jar file containing a web server) could check over the internet if a new version is available and then download and install it (however, you should generally ask for user's permission to do so, as many users are not delighted with silently auto-updating software). Concerning question
(2) you might use some code obfuscator to make your compiled java classes more difficult to decompile, and use an encrypted SSL connection for the transactions related to payment (while checking for server certificate to avoid man-in-the-middle attacks by the end user); however any software that a user can have on its computer will be eventually cracked by somebody. Therefore, the best solution is possibly to keep all on your server, while securing as much as possible the whole: use encrypted connections with SSL for everything, or even if the files are highly sensitive, provide a public key so users can encrypt their files with GPG (or similar software) before sending them to the site, and encrypt the files to be sent back to the user by using its public key (that he/she has to provide you and that is not critical at all to be transferred over the internet). Also carefully check the security of your web server and all the software running on it, to avoid bugs that might allow somebody to hack into it. Using the encryption with GPG/public keys and only storing encrypted data on your server might be already a good protection (but you have to make sure that it is impossible to get your private key in any way!).
Here is my requirements:
Usable by any mobile application I'm developing
I'm developing the mobile application, therefore I can implement any securing strategies.
Cacheable using classical HTTP Cache strategy
I'm using Varnish with a very basic configuration and it works well
Not publicly available
I don't want people be able to consume my API
Solutions I think of:
Use HTTPS, but it doesn't cover the last requirements because proxying request from the application will show the API KEY used.
Is there any possibility to do this? Using something like a private/public key for example?
Which fits well with HTTP, Apache, and Varnish.
There is no way to ensure that the other end of a network link is your application. This is not a solvable problem. You can obfuscate things with certificates, keys, secrets, whatever. But all of these can be reverse-engineered by the end user because they have access to the application. It's ok to use a little obfuscation like certificates or the like, but it cannot be made secure. Your server must assume that anyone connecting to it is hostile, and behave accordingly.
It is possible to authenticate users, since they can have accounts. So you can certainly ensure that only valid users may use your service. But you cannot ensure that they only use your application. If your current architecture requires that, you must redesign. It is not solvable, and most certainly not solvable on common mobile platforms.
If you can integrate a piece of secure hardware, such as a smartcard, then it is possible to improve security in that you can be more certain that the human at the other end is actually a customer, but even that does not guarantee that your application is the one connecting to the server, only that the smartcard is available to the application that is connecting.
For more on this subject, see Secure https encryption for iPhone app to webpage.
Even though it's true there's basically no way to guarantee your API is only consumed by your clients unless you use a Hardware secure element to store the secret (which would imply you making your own phone from scratch, any external device could be used by any non official client App as well) there are some fairly effective things you can do to obscure the API. To begin with, use HTTPS, that's a given. But the key here, is to do certificate pinning in your app. Certificate pining is a technique in which you store the valid public key certificate for the HTTPS server you are trying to connect. Then on every connection, you validate that it's an HTTPS connection (don't accept downgrade attacks), and more importantly, validate that it's exactly the same certificate. This way you prevent a network device in your path to perform a man in the middle attack, thus ensuring no one is listening in in your conversation with the server. By doing this, and being a bit clever about the way you store the API's parameters general design in your application (see code obfuscation, particularly how to obfuscate string constants), you can be fairly sure you are the only one talking to your server. Of course, security is only a function of how badly does someone want to break in your stuff. Doing this doesn't prevent a experienced reverse-engineer with time to spare to try (and possibly succeed) to decompile your source code and find what it is looking for. But doing all of this will force it to look at the binary, which is a couple of orders of magnitude more difficult to do than just performing a man in the middle attack. This is famously related to the latest snap chat flurrry of leaked images. Third party clients for snapchat exist, and they were created by reverse engineering the API, by means of a sniffer looking at the traffic during a man in the middle attack. If the snapchat app developers would have been smarter, they would've pinned their certificate into their app, absolutely guaranteeing it's snapchat's server who they're talking to, and the hackers would need to inspect the binary, a much more laborious task that perhaps given the effort involved, would not have been performed.
We use HTTPS and assign authorized users a key which is sent in and validated with each request.
We also use HMAC hashing.
Good read on this HMAC:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
So I have a web application that integrates with several other APIs and services which require authentication. My question is, is it safe to store my authentication credentials in plain text in my source code?
What can I do to store these credentials securely?
I think this is a common problem, so I'd like to see a solution which secures credentials in the answers.
In response to comment: I frequently use PHP, Java, and RoR
I'd like to see some more votes for an answer on this question.
Here's what we do with our passwords.
$db['hostname'] = 'somehost.com'
$db['port'] = 1234;
$config = array();
include '/etc/webapp/db/config.php';
$db['username'] = $config['db']['username'];
$db['password'] = $config['db']['password'];
No one but webserver user has access to /etc/webapp/db/config.php, this way you are protecting the username and password from developers.
The only reason to NOT store the PW in the code is simply because of the configuration issue (i.e. need to change the password and don't want to rebuild/compile the application).
But is the source a "safe" place for "security sensitive" content (like passwords, keys, algorithms). Of course it is.
Obviously security sensitive information needs to be properly secured, but that's a basic truth regardless of the file used. Whether it's a config file, a registry setting, or a .java file or .class file.
From an architecture point of view, it's a bad idea for the reason mentioned above, just like you shouldn't "hard code" any "external" dependencies in your code if you can avoid it.
But sensitive data is sensitive data. Embedding a PW in to a source code file makes that file more sensitive than other source code files, and if that's your practice, I'd consider all source code as sensitive as the password.
It is not to be recommended.
An encrypted web.config would be a more suitable place (but note can't be used with a web farm)
It appears the answer is the following:
Don't put credentials in source code but...
Put credentials in a configuration file
Sanitize log files
Set proper permissions/ownership on configs
Probably more depending on platform...
No, it is not.
Plus, you might want to change your password one day, and probably having yo change the source code may not be the best option.
No. Sometimes it is unavoidable. Better approach is to have an architecture set up where the service will implicitly trust your running code based on another trust. (Such as trusting the machine the code is running on, or trusting the application server that is running the software)
If neither of these are available, it would be perfectly acceptable to write your own trust mechanism, though I would keep it completely separate from the application code. Also, would recommend researching ways to keep passwords out of the hands of predators, even when stored on local machine - remembering that you can't protect anything if someone has control of the physical machine it is on.
If you control the Web server, and maintain it for security updates, then in the source (preferably in a configuration module) or in a configuration file that the source uses is probably best.
If you do not control the Web server (say, you are on a shared or even dedicated server provided by a hosting company), then encryption won't help you very much; if the application can decrypt the credentials on a given host, than the host can be used to decrypt the credentials without your intervention (think root or Administrator looking at the source code, and adapting the decryption routine so that it can be used to read the configuration). This is even more of a possibility if you are using unobfuscated managed code (e.g., JVM or .NET) or a Web scripting language that resides in plaintext on the server (like PHP).
As is usually the case, there is a tradeoff between security and accessibility. I'd think about what threats are the ones you are trying to guard against and come up with a means to protect against the situations that you need. If you're working with data that needs to be secure, you should probably be redacting the database fairly regularly and moving data offline to a firewalled and well-protected database server as soon as it becomes stale on the site. This would include data like social security numbers, billing information, etc., which can be referenced. This would also mean that you'd ideally want to control the servers on your own network which provide billing services or secure data storage.
I prefer to keep them in a separate config file, located somewhere outside the web server's document root.
While this doesn't protect against an attacker subverting my code in such a way that it can be coerced into telling them the password, it does still have an advantage over putting the passwords directly into the code (or any other web-accessible file) in that it eliminates concern over a web server misconfiguration (or bug/exploit) allowing an attacker to download the password-containing file directly.
One approach is to encrypt The passwords before placing the password in config.web
I'm writing this for web service app that receives password, not client:
If you save hashed passsword in source code someone who views the source code won't be able to help himself with that hash.
Your program would receive plain password and hash it and compare both hashes.
That's why we save hashed passwords into databases, not plain text. Because they can't be reversed if someone for example steals db or views it for malicious purposes he won't get all users passwords, only the hashes which are pretty useless to him.
Hashing is 1 way process: it produces same value from same source but you can't compute source value out of hash.
Storing on client: when user enters pass u save it to db/file in plaintext, maybe obfuscate a little but not much u can do to prevent someone who gets a hold of that computer to get that password.
Nobody seems to have mentioned hashing yet - with a strong hash algorithm (ie SHA-2 and not MD5), it should be much safer.