Storing credentials in a c# application - c#

Hi everybody i do not have a lot experience with c#. I want to write a very simple application, with must access a fileshare. The User (who executes the application) has NO access to that fileshare. So I need to use other credentials to access that fileshare. But I think it is not a good option to provide that credentials directly in the source code. I am thinking and thinking, but get no solution to that. Do you have a idea, how I could solve that problem? Is there a way to store the credentials somewhere, so that a possible attacker has problems to receive the used password?

You can't both give the user the password and prevent them from having the password. But every computing problem except for one, can be solved by adding an extra layer of indirection. Create something that doesn't run on the users machine, that acts as a middleman between the file share and the user. I would suggest using the WebDAV protocol.

Related

Secure authentication and requests with C# through a PHP REST api

Introduction
Okay so I've got a website (PHP) with a database (MySQL). You can create an account on this website and edit your details and so on (let's say date of birth, real name, address, and so on).
Now, what I wanna do is to create a desktop application (most likely c# with WPF) that interacts with a REST api (in PHP) from the website, which will allow to :
Create accounts directly from the application
Log in to your account
Be able to edit your details directly from the application
As of now I only want to do a desktop application, but it might evolve into a mobile app. I don't think that is relevant though.
Creating accounts and logging in
I'm struggling with the create account / log in part. I want it to be as secure as possible. On the website, I'm using password_hash(PASSWORD_BCRYPT) with a cost of 10 to store passwords in the database, and password-verify to check log ins.
Regarding the application, I imagine the way to go is to pass the username and password to the REST api and do the encryption directly on the server side. But sending the password itself sounds terrible so I thought about encrypting it with a secret key that only the application and the website know, so the website can figure out the password and encode it correctly in the database.
If I'm right, what encryption algorithm should I use? If not, how should I do that?
Edit your details directly from the application
I'm thinking about doing the following : Let's say the user has logged in through the application. If the authentication is successful, the server randomly generates a token (I'll probably use ircmaxell's Random-Lib) and send it as a reply to the application. From then onward, when the application wants to make a request to the api, it adds the username to the datas string, and generates a hash (sha256 for example) with the data string plus the token; then the server can repeat the exact process using the token stored in database to make sure the user actually has the right to access/modify his details, and nobody is trying to pretend to be an user he isn't.
I feel like the problem is, if someone listens to the first api reply after the authentication, he gets the token and can use it to act as if he was the user. Would encrypting it with the same process used for the password be enough to make sure this can't happen?
Last but not least, if I want the user to be able to be directly logged in the next time he starts the application, I guess I have to give the token a permanent durability and store it in a file or something on the computer. But that doesn't sound really safe because anyone could just read the file content and figure out the token.
Final questions
So. What do you think ? Does it sound good or am I completely off the tracks?
The website hosting is in http://* so I guess using HTTPS communications is not an option here. I know that's a big problem to create something really secured, but I'd still like to make something as safe as possible with what I have.
Thanks a lot for your advices. :)
Btw I tried to make this as clear as possible, hope it worked. I have close to pretty little knowledge of security, encryption, ... so you'll have to speak like to a 3 years old to me.
I think the first, most important piece of advice I could give is to never try to roll your own security code, unless you are an absolute expert. You'll want to put together a solution based on the frameworks that .net provides for you.
First things first - your REST API. I'd suggest building on top of ASP.NET Web API. HTTPS is mandatory here - if your hosting provider can't give it to you, you need a new hosting provider. It also conveniently takes care of encryption for you.
There are various security options available for ASP, I'd read this for a detailed overview: https://docs.asp.net/en/latest/security/. Using the existing ASP options will also take care of your requirements around user account creation and self-service.

Custom authentication against SQL Server database

I have a WPF application and a SQL Server database with a Users table. Every user has it's own row including hashed password and role in Users table.
I need to let them authenticate in my application and keep some kind of credentials, including role. Based on that role, they will see only what they should see.
Can you give me some clue how to accomplish it? What is the best way to keep those credentials and hide parts of my application based on user's role?
Thanks for any help, JiKra
Ok, I was thinking and how about to use a singleton? User authenticates, I grab his role from database, instantiate a singleton, set his credentials and use them in my app.
Is that correct? It's the easiest way to do that?
JiKra
The "functional model" as you call it can be based on the MembershipProvider/RoleProvider APIs. There's a tutorial video by Todd Miranda:
http://windowsclient.net/learn/video.aspx?v=293710
What the tutorial lacks is where you should store the information so that it's available for the other parts of the application. The answer is simple - since you have the stateful application, you can store the information in a shared (static) resource in a class.
Please also be aware of a potential security risk, I've added a comment under your question.

Hiding MySQL credentials in a C# app

