Scott Forsyth's Blog

Postings on IIS, ASP.NET, SQL Server, Webfarms and general system admin.

Cloud Resources

IIS Resources

IIS’s ApplicationPoolIdentity Made Easy-Week 22

Managing Windows users for IIS security can sometimes be a pain and, if not handled correctly, can leave your server vulnerable. In this week’s video I introduce the new ApplicationPoolIdentity account that was introduced in IIS 7.0 and improved in IIS 7.5. This “virtual account” offers a lot of power and is easy to use once you understand the basics.. Since it’s the default account for application pools, understanding it is important for any web administrator.

This video demystifies this special account and covers information useful to the web pro.

You can find the video at its new home on DotNetSlackers.

http://dotnetslackers.com/articles/IIS-ApplicationPoolIdentity-Made-Easy.aspx

This is week 22 of a 52 week Web Pro series on various web administration related tasks. Past and future videos can be found here.

Comments

OWScott said:

Hi Rovastar.  That's great info.  I've seen the AspNetHostingPermission issue a few times but I haven't tracked it down to this issue previously.  I'll definitely keep this in mind.  

As for the France IIS reply, I believe him that it's possible although I haven't tried it personally.  But it's a lot of work to do that.  I always unblock zip files as soon as I download them from the Internet (the first thing I do), so if you follow that practice then you won't run into this.  That's easier than messing with the .NET code group.

# June 7, 2011 9:22 AM

Brian Vallelunga said:

Is the ApplicationPoolIdentity a member of the machine's Users group by default?

I'm trying to figure out how this interacts with permissions in a web-farm scenario. I assume they're only scoped to the individual web server, but I would like to remove the Users group permissions, as you outline in the next video.

# June 8, 2011 11:23 AM

OWScott said:

Hi Brian,

Yes, the ApplicationPoolIdentity is a member of the users group.

For network access, the network resource will see the computername$ account.  So the unique part of the user is only available on the local machine.

If you use something like DFS to keep content in sync and you access local resources only, then the ApplicationPoolIdentity works well, even on a webfarm.  To access UNC paths or databases on remote servers then I usually recommend maintaining your own custom app pool identity users.  Use AD users so that everything works with shared config.  ApplicationPoolIdentity doesn't fill the need very well on network access.

# June 8, 2011 1:11 PM

Brian Vallelunga said:

I'm using the new Web Farm Framework to synchronize settings and content between servers, and thus each server is accessing local resources plus a database.

The problem is that if I remove the Users group of permissions from my web folder, I'm not sure how I'd go about adding back the ApplicationPoolIdentity for each server.

I think in this scenario that domain user might be a better fit.

# June 8, 2011 2:08 PM

OWScott said:

Since content is synced locally for you, you should be able to just add the user to one of the servers and it will push out the SID to the other servers.  That SID will work on the other servers too.  That doesn't account for SQL Server.  SQL Auth is an option there.

# June 8, 2011 2:16 PM

Brian Vallelunga said:

Thanks. I've decided to just use domain accounts for simplicity. I also need to create random accounts for individuals to access a site while in development.

I currently have this structure, that seems to work well.

Group: web-clientname

App Pool: ap-clientname

User: joebob, which is then a member of web-clientname

With this, I assign the group read/execute permissions and then give write permissions to specific folders. The users automatically get read permissions and I can make as many as I need for a client.

Now I'm dealing with how to synchronize ACLs across multiple servers.

# June 9, 2011 8:43 AM

Brian Vallelunga said:

I've considered the issue with write access. Generally speaking we have very few third-party people accessing our systems, and those that do generally just need read access to view a development site.

The ACLs issue is interesting. WFF uses MSDeploy to synchronize all of the files. I've asked on the WFF forums to see if there's a solution, but nothing yet. In theory, I just need to set the includeAcls flag on MSDeploy, but there's no mention of where I can set that in the UI.

# June 9, 2011 2:02 PM

OWScott said:

The group assignment sounds like it will work well for your situation.

For the MSDeploy/WFF/ACL issue, it sounds like you're asking in the right place, on those forums.  When you do find out, I would be curious to know what you discover.

# June 9, 2011 6:03 PM

Gregory Suvalian said:

Thanks for this episode.

Questions/comments

1. How using ApplicationPoolIdentity is any different then using BUILTIT\Network Service? I don't see much difference, seems to be having the same limited permissions on local machines and MachineName$ on network.

2. For remote SQL authentication you can use Domain\ComputerName$ inside SQL manager to assign permissions to database objects. This is great way to avoid real domain account for AppPool identity since you never have to manage password or in fact make any changes IIS to make this work right out of the box.

# June 27, 2011 12:09 PM

OWScott said:

