I am stuck when it comes to keep data save over web, I have a console application that acts as my host portal (using owin selfhost) to handle requests and I have a WPF application that my users can use at any time, this WPF application is suppose to ask for information like my connection string info to connect to the database, since i did not want to put that information hardcoded in the application (for decompile reasons) I decide to let the WPF application make a request over web (using WebClient) to receive the database connection string information, but since we cant just send that back as plain text, we do need encryption and there is where I am stuck.
I use a class library to store the encryption methods (encrypt/decrypt) and implement that library in both applications, when a request comes in my console application is encrypting the data to send it back to the WPF application but my WPF application cannot decrypt the data, there is where I am running into exceptions thus the data stays encrypted and is basicly useless at this moment.
Can somebody please explain me how to fix this problem so any user can make requests with the WPF application to my console application while everything been send over the web is encrypted and safe?
I am fairly new when it comes to this topic, and when I look around on the internet I only get examples where encryption and decryption is done in the same application with build in classes inside the application itself rather then using libraries to share it across multiple applications within the same solution. So far nothing really helped me, i have been looking for 2 days for this now, watched a ton of youtube videos but they all end up the same using it in the same application...
If i do that aswell, it works fine, but once I try with my WPF application the data fails to decrypt.
I hope somebody can lead me to a solution with this.
My appologies if my english is a bit broken, I am trying my best to improve this.
If you need more information to understand my problem please ask, I provide as much info as I can
Related
Hi i have a C# WinForms app. I wrote essential methods on C#. But I need a login form and its not safe since apps like dotpeek can inspect the source code and hack it. Can i communicate with another application that is written in another language (java,c,python etc). I need to send input data from WinForms C# to another app then it should connect to database and check if login succesfull then return a value back to C# WinForms app. Is that possible, how can i implement that? I dont want to write all application in another language since C# has good methods to process images/pixels and gui support with very small memory usage.
I got the point you are trying to make.
One thing to admit is that you can't completely avoid decompiling of apps. C# or C++, no matter anything can be reverse engineered.
If you still need it, a comparatively safer approach is to not put the checking app at the client's machine. Create an API and host the database on a server.
Then initiate just an Http Request to the server from your Windows Forms app.
Then you have the full control of Login API and database. Many applications use OAuth similar to this. Another examples are apps verify it's license using an online API.
You can get a LightSail Windows server in around $10 a month if you want to setup. Try exploring
Your concern is not baseless. C#, or for that matter, any .net language running on the CLR, will be easier to inspect than a language like C or C++.
Having said that, no app will be completely secure, and communicating between apps has its own problems. How does one app verify the other? etc. You can create a web service that would communicate with the database (and communicate with the web service using HTTP or WCF) which would mean your app wouldn't have direct access to the database, but that would only protect the database from your app, it would still allow someone to inspect your app and use the web service, impersonating your app. Also, you would need to host the web service on some web hosting service, and then you would have to trust that service to not inspect your app...
You can reduce the problem by storing the password etc. as byte arrays, but regardless of what you do, I don't know of a way to completely safeguard your app. If a malicious app/actor is on your computer they can inspect your app.
As for your question itself - look into WCF or named pipes (includes a simple example).
As I developped a WPF .NET Core Application that interacts with an online MySQL Database using EntityFramework, I noticed I had absolutely no way of protecting my Database from being read or modified using the easily accessible connection string if my app was deployed and someone code reversed it.
I searched a bit and found these few possible solutions:
Storing the connection string in an encrypted app.config using aspnet_regiis (but .NET Core seems to be more oriented on .json configuration files, and therefore cannot be encrypted using aspnet_regiis)
Obfuscating the source code using an c# obfuscator like ConfuserEx (if I understood correctly it's just making the connection string harder to read, but it remains possible to get it and mess with the DB right?)
Building and interacting with API instead that would do the changes to the DB (but even then how to make sure the API requests are truly coming from my WPF app and not from a malicious user?)
If you know any more precisions about these solutions or perhaps have another way of making it secure and safe to connect to an online Database, detailed steps/links are very welcome!
Building and interacting with API instead that would do the changes to the DB
This would be the recommended approach.
(but even then how to make sure the API requests are truly coming from my WPF app and not from a malicious user?)
You can't really.
When you embed some kind of access key or a public URL in a client application that you expose publicly, you basically accept the fact that it may be exposed. You should assume that a malicious user can extract the key/URL from the client app regardless of any obfuscation.
The service may reject requests from IP addresses that it considers to be misusing the API but it will still need to handle those requests.
Managing a public API is not trivial. You may want to consider hosting your app in a managed cloud.
After some researches and tests, I found that the proper way to prevent a malicious user from reading and messing up with the connected database (even if he gets access to the connection string) is by Limiting my app to only execute Stored Procedures that will give the minimum data required. And for stored procedures that will read or change a user's sensitive data, also by having in their required parameters the user's secret token, which would be a random string generated in SQL the same time the user registers.
The only issue remaining is if the hacker spams requests to try to bruteforce (even if it's almost impossible to bruteforce a very long and safe token), it might still makes the MySQL server overload or even crash. To prevent that from happening the only solution seems to use an API.
I am newbie to the web programming. I have been working as desktop application programmer for the last 8 years. Now one of my projects is to create a web application using HTML 5 and some java script that can be live on the cloud as well as downloadable as a desktop application to work offline. I don't need any database to store any data. I am thinking of writing a C# win form application with a web browser control to load the HTML pages and the .js files.
My questions are:
Is it possible to achieve? if so, is there any other way than what I mentioned above?
What about the security concerns such as accessing the files(the html files, java script files, etc)? Whether this can be called into my application from the local hard disk?
If I can run it as a desktop application, how to make sure that the source code is not accessed by anyone in the client machine?
It's achievable, but why you would want to wrap it in a C# web browser control doesn't really make sense to me. With HTML5 you can define cache manifest files to create offline apps that run in any browser that supports it, no need to wrap it with anything as long as the client has a capable browser. They don't even have to know it's an offline app!
Not quite sure what you mean here with regards to security concerns. That's a massive topic. Just use common sense and realize that anything you store on their computers will be accessible by them (e.g. do not give them your public/private key pair or store any passwords or anything you don't want them reading in the files you're sending to them) and use a secure connection to send sensitive data back and forth between the client and your server.
You really can't prevent anyone from accessing the source code if it's on their machine. The best you can do is obfuscate it to a reasonable degree before deployment to make it harder on the person trying to read it.
I have developed a .Net 3.5 windows forms application. I also want to design a website that has a webservice with multiple Webmethods to query the database on the host machine. I want the webservice to be called ONLY through my winapp and my website! And I don't want any other people to be able to call and use my webservice but only some people who have access to the windows application that I have developed.
I need a good security scenario for this! I truly appreciate anyone who can help me because this is my first experience of developing a webservice and I really need it to be as secure as I mentioned!
What you're talking about is going to be difficult to do for several reasons, but primarily this:
If you put anything in code on your WinForms app, it can be decompiled very easily. You can obfuscate the code all you like, but it can be de-compiled.
Because of that, any code that you have in your app can be read by anyone with access to the code. You should always treat any WinForms app as if it's completely compromised, and ensure that the security at the server end compensates.
Because of this, you can't simply store usernames and passwords in configuration files or in code. You have to come up with something else. You CAN use authentication and prompt the user to enter a username/password on program launch, and use that. However, people tend to share these things, so you may want to go for extra protection.
You can put the connection info, or secrets into the app.config and encrypt it, but anyone who can de-compile the code, can recompile it, and add code to decrypt it at will.
You can provide signed keys with your app, and use that in an authentication mechanism, but that can be bypassed.
You can restrict your IP address to specific IP addresses, but those can be spoofed.
However...
By layering all of the above techniques, you can make it difficult for an attacker to bypass your precautions. We did the following in one of our apps where we had a similar requirement:
We set up a database that holds a GUID record for each authorized customer, and IP addresses allowed for that customer.
Every web method expects a CustomerKey parameter. (the guid mentioned above) Each call to a web service checks the key against the IP address.
If it matches, valid data is returned.
If it fails, valid looking data is returned. We actually return what looks like good data, but it's really not. This makes it harder for an attacker to know if they've actually broken through the defenses.
In the WinForms app, the key is stored in the app.config, which is encrypted in the main() event (the entry point for WinForms apps). This is to prevent the casual reader from accessing it.
The program is launched automatically on install, so that the encryption happens at startup, to minimize the chance someone can read the file before it's encrypted.
Also, the code is obfuscated.
Layering the defenses, hopefully, will discourage the average attacker.
Microsoft has some guidelines as well: http://msdn.microsoft.com/en-us/library/ff648643.aspx
The basic question
How do I know that it is my publicly accessible (client) application that is sending my service messages? How do I know that it is just not some other application that is impersonating my application?
Some Background
Currently we log all errors that occur on our websites via log4net and WCF to a database. This works well because the web server (accessible from the web - Partly Trusted) reports there errors to the WCF service running on the application server (inaccessible from the web - Trusted) via a trusted relationship. We therefore know that all error logs are real and we need to investigate them.
With our new sites we plan to make use of SilverLight to liven things up a little. The problem we are faced with is how to report errors back from the SilverLight application running on the web consumer's PC (Untrusted) to our application server (inaccessible from the web - Trusted).
We can solve the inaccessibility problem of the application server by making the client communicate via a service facade on the web server, so that is no worry. The problem occurs when we need to be sure that the application sending the messages really is our application and not just an impersonator.
Some Thoughts
The code will be written in C# and be running in a SilverLight application that runs locally on the client PC, so we cannot be guaranteed that it will not be decompiled and used to send fake messages to our service.
The above means that we cannot make use of conventional symmetric encryption because we can't store our private key in the application (it can be decompiled). Similarly we can't use asymmetric encryption since it could just be impersonated (the attacker could just sign messages with the stored public key and send them - the messages would look real)
In the case of this application there is no user authentication, so we cannot use that to provide us with trust.
Yes, I know this is rather bizzare with the error logs being better protected than the data the application displays, but it is the case :)
Any thoughts or help would be greatly appreciated!
Impossible.
You can authenticate users, but not the application.
Let's say you decide to digitally sign the application. This signature is then read at runtime by your client application checking its own executable binaries against this signature. There is nothing that prevents the adversary from simply removing this check from your application.
Even if you make it close to impossible to reverse engineer your application, the adversary could always look at the communication channel and write an imposter that looks indistinguishable from your client to your server.
The only thing you can do is validate the actions on the server against a user identity.
Presumably, your server is creating the web page that the Silverlight application sits in. You could create a short-lived temporary "key" that only that web page contains. When the Silverlight app starts up, it reads this key and uses it. Because the server itself has a constantly changing, very short list of allowed keys, you can be more sure that only your app is accessing your services.
The best advice for you in this matter is to hire a security expert to help you. This is not a unique or unusual problem -- consider any game (like WoW for example) that is attempting to determine if it is speaking to a true client or a fraudulent client. Even with a massive amount of effort (look up Blizzard Warden, I'm not going to link it here), they still have issues. The problem boils down to exactly how much time and effort your attacker is going to invest in thwarting your attempts to make thing hard on him. Just be sure to validate everything on the server-side. :)