I am extending an open-source VoIP softphone application (written in C#/.NET) to my needs but don't know how to best approach this issue. I want the application to connect to database when a user enters his email address to log in, and perform a SQL query to fetch his account number using that email and authenticate with account number. But, I think including my MySQL connection credentials (host, username, database) is insecure? How should I do it?
It is indeed insecure.
You need software running on the server, that can accept said email and password as input and connect to your database (so the connection string is sitting on a machine in your control), check it and return either ACCEPTED or DENIED to the client. In your case, ACCEPTED could be just the account number you mention.
Bonus points if the email and password are transmitted from client to server app over an encrypted link (public key).
You should put the connection strings into a configuration file and then encrypt that portion of the file. There's a tutorial on how to do that here: Protecting Connection Strings and Other Configuration Information. Although the tutorial is for ASP.NET, the same principle will apply to pretty much any .NET config file.
There's also a similar question here: Encrypting passwords in WinForms app.config, .NET.
Our rule of thumb when designing database applications is to always use delegation and isolation.
What isolation means is that we isolate database interaction from the end user application through the use of services (i.e. web services, wcf, .net remoting, etc). In this way, the database is never directly exposed to the user.
What delegation means is that the database access is always performed on behalf of the end user by a well-known, limited-access database user (generally the user that the service is running as). If at all possible, the database access should be performed by a user authenticated by the network rather than by storing user names and passwords in connection strings or other semi-secure locations.
Finally, one important note: you should always encrypt your end-user's login and password information before sending it over the wire. This is a little extra work, but well worth it from a security perspective.
Can MySQL do Windows based authentication (i.e. on a domain)? If so, you could use that. Otherwise you might want to have credentials to a service, or use encryption, but you would need to include the encryption key so anyone dedicated to discovering it would.
You could code your connection strings so that they end up in your assembly and use a code obfuscator to protect it from disassemblers
There are many ways to do it, including obfuscation and other ways making it difficult to use outside of the application, but not impossible to retrieve/use.
How should you do it? The best way (as far as I know) is to give the account the minimum credentials necessary so that if someone does have the username and password he/she cannot do anything malicious with it. Permissions can be set up in many ways for user-specific data, such as views so a user can only access the correct rows. Basically, if security is a top concern, assign permissions conservatively and if necessary give different users different credentials.
You should host a (php/jsp/asp) script at your server with which your application will talk. you should not store your credentials inside the app at any cost.
Tthere are so many ways to just take out the information. Especially .NET applications. it doesn't takes more that 30 mins :p

Implementing a local password within an application

CONTEXT:
I have a c# .net application made for a customer. The application has no network communication. In fact, the computer it runs on wont likely have any internet or network access.
In comes our customer with a very specific and non-negotiable request:
Request a administrative password before opening up certain screens and grant certain rights. This password must be within the application. The default password (i'll probably set it to 'password') must be changeable, so it can't be hard coded. And there ought to be some way to return to the default in case they forget the password.
It seems kind of superfluous to me just to stick a encrypted password in a file, in the application folder. Anybody who deletes the file would erase the password.
Is there some widely known strategy for this?
Again the password is local and not authenticated on any network.
Maybe hide it in the registry? If the registry key isn't there, then just remake it and set it to the default password. Hardcode the default password, maybe encrypted or something so someone who scans the .exe can't finde it. Also ask your client for what the default password should be, not simply make one.
The problem is, as long as you store something locally, everyone who really wants to know it, will find a way to get it. :/
If it is on windows (is it?)
Key Storage and Retrieval
MSDN Security Briefs Article (part 1)
MSDN Security Briefs Article (part 2)

Windows Impersonation from C#

How can a C# program running as LocalSystem impersonate the login identity of another user temporarily? Roughly speaking I have a Windows Service that I'd like to run as LocalSystem but at times impersonate user XYZ (when connecting to a db using windows integrated security).
Most important of all: Is there a way to do this without knowing the other user's password?
Note: if a password is mandatory is there a recommended strategy for storing a password securely (c# and/or vbscript).
It's possible, although it requires you to do a lot of code. See NtCreateToken and CreateToken. You need SeCreateTokenPrivilege, although that won't be a problem since you're running under NT AUTHORITY\SYSTEM. You can then use the created token to impersonate inside a thread.
Short answer: you can't without the user password or the user calling your service through COM.
To impersonate another user in your process, you have to call ImpersonateLoggedOnUser. ImpersonateLoggedOnUser requires a token handle. There are several ways you can obtain token handle:
by logging on as the user with LogonUser. This however requires you to know the user password.
by duplicating an existing token with CreateRestrictedToken, DuplicateToken, or DuplicateTokenEx.
by opening the token from another process or thread, that already is loggen on as the user, with OpenProcessToken or OpenThreadToken
For the password storing part, you may want to have a look at this question asked recently.
This was my answer:
You could/should use the DPAPI, the Data Protection API that provides storage encryption.
It's there just for this type of problem.
Encryption of the storage is based on either:
the user account, so only the logged-in user can access the data. This makes the data transferable to another PC with the exact same user credentials.
the machine, making the data only accessible on that particular machine setup and not transferable to another PC.
There is a dnrTV show with Karl Franklin showing exactly what's needed to implement this, and other encryption functions.
The source code from the show is also available on the page.
There are, of course, lots of other articles on that subject.

Categories

Resources