I wanted to know if it's possible to have a page on another server query the database on our server, or is that a big security no no?
This is a very common practice.
Sometimes several applications are sharing the database(s).
Sometimes the database is on its own server so that the server can be optimized for the database, and the database can use all of the server resources instead of sharing them with the web server.
Security is handled by setting permissions in the database, regardless of whether the calling application is on the same machine. Generally, applications will operate with their own identity and credentials. They are given very limited permissions on the database.
Yes it is possible, you should just make sure that you follow proper steps to minimize any security risks. How is your page going to connect? What type of connection? Make sure the permissions to the DB are only based on what the page needss and nothing more. Make sure your page also protects against possible attacks such as SQL injection, etc.
In short, yes this is possible and perfectly normal. I do recommend you do some research on proper practices and preferred security settings.
it can do so, without any security violations.
Related
I've had some recent difficulty with SQL Server not liking the default AppIdentityUser for logins, so I went ahead and created a custom DB user with write access.
But it made me wonder - is this the best approach?
I was wondering what the best SQL Server login approach would be for Asp.Net Core. I know there's a question similar to this for normal .NET, but you can't encrypt a Core web.config/appsettings.json (well, in a quick and straightforward manner).
Here are the options as I see them:
Connect via SQL Server ID that is stored in appsettings.json.
Pro: Already configured.
Cons: Password in web.config/appsettings.json; have to specifically configure SQL Server ID. Not centrally revokable.
Connect via user NT ID via ASP.NET "AppIdentityUser".
Pro: No passwords in appsettings.json.
Cons: Not centrally revocable. Seems to be restricted to the server name for user.
Connect via Active Directory user.
Pro: Easily revokable.
Cons: Active directory user password in appsettings.json. Could be bad if somebody accidentally reuses that user in another application in the company, and that user gets breached.
Are there other options that I'm missing? Which of these options are used in which situations? Which are more standard? Are there pros and cons that I'm not thinking about?
You should absolutely use a custom SQL Login to connect to the database. Under the hood, the SQL Login could be tied to a local account, service account, network account, etc. It doesn't actually matter.
The real issue you seem to be having here is in not wanting (rightly) to expose login credentials in plain text. I'm not sure why you keep referring to Web.config here, as ASP.NET Core doesn't use that. Instead, there's various configuration providers that can be optionally utilized. By default, ASP.NET Core (at least since 2.0) adds a JSON config provider that looks for appsettings.json and appsettings.{environment}.json in your project, a command-line configuration provider, a user secrets config provider, and finally an environment variable configuration provider.
The last two are the most interesting for your circumstances. In development, you should use user secrets. In production, you should use environment variables. However, neither stores secrets in an encrypted way. The benefit to either approach is that the secrets are not in your project, and therefore also not in your source control. Even though neither is encrypted, it's not as big of a concern as you might think. Getting at the secrets in either would require direct access to the server/development machine. Additionally, user secrets is by default tied to a particular user account, accessible only to that user, and environment variables can be set up the same way. Therefore, someone would need to both gain access to the machine and gain access to the particular account. That's actually a pretty high bar, and if it were to occur, exposing a database password is really the least of your concerns at that point.
Nevertheless, if you want true encryption, you have the option of using Azure KeyVault. KeyVault can be used whether or not your application is actually hosted in Azure, and while it's not free, it's exceedingly cheap.
Finally, you can always create your own config providers or source third-party ones. For example, while the default JSON provider doesn't support encryption, you could potentially write one that does.
We currently use a connection string to authenticate our database credentials. Due to grown and compliance the developers are no longer allowed to "see" the database credentials that our websites use. Are solution to this problem is use Integrated Authentication. We planned on setting up a user per App Pool and then allowing that use access to the Database.
My question is: Are there any security concerns around this approach? As far has removing the DB credentials from the connection string, is there a better(easier or simpler) approach we should/could be taking?
If you need to secure and audit access to the production database then Windows Authentication is a better choice than Sql Authentication for a number of reasons:
You can control exactly who can access the database via NT groups and permissions, which means you know who specifically has access to the database. The pool of access with sql authentication is only limited by who knows the password. Given n people who know the password, tracking who did what at a certain point of time is trickier (but not impossible) given that.
Only your sysadmins need know the password for the nt identity with access to the database; in fact, much of the config can be done only knowing the username
Logins and access can be tracked at the domain level far more easily than with SQL Server logins.
What it wont give you is:
Ability to ensure that the developers can't see production data - whoever writes the app can easily include some diagnostic routines to select out data
Ensure that production data only stays in production - anyone making a backup of the production database (say to restore it to a UAT environment for testing) could easily expose production data.
Problems with this approach have already been discussed in other posts; in particular, with ASP.Net applications, you have to consider whether or not you are going to use Impersonation/Delegation (webserver can act as the NT user accessing it) or a Trusted User model (where you configure a fixed identity to access certain resources).
This is further complicated by the IIS version you are using.
If your connection string is stored in a web.config file, you could create a separate production version of that file that the deverlopers can't see. That's easier to test and setup than integrated authentication using app pools.
One word of warning though: If you restrict developers that much, it will slow down their velocity of change. Since the rest of the world does keep moving, this usually ends with the application becoming a dead legacy package. That's dangerous if you plan to grow, improve or extend.
Use of application pool's identity can be quite complicated to set up, consider trust and delegation problem.
A better option can be securing connection strings using encryption.
I am trying to secure a MSSQL database for our .Net website.
I wanted to separate the database into different schemas so that we had an schema like 'Account' which had personal information and a schemas like 'Public' that had generic public content data.
Each of these schemas would be accessed using different SQL user accounts and they would each need their own DBML since they would need separate connection strings(we are using LINQtoSQL).
My colleague is claiming that since we just have both of these accounts in our web.config anyways this design is no more secure than just using one SQL server account that has access to the whole database. There is no need to separate the schemas since we aren't using Windows based authentication.
So my question is who is correct? Would separating the database into schemas be any more secure? Or is it a waste of time since both SQL accounts would be located in the web.config (even if encrypted)?
Your colleague is wrong on one level and right at another.
Breaking the database into schemas as you propose will help with attackers who are able to find things like SQL injection flaws. If you are diligent in setting your permissions, that is...
However, splitting the schema like this offers no additional benefit if someone manages to get into the actual file system and can red the web.config.
You need to think about all the possible layers.
If you haven't already, check out this great resource:
http://msdn.microsoft.com/en-us/library/ms998372.aspx
Also, try googling storing your connection strings in the registry. There are some good references for that, which will help protect you if someone gets into the file system and can read your web.config.
Finally, don't forget to encrypt your web.config...
Separating the accounts will reduce the risk in case the attack vector is SQL Injection. The attacker will only be able to do whatever is allowed by the priviledges of the session is using to carry on the injection. Presumably only an authenticated attacker can use the Account session as the injection vector so he will be detered because it can be discovered from logs who did it. Wether this separation is an effective mittigation of a threat, it depends a lot on information you left out, most importantly how do you separate access to the two areas in your code.
Having both connection strings in the web.config means that if the ASP pool itself is compromised then an attacker can use both string.
I presume the strings are encrypted none the less, see Encrypting Configuration Information Using Protected Configuration. This way at least the connection info is not lost if the web.config is leaked.
Well if you encrypt the section the accounts are in, I don't see what would be the problem. The only problem could be on connection pooling, it will fragment the pool in 2 that's it.
Working inside the context of an ASP.NET application I am creating a page that will be able to execute database scripts against one of many databases in our environment. To do this we need to prompt the user for a username/password combination, this value can be used for all servers without issue.
The question is where is the most secure location to store this information? We need to store it temporarily as when they are on this specific page they could be executing hundreds of scripts, over multiple postbacks. From what I can tell I have 3 options and I'm not sure what is the best. Below is my take on the options, what is the recommendation of everyone here? What is the most secure, while still being friendly for the user?
Store Information In Viewstate
One of the first ideas we discussed was storing the information after being supplied by the user in the ViewState for the page. This is helpful as the information will only exist for the lifetime of the page, however, we are unsure of the security implications.
Store information in Session
The next idea we had was to store it in session, however, the downside to this is that the information can be made available to other pages inside the application, and the information always lingers in memory on the server.
Store Information in Application
The last idea that we had was to store it in the Application cache, with a user specific key and a sliding 5 minute expiration. This would still be available to other pages, however, it would ensure that the information is cached for a shorter period.
Why?
The final question that is important is "Why are you doing this?". Why don't we just use their Lan id's? Well we cannot use lan id's due to the lack of network support for delegation.
S0 what is the recommended solution? Why? How secure is it, and can we be?
Update
Great information has been discussed. TO clarify, we are running in an intranet environment, we CANNOT use Impersonation or Delegation due to limitations in the network.
In my opinion the natural place for this is the Session.
I'm not sure why you seem to be fearing "other pages inside the application" (you control the appliciation, don't you?), but if you really are, you could use some sort of encryption before you store it.
But if you are going to do that, the data could live in the ViewState as well.
I don't like any of these ideas, but totally hate the viewstate idea.
I don't know how many databases you are attaching to, but if there is a limited number, I kind of wonder if handling your authentication and authorization in a standard secure manner, then connect to those databases via integrated security using identity impersonation with an account that has minimal permissions.
The ViewState approach is good but has the problem that you are giving out the username and password to the client. Even if you encrypt it, if some attacker has the encryption key, the situation will not be very good.
Regarding the Session and Application approaches, I don't think Application approach makes sense. Data is user specific, so Session should be the way to go. It'll go away as soon as user's session is closed. By the way, if you chose to store it at the server, use SecureString class.
As John MacIntyre wrote you should use integrated security and impersonation for this.
If for some reason you can not use it and you are going to provide your own login page, use by all means SSL to encrypt the traffic between the browser and your server. Using the ViewState approach is also completely insecure if you do not use SSL, there are tools to view the contents very easily. From the methods that you enumerate the best one would be to use the Session state. You can offload saving the session state from your web server memory and save that data in a database that you can secure the way you want. If you don't like the way these work you could even write your own session state provider and apply the security you need there.
Storing in Viewstate increases your exposure because the password will be flying around the internet again and again. It's up to you if encryption is good enough to address this risk.
Using Application or Session both keeps the password in the server. As mentioned above SecureString will keep people from simply reading passwords out of memory. Session will scale to more users, and probably more importantly to multiple servers much easier than Application. Unless you are sure you will never use more than 1 web server I would not use Application, as it will be up to you to synchronize all the servers.
Never store passwords!
Rather store the hash of a password. See: http://en.wikipedia.org/wiki/Crypt_(Unix)#Library_Function.
I'm aware this does not answer the question, but the more programmers who ignore this advice, the easier it will be for criminals to steal data. Don't let your organization become a news story.
The username/password really shouldn't be stored anywhere.
You store a live database connection, preferably from a pool in your Session object. You only need the username/password as long as it takes to log into the database.
While another page can use the live connection, it doesn't give anyone else permanent access to the database as you would by storing a username/password.
Is there an elegant solution for synchronizing sessions across multiple ASP.NET applications? I'm sure this could easily be considered a security hole, but there is a 3rd party ASP.NET application involved, for which there is no ability to extend. For this reason, a second [related] site is being developed, but will require direct access to the sessions created on the 3rd party application.
As an example, when a user logs in/out of one site, the same operation should occur on the other site. However, it's important to note that this goes beyond a typical SSO.
Using SQL Server to store is one of your most easy solutions.make sure you have proper permissions set on the SQL objects. I am not familiar with what Manu has suggested. There is actually one more way of doing it which is a little difficult. Its done by implementing a modification of the memento like pattern. App1 stores session info in the database but instead the other application App2 getting access to the DB, the session info is exposed via a service which App2 can reference. Once the user moves on to app2 and is authenticated, its session is restored using the service.
Hope that helps. It worked for me in one of my projects.
Try memcached session state provider: http://www.codeplex.com/memcachedproviders
Since the cache runs in a seperate service, I am pretty sure you can access the same storage pool from different apps.
Cookies are an option assuming the application is storing some key data in its cookies. If the other site is in the same domain, it can read them.
Use NCache - http://www.alachisoft.com/ncache/
It'll help you to acheive what you are looking for.
It has built in distributed ASP.NET session state cache as well, and will help you to share sessions across multiple sites. Details Here