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.
Related
So this is my first question on SO and this is my issue...
I have made a widows form app in visual studio for the Client of an organisation application(Like JIRA but not..). I am using a SQL server DB to save data and signal-r to communicate. A user must open the application and be hailed by a msgbox asking for name and pw. Using these creds I need to verify that the user is in the database and that the creds are correct. At the moment I send the data to the server and then check that the creds are valid and then return a bool indicating if it was successful or not, but I'm sure that's not the best way to do it... I've done near to no security(i just started as a junior dev) and have no idea where to start from a security stand point. i would like to save the users names and pw's in the Database as well as the connection id, but I'm not sure what to use. there are lots of examples out there (OAuth,certificate, etc.. (those might be the same thing for all I know right now)) Maybe a few examples would help, I've googled most everything I could think of and have come up with very few examples that are relevant to what i need. Maybe I'm just asking the wrong questions, but some/any help would be nice.
Thanks
LegenBerry
As you have mentioned that your are using SignlR I assume you are using OWIN to host the application.
You should be relying on ASP.NET Identity to perform authentication and authorization.
You may follow the steps documented at https://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/ to write a simple cookie based authentication.
Our system is built using MVC4-EF6-SimpleMembership.
I'm struggling for 2 days now with how to enable an affiliate company website to login to our system.
What I wanted to implement is a simple GET from their site to ours (we would check the request comes from their domain), where they would pass in an encryption or hash of the password along with a username (not hashed/encrypted).
It turns out I don't have an encrypted/hashed password, which I can give them in order to use it and login, nor I have a way to recover the password in order to hash it myself and most importantly to manage to login with it from code.
Also, I didn't find a way to use the encrypted password field inside the webpages_Membership table. I thought that would be the token to send to our affiliate, but can't see any use for it.
Any ideas?
P.S.
I know there's the OAuth possibility, but I'm afraid to loose time figuring this out and then being dependent on the affiliate site. Is this a wrong approach?
Thanks very much for any help.
This whole approach is a really bad idea, and could very easily open your application up to hackers. You really need to learn more about how to handle authentication with trusted third parties if you're going to go forward, even if it costs you time. What it costs you time now it saves you in the long run in liability.
I'm not clear on your use case for them logging in right now. If it's a human being logging in, just provide them "normal" credentials and have them log in normally (i.e. through a web page POST to get a session cookie, etc).
If you are looking for a way for one of their applications to perform actions on someone's behalf (e.g a cron job or to enable integration with their services), then you should look into providing an API (not using a website per se but a REST or SOAP API). There's a number of mechanisms for that as well (Javascript Web Tokens, SAML assertions, etc).
Finally, if you're intending one of your users on their site to authorize their site to pull information about your user, or perform actions based on your user's wishes, then that's the "sweet spot" for OAuth.
Do not go forward with your plan of issuing out hashes of people's passwords. That isn't how the auth works at all, even if it were a good idea to do so. Standards exist for a reason.
I've built an application that utilizes a database hosted with Amazon. I'm trying to find a way to connect to this securely and overall, I've been assured that I have no idea what I'm doing.
My original intent was to store my database credentials in my application with encryption, but I've been led to believe that using a web service would be a better option as nothing stored local can be really secured. However, I have no idea how to use a web service for this and or why it would make a difference.
In using a web service, would I be building a Windows Server and deploying this "web service" to it to connect to, which would then connect to my database? That almost seems superfluous, though I still consider myself to be an amateur. Even then, how would I authenticate to it securely?
The end-game for me is to be able to store DB (and PayPal seller credentials) somewhere that a user cannot access in any case, but my program can. It seems much more cut and dry than people here and elsewhere have made it seem, but again, I'm a newb.
Any direction would be greatly appreciated! I'd like to deploy this, soon outside of our organization for testing and such.
Thanks, guys!
To me, it's unthinkable to give your "application" -- which I assume means an "app" deployed on people's devices or maybe some kind of a desktop application -- direct connectivity to your database, unless the thought of putting the key to your car in a paper envelope and sticking it to the window seems secure.
The application should have an extremely small number of very specific things it can do to the database, and should be leaving a trail of exactly what it does and from where and on whose behalf. The app can make requests to a service, such as a REST API, running on your application server -- the "web service" -- over https, and your application server would then mediate the requests and fetch values from, or send updates to, the database, as appropriate... only after the app has convinced the application server that it indeed represents the particular user that it claims to represent.
It's a fundamental principle that anything you don't control, you can't trust.
"Why it would make a difference" is the difference between "Ha! I hacked one user's password" and "Ha! I stole your database." The application server can authenticate any request as being legitimate for the particular end-user credentials presented... while the database is, in large measure, ill-prepared to do anything of the sort.
The end-user (not the application) would authenticate to the application server, the application server would validate those credentials against the database, providing no hints as to why authentication failed... user not found, password incorrect, we don't know, we don't care -- sorry, login failed. Give us your e-mail address and we'll send you a support email, or if that's not an e-mail we have on file, we'll pretend that we did. Hints help hackers.
store ... PayPal seller credentials
Well, you'll want to be sure that's not among the things that are prohibited from "collect, capture, use, or store" in section 10.1.2 of the Paypal Developer Agreement.
So, how do you do this? That part of the answer takes us a little bit out of scope, because there are many options, the landscape shifts, and it's largely a matter of opinion as to the "best" way but I'd assume ASP or PHP would be the most straightforward.
Think of it as building a database-enabled web site without the hassles of making it pretty, because nobody's going to see it except that back-end of your app... and there's your "web service".
I've been assured that I have no idea what I'm doing
That puts you way ahead of the terrifying number of people who don't realize that they don't know what they are doing.
If your database is mysql, then you can use: Connector/Net from mysql. Credentials for the db are usually kept in web.config of your application. Also I see no reason of using web service in your case. Web services are used when you need to transfer data from one system to another, not to provide better security for database connection.
EDIT:
As Michael kindly explained this approach is for the web application which is hosted on the server. As for the client application, keeping the database credentials in the app (encrypted or not) is very bad idea. In this case additional web application should be developed, which will provide the way to authenticate users using web service (over https), and transfer the data to users from database.
I have been making basic forms applications in C# for a year or two now and have done some very basic log in forms (plain text passwords etc).
I am looking for a better, more secure option for security. I have looked and found some articles about .net membership and I have come across it before in other applications I have used. I feel that searching google sends me around in loops of why X is better than Y and also the resources are diluted by various reccomendations from 3-5 years + ago.
I am very comfortable with SQL and use Visual Studio Express for my development.
All I am looking for is a good resource / link to the most common authentication methods around. This site will eventually end up live on the internet so needs to be secure.
Thank you.
I use the ASP.NET Login Controls. There are other solutions, but this is one area (much like encryption) where I think you're better off not coding up your own solution - there are too many ways to fail.
See also What should every programmer know about security?
First of all the only way You can secure send password is SSL. The only excepion for this is for internet sites which are using windows integrated authentication. Buti in this case You do not send password (so it is still ok).
Second part is storing passwords. If you store them plain, somebody can hack your server and get them. That is way you should store hash of the password.
For me the best way is 2 way authentiation. I use SMS service and password.
Passwords are stored in database where every character is hashed(SHA512 or md5) with SALT. Salt is neccesary because if someone gets into your database he can find passwords and check them in dictionaries. I force user to randomly enter some characters of password + valid code from sms.
Also good way is to use CAPTCHA when user fails to enter data several times.
You should log such invalid login tries and if you think there can be attack on this account, you should block it and inform user about it.
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