Is allowing the AppPool local activation permission System Wide in dcomcnfg a big security risk? - asp.net

I've recently been trying to use the IIS AppPool identity instead of Network Service or Local System.
As such I came across the ugly error
The machine-default permission settings do not grant Local Activation
permission for the COM Server application with CLSID
{6E46607A-7347-471B-A98C-BC9E49B07248} and APPID Unavailable to the
user IIS APPPOOL\MyAppPool SID
(S-1-5-82-476059244-1685105758-59475158-1390954050-72429515) from
address LocalHost (Using LRPC) running in the application container
Unavailable SID (Unavailable). This security permission can be
modified using the Component Services administrative tool.
As you may notice my APPID was missing from this error, I searched the registry and found out which component it was (also by debugging).
It's a VC++ out-of-process OLE/COM server which processes requests from our web server. (Yay, 1990's called). I'm not entirely sure why this involves DCOM, there's nothing 'distributed' about it by design, maybe more by accident or an artefact of VS2008's default MFC/OLE server templates?
On using the power of Google, I followed the typical route of changing the dcomcnfg setting for this component to allow my IIS AppPool\MyAppPool user the local activation permission (I tried them all actually!), and confirmed that w3wp.exe is running as the same identity.
I also made sure that this exe was readable/executable by that user.
However the error still persisted.
Only by setting the same permissions machine-wide (via the My Computer node, instead of the individual component node), did the component load properly. This feels like a big security risk. Is it?
In the failing case, I tried using process monitor to spot any registry keys or file access problems, or to identify what other components might require access. But nothing reared its head.
Given that setting the DCOM permission system wide fixes the problem - It does feel to me that there's another DCOM component or service that needs permissions being set, but I can't find out which.
So
a) Is there a way to further diagnose this problem? Sniff out decisions being made by DCOM? Is there a central DCOM broker that needed the permissions set also? Debugging/Process Monitor doesn't seem to help.
b) Is it ok to set the AppPool local activation policy machine wide?
Many thanks to anyone who helps me make the right decision.

Q1. Is it bad practice to give your App Pool account local DCOM activation permissions, computer-wide?
A1: Yes, it's bad. According to the book Secure DCOM Best Practices
It isn’t a good idea to loosen these permissions from the default
values
Q2: Why is the component still failing?
A2: This was a combination of problems:
Process monitor DID pick up an issue that my AppPool identity was not able to read the registry key HKEY_CLASSES_ROOT\WOW6432Node\AppID\{C33D7656-D310-4684-9482-A486787E4E3B}. Enabling read permission for my AppPool identity got me one step further.
The event log message about an Unavailable AppID was a clue. There was no AppID REG_SZ entry for the class being requested. So the security settings were not being picked up. I needed to ensure the following key existed: HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{6E46607A-7347-471B-A98C-BC9E49B07248} with String Value AppID={C33D7656-D310-4684-9482-A486787E4E3B}
As per MSDN documentation AppID, and What is AppID

Related

ASP.NET application cannot access network share even with "Everyone" granted access

