views:

553

answers:

4

I have a strong gut feeling that using SharePoint RunWithElevatedPrivileges should be avoided like the plague, but need to convince some others as to exactly why. Here's what I have.

  • Spawns a new thread with elevated privileges
  • Blocks other operations until the passed delegate returns
  • Security problems (runs with a high level of privileges, perhaps by an end user)
  • Others?
+2  A: 

RWEP, like everything else, have pros and cons.

If you're concerned about end user running RWEP, probably you already have a bigger problem, since that code already has been installed on GAC.

Sometimes, you just need to stick with it: consider a user which doesn't have admin rights, running a document workflow. After this user approves (or reject, doesn't matter) it, your workflow engine should be able to redefine that SPListItem privileges.

Rubens Farias
Could be another good reason to avoid RunWithElevatedPrivileges. Code Access Security. Ruben, could you confirm the source for the GAC requirement?
Tom Resing
A: 

I use it, and find it to be very useful functionality. In my view, I am choosing to let the user run my code and have that code do stuff that the user could not normally do. You can lock something down, and still let the user access it in a very controlled manner.

Chrisb
"do stuff" is very broad. For accessing SharePoint objects, it should be avoided. Instead follow dahlbyk's suggestion of SPSite Impersonation removes the complexities of RunWithElevatedPrivileges read more at:http://solutionizing.net/2009/01/06/elegant-spsite-elevation/
Tom Resing
+3  A: 

1) Substantial use of RWEP is a good indication of code smells. It can be easily abused without thought which leads to serious security problems. Many developers don't think about what users could do with the power they are indirectly being given "under the hood".

Just one example: it is important to call ValidateFormDigest before using RWEP to prevent malicious requests in application pages.


2) SPWeb and SPSite objects need to be created in the context of RWEP. This is easy for novice developers to forget, leading to much frustration.

This restriction also means that all work and any objects created by these objects have to be used and finished with before the end of the RWEP delegate. This is another common mistake.

Keith Dahlby has written extension methods to get around these problems, giving more robust and readable code.

Alex Angas
"good indication of code smells" - I like that. Too bad noses don't work for that, too. ;)
Tom Resing
+9  A: 

Reasons to elevate fall into two categories:

  1. Your code needs to perform operations in SharePoint for which the current user does not have permissions. This should always be done while working with SharePoint security, not as a "just in case" measure which indicates you need to understand your security situation better.
  2. Your code needs to access external resources (server file system, database, file share, etc) to which the application pool identity has access but the current user does not.

For the former, you're much better off using SPSite impersonation. The latter is the only reason I ever use RWEP.

To clarify, RWEP does not spawn a new thread. Instead it uses Win32 APIs to revert the current thread's identity back to the process identity (turning off impersonation) to run the elevated code, then switch impersonation back on to resume work on behalf of the current user. This has several implications:

  1. RWEP does nothing if the thread isn't impersonated, so it is useless in timer jobs, Visual Studio workflows, console applications, and code run via stsadm (feature receivers).
  2. Access to SharePoint, assuming you create a new SPSite in your CodeToRunElevated, will be performed with the rights of the application pool (SHAREPOINT\system). This account will have full access to the current web application, but should not have farm-level permissions to do things like modify SPFarm properties or make changes to the SSP.
  3. Using identity-aware objects (like SPSite and its children) across the execution boundaries of your CodeToRunElevated has the potential to cause some really funky behavior and race conditions. For all intents and purposes, consider this unsupported.

And as Alex said, children of an SPSite inherit their permissions from the SPSite, which in turn has its permissions set when it is created. So SPContext.Current.Site will still behave with the permissions of the current user even if you reference it within your CodeToRunElevated. Instead, you would need to create and consume a new SPSite within the elevated block.

To summarize: RWEP to impersonate the App Pool outside of SharePoint, SPSite impersonation to impersonate the App Pool inside of SharePoint.

dahlbyk
Excellent info, thanks Dahlbyk!
Chris Ballance
good answer. could you elaborate on why its useless in timer jobs etc?
Anders Rask
SharePoint web apps use impersonation to run code as the user that's signed in - RWEP just temporarily turns off that impersonation on a thread. If the code isn't running with impersonation to begin with, as in a timer job or console app, then the thread user and process user (RWEP's "elevated user") are the same.
dahlbyk