Hi Gregory,

Good question.  The Network Service account is more general than the app pool identity.  This is important in an environment where you need to protect sites from either other.  Note: even if the sites trust each other it's best to isolate them so that a hacker exploiting one site should be blocked from hacking another through ntfs permissions.

Consider a server with 2 sites on it: Site1, Site2.

If you lock it down with Network Service, then you need to give Network Service at least read permissions to Site1 and Site2.  That means that Site1 can access Site2's content and vice versa.

However, if you use the app pool identity only, then Site1 can't access Site2.  Neither can Site2 access Site1.  

So the app pool identity offers complete disk level isolation between sites, without needing to create custom accounts and manage passwords.

For your point #2, you're correct that that works.  The issue is the same though in that granting the entire server access to a sql server database doesn't protect against other sites on the same server.  And if the server is exploited, then almost any account type on the server will have the ability to access your database.

It's not completely taboo to do that if you manage and trust all sites on a server, but using the most specific account possible offers the best security.

# June 27, 2011 12:35 PM

OWScott said:

Hi Ricky.  There isn't anything specific between the system or other volumes per se.  However, ASP.NET requires that it have list permissions from the root of the drive up to the site.  You can try adding Users with List to the root of the drive and any folder in-between if it doesn't already have it.  

Your permissions at the site level should be SYSTEM/Full, Administrators/Full, IIS Apppool\{apppoolname}/Read (or write if needed).

Also, make sure that the anonymous user at the site level is set to use the app pool identity.  If you don't do that, then make sure to also add the site's anonymous user identity.

If it still doesn't work after reviewing that, the best tool to troubleshoot this is procmon.  Check out week 20 for a walkthrough on that: dotnetslackers.com/.../LearnIIS7.

# September 19, 2011 5:52 PM

Richard said:

Hi Scott, thanks for the video, i've followed the instructions and its working like a charm. Like you did in the video I ditched the users group from my inetpub, so the filesystem rights for two pools are isolated. However, I noticed it's still possible to sniff in directories like C:\Windows or C:\Program Files with my application pool set to a ApplicationPoolIdentity. I.e., every directory where the "Users" Group has access to.

Basically any website in full trust can access the C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files folder and sniff through the source of other websites (after decompiling), right?

Is it possible to remove the ApplicationPoolIdentities from the Users group so they can only access their own website folder?

# May 10, 2012 12:05 PM

OWScott said:

Hi Richard,

That's a good question.  The app pool identity can't be removed from the Users group, and ultimately you wouldn't want it to.  The app pool worker process needs to have read permissions to access things on disk and in the registry.  The whole c:\windows folders and many subfolders have read-permissions, for example.  

If the worker process needs to access them, that's the group that it accesses it through.  For the most part this isn't a problem since the windows file structure is made up of common files which anyone can obtain for a windows installation disk.  As long as there aren't read permissions to any of the log folders and there aren't write permissions, then it's generally fine.

And it's the same with the temp folder.  The worker process needs read/write access to the .NET temp folder for whatever it needs.  That is a known concern with ASP.NET because of the shared working folder.

There are two solutions to the temp folder issue.  One is to give each user their own temp folder.  It's possible with web.config to set the temp folder.  If every site on a server is given their own custom temp folder then they can be locked down specifically.  That's a management nightmare though, but it is possible.

The other option is to use Code Access Security (CAS) which allows you to isolate a user to their own folder.  That's the purpose of CAS and the safest solution.  However, the drawback is that CAS only applies to .net versions where you set it, so it doesn't protect against PHP or Classic ASP, and CAS can be a pain to manage if you need to grant access to other permissions which aren't in the default medium trust template.

So, as you can see it's a big issue that doesn't have an easy answer.  That said, CAS in particular is a fully supported solution for this.

And regarding the app pool identity user, it's really meant to protect the website folder from other sites or apps on the server, but it doesn't specifically protect the rest of the server from the website.

# May 10, 2012 1:43 PM

Richard said:

Thanks Scott, really appreciate your response!

# May 10, 2012 2:53 PM

Rajesh Cheedalla said:

If I set App Pool Identity with network user credentials that has access to database and Website application code path (UNC folder) with different domain user credentials  how that affects access to db? I noticed that db is being accessed with domain user credentials rather than network user. Has anyone experienced similar issues?

# January 29, 2013 6:27 AM

OWScott said:

Hi Rajesh,

If you access your account as an authenticated user then it will run as that user rather than the app pool identity user. If you turn off Windows auth and just have anonymous auth enabled, or if you try with a non-IE browser, then I believe it will run as your app pool identity instead (I haven't tested or reviewed docs on this in quite some time but I'm pretty sure of this).

# January 29, 2013 12:51 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)