Sharepoint, WSS and MOSS application development and security testing
22 Apr 2008
Here's a few things to lookout for when auditing or security testing a Sharepoint/WSS/MOSS application, or when building one. But first: a new Microsoft MVP article on the subject just came out:
Security and Application Development in SharePoint: First Steps
And some other documents from Microsoft do exist:
Best Practices: Common Coding Issues When Using the SharePoint Object Model
Best Practices: Using Disposable Windows SharePoint Services Objects
Office SharePoint Server Security
Windows SharePoint Services Security
However I haven't been able to find much documentation on the following things, which you should be aware of if auditing, security testing, or deploying a Sharepoint,WSS,MOSS application:
1. Watchout for
As the name suggests, we should watch for the use of this method. In normal requests, SharePoint will execute code under the identity of the calling user. But when this method is leveraged, SharePoint will execute object model code with elevated permissions as the app pool account identity, which normally has full rights to the site collections it hosts.
2.
SPListItem sanitizes user input to mitigate XSS attacks. However, documents in the document library (doclib) are not afforded this protection. It is possible for contributors to upload malicious content into the doclib. Meaning, you can upload html files to a doclib and they'll be loaded as any hosted html file in that domain. So if you have uploaded a file called 'myfile.html' and you navigate to:
http://mysharepoint/Shared%20Documents/myfile.html
Then myfile.html loads in the browser as any other html file would in that domain (as Content-Type: text/html). There might be a setting to mitigate this by forcing a Content-Disposition: attachment header (a download dialog prompt) but I'm not sure. Someone with more Sharepoint knowledge would know. Otherwise you could customize the code yourself to force this.
3. Leverage
This can be considered on par with ASP.NET's ViewStateUserKey. To protect against cross-site request forgery, be sure your custom built aspx pages call SPUtility.ValidateFormDigest(). Sharepoint pages includes a hidden token in the postback which is unique to the user and the request. ValidateFormRequest() can be called in your custom aspx pages directly, or if you inherit from the WSS master page, to ensure you're leveraging this same protection.
4. Calling
Be sure to close objects before loosing references to them, otherwise you'll wind up with memory leaks fast. The two 'Best Practices' docs I've listed above will give more details.
5. Don't enable AllowUnsafeUpdates
When set to true the AllowUnsafeUpdates value tells Sharepoint to allow actions and data from GET requests to modify the database. By not allowing GET requests to modify data (this is the default), you've effectively protected against CSRF attacks which exploit GET requests. This is supplementary to ValidateFormRequest() above which only works with POST requests.
Update: July 2008 - updated with #5 above and found this interesting blog post on the subject from Hristo Pavlov’s Blog.
Security and Application Development in SharePoint: First Steps
And some other documents from Microsoft do exist:
Best Practices: Common Coding Issues When Using the SharePoint Object Model
Best Practices: Using Disposable Windows SharePoint Services Objects
Office SharePoint Server Security
Windows SharePoint Services Security
However I haven't been able to find much documentation on the following things, which you should be aware of if auditing, security testing, or deploying a Sharepoint,WSS,MOSS application:
1. Watchout for
SPSecurity.RunWithElevatedPermissions()
As the name suggests, we should watch for the use of this method. In normal requests, SharePoint will execute code under the identity of the calling user. But when this method is leveraged, SharePoint will execute object model code with elevated permissions as the app pool account identity, which normally has full rights to the site collections it hosts.
2.
SPListItem
versus doclibSPListItem sanitizes user input to mitigate XSS attacks. However, documents in the document library (doclib) are not afforded this protection. It is possible for contributors to upload malicious content into the doclib. Meaning, you can upload html files to a doclib and they'll be loaded as any hosted html file in that domain. So if you have uploaded a file called 'myfile.html' and you navigate to:
http://mysharepoint/Shared%20Documents/myfile.html
Then myfile.html loads in the browser as any other html file would in that domain (as Content-Type: text/html). There might be a setting to mitigate this by forcing a Content-Disposition: attachment header (a download dialog prompt) but I'm not sure. Someone with more Sharepoint knowledge would know. Otherwise you could customize the code yourself to force this.
3. Leverage
SPUtility.ValidateFormDigest()
for CSRF mitigationThis can be considered on par with ASP.NET's ViewStateUserKey. To protect against cross-site request forgery, be sure your custom built aspx pages call SPUtility.ValidateFormDigest(). Sharepoint pages includes a hidden token in the postback which is unique to the user and the request. ValidateFormRequest() can be called in your custom aspx pages directly, or if you inherit from the WSS master page, to ensure you're leveraging this same protection.
4. Calling
.Close()
on SPWeb and SPSite objectsBe sure to close objects before loosing references to them, otherwise you'll wind up with memory leaks fast. The two 'Best Practices' docs I've listed above will give more details.
5. Don't enable AllowUnsafeUpdates
When set to true the AllowUnsafeUpdates value tells Sharepoint to allow actions and data from GET requests to modify the database. By not allowing GET requests to modify data (this is the default), you've effectively protected against CSRF attacks which exploit GET requests. This is supplementary to ValidateFormRequest() above which only works with POST requests.
Update: July 2008 - updated with #5 above and found this interesting blog post on the subject from Hristo Pavlov’s Blog.