I have two servers: server A which is a web server running an ASP.NET application on IIS, and server B which is an SSIS server with a network share that contains a configuration file.
I need server A to be able to write to the configuration file on server B. This seems fairly straight-forward, however I keep getting the error: "Access to the path \\ServerB\files\config.xml is denied." What I have done for testing, to make this perfectly clear:
I have set "Everyone" to have full control of the folder.
I have set "Everyone" to have read/write access on the share.
I have set "Everyone" to have full control of the file.
I have verified that the file is not read-only.
I realize this isn't a good solution, I am just doing this for debugging so please don't comment to tell me not to do this.
Anyhow, even with these things set, I still get "Access is denied." I have also explicitly given access to a number of users, including Network Service, IUSR, Anonymous Logon, and IUSRS group, and it has not fixed the problem.
The application pool on Server A is using ApplictionPoolIdentity. I have Googled and Overflowed and found suggestions to give permissions to things like IIS AppPool\{Application Pool} or {MACHINE}\ASPNET, but I cannot access these resources from Server B so I do not understand how this would be possible.
Finally, the perplexing thing is that developers running solutions on their local machines are able to access the file. So it is something to do with how something is configured with Server A, however I cannot figure out what.
Edit: Truly wacky stuff going on here. I have figured out how to enable auditing and get the requests logged in the event viewer on Server B. When the developer runs the process from his local, I can see all the requests logged on Server B. Eg: "A network share object was checked to see whether client can be granted desired access."
However! When attempting to connect from server A, nothing gets logged. Nothing is there at all. Server A throws an "access to the path is denied" error, but I don't even see the request from Server B. :(
It has been long time ago but maybe it could be useful for someone.
Try and use the class NetworkConnection to access to the shared folder. You'll need to specify the path and credentials.
More reference about the class here:
https://gist.github.com/AlanBarber/92db36339a129b94b7dd#file-networkconnection-cs-L15
You seem to be using all Local Identities and I think that will not work on a network share despite what permissions you give. You need to make a domain user and run the app pool with that user and you should be good to go.
Also please do verify if the path is reachable or its access denied. Sometimes we go get the access denied message even though the path was not reachable.
You may need to edit settings in the Group Policy Editor on the machine where the share is hosted.
Open the Group Policy Editor via Start → Run → gpedit.msc. Set the following under Local Computer Policy → Computer Configuration → Windows Settings → Security Settings → Local Policies → Security Options:
Network access: Shares that can be accessed anonymously - Enter the name of the network share folder (files in your question above) in the text field. (Don't include the hostname.)
Network access: Let Everyone permissions apply to anonymous users - Set to Enabled. (For me, this was necessary for write access to be granted.)
When done making changes in gpedit.msc, from an admin-elevated command prompt, run gpupdate /force to apply the Group Policy changes.
Obviously, you should consider the security implications in your specific situation before making these changes.
You have to modify ApplicationPoolIdentity according to this article http://blogs.msdn.com/b/vijaysk/archive/2009/02/13/goodbye-network-service.aspx as it works with the NetworkService identity
Under system.web, on identity tag, set impersonate=true also set username and password of the production server

IIS application using application pool identity loses primary token?

(This is a question about a vague problem. I try to present all relevant data, in the hope that someone has helpful information; apologies for the long description.)
Our web app
We have a .NET 4 web application running in IIS 7.5 accessing Active Directory and a SQL Server database.
This web application is running under a virtual 'app pool identity', by setting the Identity of the application's application pool to ApplicationPoolIdentity. A concise description of virtual identities can be found in a StackOverflow answer, and the blog post to which it refers: an app pool identity is just an additional group which is added to the web application's worker processes which is running as 'network service'. However, one source vaguely suggests that "Network Service and ApplicationPoolIdentity do have differences that IIS.net site documents do not publish." So a virtual identity might be more than just an additional group.
We chose to use ApplicationPoolIdentity, as opposed to NetworkService, because it became the default in IIS 7.5 (see, e.g., here), and per Microsoft's recommendation: "This identity allows administrators to specify permissions that pertain only to the identity under which the application pool is running, thereby increasing server security." (from processModel Element for add for applicationPools [IIS 7 Settings Schema]) "Application Pool Identities are a powerful new isolation feature" which "make running IIS applications even more secure and reliable. " (from IIS.net article "Application Pool Identities")
The application uses Integrated Windows Authentication, but with <identity impersonate="false"/>, so that not the end user's identity but the virtual app pool identity is used to run our code.
This application queries Active Directory using the System.DirectoryServices classes, i.e., the ADSI API. In most places this is done without specifying an additional username/password or other credentials.
This application also connects to a SQL Server database using Integrated Security=true in the connection string. If the database is local, then we see that IIS APPPOOL\OurAppPoolName is used to connect to the database; if the database is remote, then the machine account OURDOMAIN\ourwebserver$ is used.
Our problems
We regularly have issues where a working installation starts to fail in one of the following ways.
When the database is on a remote system, then the database connection starts to fail: "Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. Reason: Token-based server access validation failed with an infrastructure error. Check for previous errors." The previous error is "Error: 18456, Severity: 14, State: 11." So it seems that now OURDOMAIN\ourwebserver$ is not used anymore, but instead anonymous access is attempted. (We have anecdotal evidence that this problem occurred when UAC was switched off, and that it went away after switching on UAC. But note that changing UAC requires a reboot...) A similar problem is reported in IIS.net thread "use ApplicationPoolIdentity to connect to SQL", specifically in one reply.
Active Directory operations through ADSI (System.DirectoryServices) start to fail with error 0x8000500C ("Unknown Error"), 0x80072020 ("An operations error occurred."), or 0x200B ("The specified directory service attribute or value does not exist").
Signing in to the application from Internet Explorer starts to fail, with HTTP 401 errors. But if in IIS we then put NTLM before Negotiate then it works again. (Note that access to AD is needed for Kerberos but not for NTLM.) A similar problem is reported in IIS.net thread "Window Authentication Failing with AppPool Identity".
Our hypothesis and workaround
At least the AD and sign-in problems always seem to go away when switching the application pool from ApplicationPoolIdentity to NetworkService. (We found one report confirming this.)
Page "Troubleshooting Authentication Problems on ASP Pages" has some suggestions related to primary vs. secondary tokens, and what I find encouraging is that it links the first two of our errors: it mentions NT AUTHORITY\ANONYMOUS LOGON access, and AD errors 0x8000500C and "The specified directory service attribute or value does not exist".
(The same page also mentions ADSI schema cache problems, but everything we can find on that topic is old. For now we consider this to be unrelated.)
Based on the above, our current working hypothesis is that, only when running under a virtual app pool identity, our web application (IIS? worker process?) suddenly loses its primary token, so that IIS only has a secondary token, so that all access to Active Directory and SQL Server is done anonymously, leading to all of the above errors.
For now we intend to switch from ApplicationPoolIdentity to NetworkService. Hopefully this makes all of the above problems go away. But we are not sure; and we would like to switch back if possible.
Our question
Is the above hypothesis correct, and if so, is this a bug in IIS/Windows/.NET? Under which circumstances does this primary token loss occur?
Through Microsoft Support I found out that we ran into the issue described in Microsoft Knowledge Base article KB2545850. This only occurs when ApplicationPoolIdentity is used. It occurs very easily, namely, after the machine account password is changed (which by default happens automatically every 30 days), and then IIS is restarted (e.g., through iisreset). Note that the problem goes away after a reboot, according to Microsoft and our observations.
According to Microsoft it is not possible to check if your Windows/IIS has gotten into this state.
Microsoft has a hotfix attached to this KB article. There is no indication when that hotfix will be rolled into an official delivery, and the hotfix is already 10 months old. In our specific case, we decided to switch to NetworkService instead.
See https://serverfault.com/a/403534/126432 for my comments on the same problem/solution.
Using the hotfix you linked to allowed me to get ApplicationPoolIdentity working as the docs say it should. This hotfix doesn't specifically describe a solution for accessing network resources as NT AUTHORITY\ANONYMOUS LOGON, but it's related to the computer password changing. Bottom line is that it worked for me, at least so far.
This is also relevant for Umbraco using Active Directory authentication.
From time-to-time you may get this exception:
Configuration Error
The specified directory service attribute or value does not exist
This is apparently caused by the problem outlined here. A reboot invariably fixes it.

Suddenly getting "Unable to make the session state request to the session state server"

The setup: 2 web servers and a seperate state server
I have two production web servers in a load balanced configuration. The ASP.NET web app they host shares state (like a web farm) using this line in their web.configs:
<sessionState mode="StateServer" stateConnectionString="tcpip=9.9.9.9:42424" cookieless="false" timeout="60"/>
9.9.9.9 is the IP of the machine the asp.net session state service is running on (ok it's not 9.9.9.9 really, changed to protect the innocent). It's a third machine (the database server, actually.
It worked fine until...
The error: website down!
Suddenly the site went down, just showing a generic asp.net error page ('turn custom errors off to see this error' or whatever).
The app's log recorded the actual error message:
An unhandled exception occurred Unable to make the session state request to the session state server. Please ensure that the ASP.NET State service is started and that the client and server ports are the same. If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection. If the server is on the local machine, and if the before mentioned registry value does not exist or is set to 0, then the state server connection string must use either 'localhost' or '127.0.0.1' as the server name.
So it appears that the web app was unable to contact the state server (9.9.9.9).
I "tried turning if auf and then onnegen" - restarting the state server fixed the problem.
Why?
I really want know what happened and why so I can prevent it happening again.
So far all I have are two theories:
A windows update, to .net framework 4, was applied around that time on the state server. So maybe the update did something to the asp.net state service? The windows event viewer showed that .net 4 had logged a warning around then:
Updates to the IIS metabase were aborted because IIS is either not installed or is disabled on this machine. To configure ASP.NET to run in IIS, please install or enable IIS and re-register ASP.NET using aspnet_regiis.exe /i.
Some kind of temporary network problem between the prod web sites and the state server? They do sit right next to each other in the same physical rack though.
??? Any other ideas, anyone?
Anyone seen this before, or able to correct me on anything?
Has this happened since? The easy answer is that the problem was with the db server, not the web app. Are there any relevant errors in the log on the db server?
The fact that both apps threw an error indicates that a common resource was the problem. We chased a similar issue for a good solid week awhile back, and eventually found a faulty fiber channel gadget. (that's below my OSI level, not sure about the details).
Start–> Administrative Tools –> Services
Right-click over the ASP.NET State Service and click “start”
It is working fine We need to follow the steps
Had a similar issue before when our Infrastructure team tried sneaking in an install of 3.5 when they forgot to install it on our Production box. Not bouncing a server after a framework update is just going to cause all kinds of weird problems.

I cannot save a file in the root of the server

I am using asp.net 3.5. And i am serializing an object in server, I rent a hosting and i want to modify something in a dinamic way with XML,
This is my code :
Stream writer = new FileStream(Environment.CurrentDirectory + #"\public_html\" + nombrearchivo.Text, FileMode.Create);
serializer.Serialize(writer, p);
this is my error message:
Exception Details:
System.UnauthorizedAccessException:
Access to the path
'C:\Windows\SysWOW64\inetsrv\dasd.xml'
is denied.
Thanks!!
The answer is in the error message: "access denied"
You do not have write permissions to that folder, which makes perfect sense; you shouldn't have write permission to that folder, at least you likely shouldn't.
If you need to cache something for later use, either use session for temporary storage, or talk to your hosting company about getting write permission for longer-term storage.
Environment.CurrentDirectory is a per process property that most likely is not the directory you want; in this case, it is the directory in which the IIS worker process is launched.
In any case, for typical ASP.Net hosting (as opposed to physical or virtual server hosting), you will be restricted by Code Access Security policy as well as the rights of the IUSR account that the IIS worker process runs as; typically this means very minimal privileges so as to attempt to limit the damage of a compromised or malicious web page script, usually significantly less than the privileges of your application-uploading login.
In short, you will need to arrange for an application-writable directory (and likely greater than medium ASP.Net trust as well) if you want to save files.
I discover that the problem was the path...
"\hmfsw\web\DTCWIN107\MYSITE.com\public_html\"
Worked fine! after asked the hosting provider 8 times they could tell me the right one
Thanks you very Much!!

Exception when ASP.NET attempts to delete network file

I've got an ASP.NET application that is trying to delete a file on a network share. The ASP.NET application's worker process is running under a domain account (confirmed this by looking in TaskManager and by using ShowContexts2.aspx¹).
I've been assured by the network admins that the process account is a member of a group that has modify permissions to the directory that contains the file I'm trying to delete.
However, it is unable to do so, and instead I get an exception (changed the file path to all x's):
System.Web.HttpUnhandledException: Exception of type
'System.Web.HttpUnhandledException' was thrown. --->
System.UnauthorizedAccessException: Access to the path
'\xxxxxxx\xxxxxxx\xxxxxxx\xxxxxx.xxx' is denied.
Any ideas on how to diagnose/fix this issue?
http://www.leastprivilege.com/ShowContextsNET20Version.aspx
Ensure your ASP.NET worker process has access to the specified file path.
You can try giving "full control" access to "everyone" and then paring back access until it works with the permissions you want.
It sure sounds like you are not running under the proper context.
A suggestion to deal with this a different way (a way that is much more secure) is to run under the default account and map to the network drive using the WNetAddConnection2 windows API. Using this API you do not change the context that ASP.net runs under, you simple map a drive connection. You can specify either a domain account or a local account. You can have it actually map a drive letter or you can just authenticate to a drive share without mapping a letter.
I have used this API from asp.net more than once and it works beautifully. Because you do not give ASP.net increased privileges this is much more secure.
More information on the WNetAddConnection2 API:
http://msdn.microsoft.com/en-us/library/aa385413(VS.85).aspx

Resources