How to use File.Encrypt from ASP.NET - asp.net

I have a simple C# ASP.NET MVC app (on Windows Server 2012 R2 & IIS 8.5) for uploading files to a server. I would like to automatically encrypt these files using File.Encrypt(path-to-file), but I get
System.IO.IOException occurred
HResult=-2146499771
Message=The requested operation cannot be completed. The computer must
be trusted for delegation and the current user account must be
configured to allow delegation.
IIS is running under the default IIS_IUSRS account, which has "Full Control" rights to the folder in question.
What I am trying to accomplish is a simple Web app where sensitive files can be uploaded by clients, which then can be accessed by authorized users only via the Web app (with no direct access via the file system, since only the encrypting user account can decrypt the files).
I realize that this solution has shortcomings, but so does public / private key based solution (you get stuck with the problem of where to securely store the private key for decryption). What I am primarily interested is a solution to my specific scenario.
How can I get this working?

I got this working by creating a user (with minimal rights and a strong password) specifically for the app pool and using it as the App Pool Identity.
I originally wanted to avoid doing this (I thought it would be less secure), but according to Microsoft's "Security Best Practices for IIS 8" (https://technet.microsoft.com/en-us/library/jj635855.aspx), it is not a problem:
Using a custom identity account is acceptable, but be sure to use a different account for each application pool

Related

ASP.NET/IIS7 - Securing access to SQL Server for multiple user roles

I'm working on an web application using ASP.NET 4.0, C#, and IIS7. The web application is a content management system that defines multiple user roles, such as editor and administrator. These users and roles are managed by the asp.net membership framework, and the associated database tables are integrated into the web app's database using aspnet_regsql. Finally, the web app is running under the ApplicationPoolIdentity. Thus, the web app runs under the virtual account "IIS AppPool\" which it does not share with any other application.
The site is designed such that user accounts are handed out by the administrator (there is no public sign-up page), although this detail may be irrelevant. In any case, the administrator should have the power to create and delete users and edit any of the content on the site. Editors, on the other hand, should be capable of editing only assigned sections of the site. Finally, anonymous visitors to the site should only be capable of viewing the content, with no option to edit.
The question is: Would it be insecure to just give read and write access in the SQL Server database to the IIS AppPool\ virtual account and give functionality to different user roles in the underlying business logic for the web application?
I wouldn't think so, but due to the necessity of the integrity of the data, I thought it might be a good idea to seek the opinion of another developer.
If (and only if) this does pose an unforeseen security risk, would it be a better idea to use impersonation, store multiple connection strings in the web.config file with SQL authentication, or track user privileges in the database itself?
The question is: Would it be insecure
to just give read and write access in
the MSSQL database to the IIS AppPool\
virtual account and give functionality
to different user roles in the
underlying business logic for the web
application?
This is how it's usually done, and for most business cases this is enough. There are insecurities in every application so you have to do the best you can to avoid buffer overflows, script injections and SQL injections, scrub your input, etc.
If (and only if) this does pose an
unforeseen security risk, would it be
a better idea to use impersonation,
store multiple connection strings in
the web.config file with SQL
authentication, or track user
privileges in the database itself?
Using impersonation is not uncommon, and very easy if you're using Windows Authentication. It's an administration headache, since users have to be added via database security in addition to the application database. Multiple connection strings is probably the least extensible and favorable of the approaches, not to mention it would hurt performance on a busy site.

Using Windows Identity Foundation to log someone in to an ASP.net application

My supervisor at the office tells me that he saw a demonstration with a pre-release version of Microsoft "Geneva" (now Windows Identity Foundation) where a developer did the following:
He set up some sort of ASP.net web application where a user could log in using a customized log-on system. Behind the scenes, the web application logs the user in as a user in an Active Directory.
The user logs in.
Once the user is logged in, the the ASP.net web application thread runs as the logged in user for the duration of the user's session and can access resources on the network (such as running SQL queries on tables whose access is controlled Active Directory)
Steps 2) and 3) are exactly the same as using the "Integrated Windows Authentication" setting in the "Directory Security" tab of the web site settings in IIS. Step 1) is different because we are using a custom log-on system as opposed to the Kerberos authentication.
We want to set up one of our applications to operate exactly as described in 1), 2), and 3). However, all the documentation that I've seen regarding Windows Identify Foundation is about Cardspace and Federated Security. We have zero interest in using either of these technologies right now.
We just want to be able to log users in to Active Directory Accounts behind the scenes.
Yes, we've tried the ActiveDirectoryMembershipProvider with Forms Authentication, but it's a complete kludge to actually access resources on the network requiring impersonation on every page!
UPDATE Jan 7, 2010. Okay, I've been working at this for a while, and everything I've managed to come up falls short of what I want to achieve. Perhaps the functionality I want is not in the release version of WIF.
Here's where I'm at now. I've found some documentation on MSDN that indicates that there are three different identities used in ASP.net: the identity specified by HttpContext.Current.User, the identity specified by Thread.CurrentPrincipal, and finally the identity specified by WindowsIdentity.GetCurrent. link
In one example of where I want to use the process I'm looking to design, I want to perform a SQL query as the logged in user. In my debugger, I see that I easily set the HttpContext and Thread users to the logged in user. However, when I connect to the SQL server using Windows Authentication, it always always always connects as the WindowsIdentity.GetCurrent user and that user is always always always the identity of the ASP.net process unless I'm using Windows Authentication with impersonation. I absolutely cannot use Windows Authentication with my application because my users must log in by playing a magic flute song and Windows Authentication has no support for logging in with magic flute songs.
To clarify, there is no trouble with obtaining a WindowsIdentity representing the logged in user (who logged in with a magic flute song). The problem is that I cannot use that WindowsIdentity to perform SQL queries for my user.
WIF allows you to configure it so a claims based identity maps to an AD account, the claim may either be a federated identity claim, or delivered via an information card. c2WTS performs this function.
Even when it does map because of delegation you're always going to have to delegate if you want to use the AD identity IIS is impersonating - that's just how it works, unless you setup Kerberos delegation for IIS
You can achieve the same using Identity Impersonation in ASP.net. Also you need to enable windows integrated authentication for you web app. This will solve the purpose. If the logged in user does not have the required rights to access resources you will get security exceptions which you will have to handle.

