Your SlideShare is downloading. ×
Writing Secure SharePoint Code - SharePoint Saturday Toronto
Upcoming SlideShare
Loading in...5

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Writing Secure SharePoint Code - SharePoint Saturday Toronto


Published on

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

No notes for slide
  • Thanks to DakshKhullar for suggesting improvements to this presentation
  • Where you do not have control, be aware
  • Responsible, Accountable, Consulted, Informed Sources:Improving Web Application Security, Threats and Countermeasures, Microsoft Press, p. lxxxiImproving .NET Application Performance and Scalability, Microsoft Developer Network,
  • When rating the threats, disregard whether or not special knowledge might be needed to discover the vulnerability. Assume that your attacker has full knowledge of the system. Describe MS10-070 (a zero day exploit of the application pool identity, allowing the attacker access to the web root including web.config and the SharePoint hive).
  • Ibid., pp. 13-43
  • Source: Ibid., p. 11
  • Click-jacking (a luring attack) is disabled in SharePoint 2013 by default. “Frame-breaking” Javascript code works equally well to prevent wrapping the page in an IFRAME. Note that Apps run in IFRAMES so you wouldn’t protect SP2013 Apps this way, only the SharePoint WFEs. Note that the “HTTP Only” cookie setting breaks out-of-box workflow as these use the InfoPath-style forms rather than WebForms. The error message is, “The form cannot be displayed because the use of session cookies has been disabled in the current browser settings. In order to load the form, session cookies must be allowed.”
  • Minimum required accounts: Reference: Account permissions and security settings in SharePoint 2013 WSS_ADMIN_WPG, WSS_WPG and other group permissions Registry, File System (including hosts)
  • Plan for App Authentication in SharePoint 2013
  • External Data Reference (BCS): account reference:
  • Authorization and authentication for apps in SharePoint 2013 presenting to Bermuda SharePoint User Group, Craig Lussier asked: “Where it would be best to store configuration if you are a vendor and want to release a web part to check for membership in a particular AD group before executing an operation (e.g. prior to creating a user in AD)?” While web.config is the easiest place to name your AD group, a better solution would be to create a Central Admin page that would let you configure the web part per site collection, and store the property in the Site Collection Root Web’s property bag. Then the web part could look the value up and if it existed, would execute; or if the propety did not exists, the WP would “know” it is not allowed to be executed in that context.
  • HP WebInspect is popular but results are mixed with SharePoint sites. MSR’s Gatekeeper project is a promising static analysis tool for JavaScript but no tools implementing its principles appear available:
  • Let’s start with an easy one
  • Based on the following post Martin Laplante (IceFire) suggested that this technique may have performance implications: However the alternative – try {} the operation and catch {} it if it fails – does not assert any security before executing the actual operation. Therefore it is a great technique for trapping exceptions before they reach the user or to display a friendly “Access Denied” message, but does not achieve the goal: to confirm that the user has an appropriate permission before running a view or update operation on a SharePoint object.
  • Anti-Cross Site Scripting Library Microsoft Anti-Cross Site Scripting Library v1.5: Protecting the Contoso Bookmark Page
  • Great posts on AllowUnsafeUpdates by Hristo Pavlov:
  • Source: WictorWilén,
  • Source: IshaiSagi,
  • Get the source to make this work from Dan Larsen: Or paste it from here! using System;using Microsoft.SharePoint; namespace LitwareSecurity{    /// <summary>A class for working with elevated privilege</summary>    public static class SpSecurityHelper    {        /// <summary>Returns an elevated site</summary>        /// <param name="theSite">        /// The site that you want an elevated instance of.         /// You must dispose of this object unless it is part of SPContext.Current.        /// </param>        /// <returns>An elevated site context.</returns>        /// <remarks>Be sure to dispose of objects created from this method.</remarks>        public static SPSite GetElevatedSite(SPSitetheSite)        {            varsysToken = GetSystemToken(theSite);            return new SPSite(theSite.ID, sysToken);        }         /// <summary>Gets a UserToken for the system account.</summary>        /// <param name="site"></param>         /// <returns>A usertoken for the system account user./returns>        /// <remarks>Use this token to impersonate the system account</remarks>        public static SPUserTokenGetSystemToken(SPSite site)        {            site.CatchAccessDeniedException = false;            try {                return site.SystemAccount.UserToken;            }            catch (UnauthorizedAccessException) {                SPUserTokensysToken = null;                 // Only use runwithelevated to grab the system user token.                SPSecurity.RunWithElevatedPrivileges(                    delegate()                    {                        using (SPSitelolcatKiller = new SPSite(site.ID)) {                            sysToken = lolcatKiller.SystemAccount.UserToken;                        }                    }                );                return sysToken;            }        }    }}
  • Source: SPC205, Ted Pattison (with changes: Cloud-hosted clarified as both Provider and Auto-hosted Apps)
  • Source: SPS030, Todd Baginski
  • Reference:App Permissions in SharePoint 2013 Elements (including out-of-box Base Type IDs)
  • Reference: Addressing same-origin policy limitations in apps for Office: Configuring SharePoint On-premise Deployment for Apps:
  • Transcript

    • 1. Eli Robillard is a seven-time Microsoft SharePoint MVP. He specializes in SharePoint architecture and building great teams to manage SharePoint as an enterprise service platform. As a thought leader and educator, Eli co-founded the ASPInsiders in 2003, launched the Toronto SharePoint User Group in 2006, launched the first free SP Saturday conference in 2007, was a co-author of Professional SharePoint 2007 Development and a technical editor of Professional Professional SharePoint 2010 Development (Wrox Press). Eli is engaged with PricewaterhouseCoopers to launch and ensure the operational success of a global internal SharePoint service. He is based in Toronto, Canada. E-mail Twitter @erobillard Blog
    • 2. Tweet about it! #spstoronto @erobillard
    • 4. Tasks Architecture Operations Development Testing Security Security Policies Responsible Informed Accountable Threat Modeling Accountable Informed Informed Responsible Security Design Principles Accountable Informed Informed Consulted Architecture and Design Responsible Informed Informed Code Development Accountable Responsible Technology-Specific Threats Accountable Responsible Code Review Responsible Informed Accountable Security Testing Consulted Informed Accountable Accountable Network Security Consulted Responsible Accountable Host Security Consulted Accountable Informed Responsible Application Security Consulted Informed Accountable Responsible Troubleshooting Consulted Accountable Informed Deployment Review Consulted Responsible Informed Informed Accountable
    • 5. Identify assets Create architectural overview Decompose the application Identify the threats Document the threats Rate the threats
    • 6. • Cross-site scripting, SQL InjectionInput validation • Cookie replay attacks, Network eavesdroppingAuthentication • Elevation of privilege, Data tampering, Luring attacksAuthorization • Over-privileged accounts, access to admin interfacesConfiguration management • Access to data at-rest, data tamperingSensitive data • Session hijacking, session replay, Man-in-the-middle attacksSession Management • Poor key managementCryptography • Form field, cookie, and query string manipulationParameter Manipulation • Errors reveal implementation, Denial-of-service attacksException Management • User denies accountability, Attackers cover their tracksAuditing and Logging
    • 7. • Contain attacksCompartmentalize • A breach should not lead to a greater breachUse least privilege • Use multiple gatekeepers, do not allow a single point of failureApply defense in depth • Assume all input is malicious until proven safeDo not trust user input • Authenticate and authorize as early in the process as possibleCheck at the gate • Do not provide details to help an attacker understand the mechanismFail securely • Is the network, host or application the weakest link?Secure the weakest link • Standards, open libraries, and automation all helpCreate secure defaults • If you don't use it, remove or disable itReduce the attack surface
    • 9. • Promiscuous headers • Identifiable UI Elements It is easy to identify SharePoint sites • Be aware, some need faster action than others • JavaScript injection is most common • IFRAME click-jacking is possible by default SharePoint is susceptible to known ASP.NET exploits • Files, pages, cookies and history can be cached on the user's system • Static assets in the SharePoint hive do not require authorization • Any web part in the GAC can be used on any site • Any application page in the hive is accessible from every application and site • Web and WCF services are visible for all sites SharePoint is susceptible to SharePoint exploits
    • 10. X-frame-options : sameorigin <httpCookies httpOnlyCookies="false" requireSSL="true" />
    • 11. vulnerability.aspx{72C1C8 5B-1D2D-4A4A-90DE-CA74A7808184}&pID=941 from-the-asp-net-vulnerability.aspx Walkthrough: MS 13-070
    • 12. WALKTHROUGH: MS 13-024
    • 13. Console / PowerShell •Member of Farm Administrators group •SharePoint Installer account Timer Jobs •Farm account SP Services •User impersonation •Application Pool Identity of the Service Application •Managed Account Client-side code •User impersonation Full Trust Code •User Impersonation •Application Pool Identity Custom CAS Policies •User Impersonation •Application Pool Identity Sandbox (Deprecated) •Application Pool Identity Apps •User-only Policy •User + App Policy •App-only Policy
    • 15. SPWeb web = site.OpenWeb(); // do stuff with web SPWeb web = site.OpenWeb(); // do stuff with web myWeb.Dispose(); using (SPWeb web = site.OpenWeb()) { // do stuff with web }
    • 16. if (HttpContext.Current == null) { // This isn’t being called in a web application }
    • 17. if (web.DoesUserHavePermissions(SPBasePermissions.ManageLists)) { // Backup list(s) to SkyDrive } us/library/microsoft.sharepoint.spbasepermissions.aspx
    • 18. /// AntiXss.HtmlEncode(myString) AntiXss.URLEncode(myString)
    • 19. // Is the ItemId parameter an Int32? if(!Int32.TryParse(Request.QueryString["ItemId"],out ItemId)) { // Exit with an invalid parameter error // Is the ListId parameter a GUID? RegexStringValidator val = new RegexStringValidator(@"^{?[dA-Fa- f]{8}-[dA-Fa-f]{4}-[dA-Fa-f]{4}-[dA-Fa-f]{4}-[dA-Fa- f]{12}}?$"); // If invalid, this will throw a System.ArgumentException val.Validate(Request.QueryString["ListId"]); Guid ListId = new Guid(Request.QueryString["ListId"]);
    • 20. LayoutsPageBase SPUtility.ValidateFormDigest() AllowUnsafeUpdates
    • 21. if (HttpContext.Current == null) { // parmAbsUrl is an absolute URL in the format "http://server/sites/mySite/" using (SPSite site = new SPSite(parmAbsoluteUrl)) { using (SPWeb web = site.OpenWeb(parmAbsoluteUrl)) { web.AllowUnsafeUpdates = true; // Update SharePoint objects here web.AllowUnsafeUpdates = false; } } } else // HttpContext.Current has a value { SPUtility.ValidateFormDigest(); // Update SharePoint objects here }
    • 22. [DllImport("advapi32.dll")] public static extern uint EventActivityIdControl( uint controlCode, ref Guid activityId); public const uint EVENT_ACTIVITY_CTRL_GET_ID = 1; // … // And then use it in code like this: try { // code block goes here } catch { Guid g = Guid.Empty; EventActivityIdControl(EVENT_ACTIVITY_CTRL_GET_ID, ref g); this.Controls.Add(new Label { Text = string.Format("An error occurred with Correlation ID {0}", g) }); }
    • 23. public string NumberArray { // Require format: 1,2,3,4 get{return _numberArray;} set{ string [] arr = value.split(','); foreach (string item in arr) { int i; if(!int.TryParse(item,out i)) throw new WebPartPageUserException("The item ""+item+"" is not a valid number"); } _numberArray=value; } }
    • 24. SPWeb web = SPContext.Current.Web; try { // Verify this is a postback from a valid Application Page SPUtility.ValidateFormDigest(); // Verify that the user has a valid permission before elevating if (web.DoesUserHavePermissions(SPBasePermissions.ManageWeb)) { SPSecurity.RunWithElevatedPrivileges(delegate() { // Read data using the SharePoint Object Model here }); } }
    • 25. // Update a SharePoint property using (SPSite elevatedSite = LitwareSecurity.SharePoint.Security.GetElevatedSite(web.Site) { // Update data using SharePoint object model here. } The secret sauce: GetElevatedSite first tries site.SystemAccount.UserToken. If that doesn’t work it falls back to RWEP() to GetSystemToken(). It then returns an elevated SPSite using this token. Get the source:
    • 26. // Call a non-SharePoint resource using (HostingEnvironment.Impersonate()) { // Call an external resource using the credentials of // the Application Pool ID here }
    • 28. App Web Remote Web
    • 29. All or nothing
    • 30. <?xml version="1.0" encoding="utf-8" ?> <App xmlns= ProductID="{4a07f3bd-803d-45f2-a710-b9e944c3396e} " Version="" SharePointMinVersion="" Name="MySampleApp"> <Properties> <Title>My Sample App</Title> <StartPage>http://ContosoApps/default.aspx/?SPHostUrl={HostUrl}</StartPage> <SupportedLocales> <SupportedLocale CultureName="en-US" /> </SupportedLocales> </Properties> <AppPermissionRequests> <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read"/> <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write"> <Property Name="BaseTemplateId" Value="101"/> </AppPermissionRequest> </AppPermissionRequests> <AppPrincipal> <RemoteWebApplication ClientId="1ee82b34-7c1b-471b-b27e-ff272accd564" /> </AppPrincipal> </App>
    • 31. Scope Pertains To Site Collection * A SharePoint Site Collection Web * A SharePoint Web Site List * A SharePoint list Search The SharePoint Search Service Workflow The Windows Azure Workflow Service Taxonomy The SharePoint Taxonomy Service BCS Read access to BCS service data sources
    • 32. App permission name SharePoint permission name Permissions Read Reader View Items, Open Items, View Versions, Create Alerts, Use Self-Service Site Creation, View Pages Write Contributor Read-Only permissions, plus: Add Items, Edit Items, Delete Items, Delete Versions, Browse Directories, Edit Personal User Information, Manage Personal Views, Add/Remove Personal Web Parts, Update Personal Web Parts Manage Designer Write permissions, plus: Manage Lists, Add and Customize Pages, Apply Themes and Borders, Apply Style Sheets FullControl Full Control All permissions.
    • 33. Policy Conditions User-only Policy Content database authorization checks succeed if the User has sufficient permissions to perform the action. App-only Policy Content database authorization checks succeed if the App has sufficient permissions, whether or not the current user (if there is a current user) has the same permissions. User and App Policy Content database authorization checks succeed only if both the current User and the App have sufficient permissions to perform the actions that the App is designed to perform. This is required to act on behalf of the user when the App is hosted in a Remote Web and not an App Web.
    • 34. oint-2013-resources-for-developers.aspx
    • 35. Join our local users groupsToronto SharePoint Users Group Toronto SharePoint Business Users Group
    • 36. Thanks to our sponsors!