I was thinking about how to secure the Data Layer in a C# Application, the layer could in this case be either a LINQ to SQL Model Diagram stored with the Application itself
One way would be to use a Trusted Connection to SQL Server, that way you don't store the username / password in code.
Shiraz Bhaiji came close, but I think they missed the key step.
Yes, you want access to the database to be mediated by a middle tier, exposed through WCF, which imposes whatever business logic you require, including full access control. This service does have the connection string that you want to keep secret, but it's not accessible to the WinForm clients.
The key step is that the client uses the user's authentication to gain appropriate levels of access, and never has any ability to contact the database or even get full control of the middle tier. The middle tier grants access to methods based on the groups that the client user is a member of. This means that a user with low security can call any method they like, but they'll get access denied exceptions, or data filtering, or whatever other failure mode is appropriate. The user account, on its own, has no access to the database, so the middle tier can do whatever it likes.
The obvious way to bypass this would be for the client to use the account of someone with full access. Of course, if they could do that, they'd already have what they wanted.
Hopefully, this approach would be useful in solving your problem.
edit
This solution does not allow LINQ-to-SQL in the client, just the middle tier. If that's a dealbreaker, then this isn't for you. Then again, the moment the client can access the database directly, a gigantic security door is opened up, and it's hard to close. There's a huge amount of extra work involved in securing the database itself so that it provides the sort of user-based, row-level security that comes naturally from a three-tier solution. I would generally recommend against it, although I do recognize that there are times when it is entirely appropriate.
The answer is simple to protect sql strings is simple. NEVER make a direct connetion to SQL in the client side.
Only accept well formed, schema-validated xml serialized objects as the entrance of your program, after being authenticated in a hashed public private key pair (http://msdn.microsoft.com/en-us/library/6f05ezxy.aspx) , being the public key certificate shipped within your program, so someone eavesdropping wont discover the password.
Also, watch out for DDOS attacks. Measure the use of each webservice exposed for each client, and if the use rises above a given limit, block all incoming connections from the user, and from the user´s ip.
I don't think there is any one-solution-fits-all to this problem, you will need analyze and adjust your solution to the particular problem you are having.
As far as I know there are no known ways of securely storing your connection information on the client side as your client is a "trusted" part of the communication to the server. No matter how you store the information, the client has to be able to reverse it or send it directly to the server, which also means that a potential attacker can repeat the process. Also any external communication directly to your database can potentially be intercepted/hacked.
The best way I can think of to protect your data is having a webservice (over a secure connection) as middleware controlling the communication with your database(which you need to secure) and adding logic to enforce whatever level of security you wish to attain. You can make it account based to grant different levels of access if needed. But the main thing is that it only allows safe/isolated operations.
To secure the webservice(middleware) there are two concerns, authentication and isolation.
You can use the standard .NET authentication as Steven suggested. I normally prefer rolling my own solution though for two reasons. First off, so far I've mostly ended up handling more complex users/roles. For example using permission based roles so that you can check for permissions instead of specific roles.
And second, it gives you more control. You can avoid session based authentication and you can also use challenge-response, for example challenge with a timestamp and expect a hash of the timestamp+password(which the user has to enter at application start) or some other creative combination as answer, I am sure there are better hash combinations to respond with. This should also be done two-way, to make sure that the client verifies whatever it gets from the server.
Also here are some SO topics about WCF Authorization that might be interesting: WCF Service authorization patterns Authorization and Authentication using WCF WCF Authorization - access to operations via claims And also a book and a paper (not free)
No matter how secure your authentication is, there is always the possibility of someone being able to access your webservice for malicious intents. As far as I know there is no one solution to this problem, but it is rather dependant on the specific application and how the data is structured and shared between users.
You will need to identify layers of isolation such that users cannot affect each other or the system in general, and also how the application is used. Will clients need to write data, or only read? If they write, is written data shared in any way and in what way can you isolate/verify that data? If they read, is the information private for the user, private for the system or shared among users?
For example a system for storing medical journals or personal task lists will have very isolated data and you can restrict access to your private information only (and possibly your doctor/boss depending on user groups). In this case you can isolate all data read/writes to the particular user, thus the attacker can only affect his own data, keeping everyone else safe.
If the data is shared between users you will need some way of verifying the input that is given from the user. Preferably you should also have some kind of trust-level for the user such as SO's reputation to prevent any one-time users to attempt a hack. This is really too specific to give any good advice on.
You also properly need to verify the input that you recieve to prevent hacks such as buffer overflow hacks and SQL injections. Allthough I don't know if buffer overflow is a problem with .NET, and SQL injections should be easily preventable with LINQ-to-SQL.
All in all there is no 100% guaranteed way of securing your data, and you should keep regular backups (separate from your database) of your data in case you get compromised and probably also transaction logs.
And as a final advice, if you are really serious about the security you should probably hire a security consultant and have a peek at how banks have set up their security infrastructure.
Also you can still use LINQ with webservices through LINQ to ADO.NET, though I haven't tried this myself.
This link might be more explaining How to move from LINQ to SQL to “LINQ to WCF”?
Where security is that important, for example when you are storing credit card information, you'll usually want the data repository and the webserver on seperate boxes, with a firewall between and both locked down by IP Security.
This way, only the webserver is exposed to the outside world. Your database server is sitting comfortably behind the firewall, and can only be accessed by the webserver through a certain port.
You might also consider SSL encryption on the web services and expose only HTTPS endpoints.
A secure method is:
Place the data layer behind a (WCF) service on an physically separate Application Server and have WinForms clients connect to the service using their Windows Credentials. The service then validates whether users can access the various methods in the service based on an Authorisation store (such as Active Directory), and database or combination thereof.
The data service can then use a single pooled identity to connect to a database.