What account should I use for ASP.NET?

By default ASP.NET uses the network service account, is this the account I should be using with ASP.NET in production? What are the best practices related to the account used by ASP.NET?
Regards
Edit: If this makes any difference, I'll be using ASP.NET on a Windows 2008 server
For production, you should create a service account that has only the bare minimum permissions in order to run the web application.
The Microsoft Patterns and Practices team provides the following guidance on this:
How To: Create a Service Account for an ASP.NET 2.0 Application
You're gonna get lots of "it depends" answers but here's my 2 cents anyway.
Consider password change management, potential damage through compromise, as well as application needs e.g. trusted connectivity.
In most scenarios Network Service comes out best in these dimensions.
it doesn't have a password, and never expires - no change management required
it cannot be used as interactive login on other machines
it can be used in trusted connections and ACL'd access to other hosts via the credential <domain>\<machinename>$
Of course your app may have different needs - but typically we use Network Service wherever possible - we run 10,000's of machines.
Unless you have some other need -- like a requirement to use integrated authentication to SQL Server for a database connection -- I would stick with the default account. It has fewer privileges than many other accounts, yet is enabled with the necessary privileges to run web applications. Caveat here: we typically don't make any privilege changes for the network service account and usually fire up a VM per production application (or set of related applications) rather than configuring multiple applications per server. If you are running multiple applications per server or make changes to the network service account's privileges for other reasons, you may want to consider using a separate service account for each application. If you do, make sure that this service account has the fewest privileges necessary to run ASP.NET applications and perform any additional tasks required.
You should use a lesser privileged account possible
1) Create a specific user account for each application
2) Create an Application Pool that runs under this account
3) The Website should be configured to run under this Application Pool.
4) In SQL Server, use Windows Authentication and give DB permissions to this User.
5) Use this User in a connection string (ie no passwords in connection string)
6) Use this User to assign permissions to other resources as required.

Preferred DB Connection for ASP.Net

What's the preferred (best practice) means of connecting an ASP.Net Website to a database? I doubt it's as simple as using Trusted-Connection and giving the NT-Authority accounts access.
What do y'all do? Assuming a clean install of SQL Server (2008), what do you do to configure access to the database for a website?
I usually run ASP.NET app pool as a separate account (not NT AUTHORITY\NETWORK SERVICE) and use Windows authentication to access the SQL Server. This method has the advantage of not storing the password in config files.
Steps:
Create a user account to run your ASP.NET application on.
Create an application pool in IIS and run it on the created account.
Assign NTFS permissions that your application needs to the account.
Grant permission to login on SQL Server.
Assign the appropriate database roles to the created login.
This will work for many apps. For more complex security environments, you might need more sophisticated strategies.
I used to use trusted connections, but ended up feeling that that sometimes I ended up having to grant too many privileges to the service account used for the connection/app pool. Now I use SQL Server accounts and set up the application to encrypt the connection strings during Application_Start if they aren't already encrypted. In fact I encrypt any section that may contain user credentials. I use an appSetting to determine whether the encryption code runs so I don't encrypt my settings in the development environment.
I also use SQL Server accounts, just find it simpler to do and to troubleshoot.

IIS7 Permission Problem

I have a normal Windows Server 2008 installation with II7. Each website has it's own application pool. But there is a security realated problem.
There is no restriction for an asp.net application to write a file into C: or any other directorys.
In IIS 6 before this could happen I would have to set those rights in the windows folder secuity permissions and allow the ASPNET_Usr to do that.
What is the best practice for hosting asp.net applications and not allowing them to write an read files in eg c:?
EDIT
Anonymous Auth. is enabled and the User specified is "ISUR". All other Authentications are disabled. In the application pool I use as Process Identity "Network Service".
I created a new User on the Server (not in the domain) "www.xyz.test" and deleted all his group memberships. Changed the Process identity to this user and made the anonymous authetication use the app pool identity and was still able to write to C:.
Changing the trust level is in my case not an option because we use an 3rd party application
It all depends on what user account your asp.net website is running on. I.e. is it Network Service? As far as I am aware, if I want to be able to write to the web directory then I give my website account write access solely to the directory where I want to save files. The account I use is the one used for Anonymous Authentication.
I.e. I have a website called mycompany.com . I create this user account as part of the domain user group. I add this as the anonymous authentication credentials and give it access to the web root, and also write access tot he nested folder which I want to write too.
The User account would be called mycompany.com so i know that it has a reponsibility solely for permissions related to the web and that particular website.
Sounds like the web site permissions (in IIS) are set to either
- Windows Auth: And you are logging in with someone who has permissions to those folders
or
- Anonymous Auth: And the account that is being used for impersonation has permissions
Best practice would be to make sure the account which is being used to access the site (i.e. if windows auth - your account or if anonymous then the account which is impersonated) does not have permissions on the folders.
You could also raise the trust level to medium, high or full in the machine.config for additional security enforcement policies - however use with caution as it can cause some ASP.NET apps to fail.

Resources