Understanding Plugin sandbox mode

Plugins

Plugins in CRM are great ways to run powerful .NET code and our one of the CRM Developers most powerful tools in his toolbox.

There are lots of steps you need to go through when creating a plugin and there are lots of things which can error.

The knowledge you need is usually built up with a bit of theoretical knowledge and then a lot of practical trying.  The amount of knowledge you need to write a plugin is one of the reasons Why .NET developers struggle with CRM Development

If you are starting out writing plugins, I would recommend my youtube plugin playlist

I would recommend reading my blog post on common plugin errors, which you will certainly experience at some point CRM 2011/2013 – Common Plugin Errors and Isolation Mode

The common errors talks about the  post discusses a deployment common error you might experience, which is you cannot deploy plugins with isolation mode = none if you are not a deployment administrator.

If the isolation mode = “Sandbox” then any CRM Developer who has the security role of Administrator can deploy plugins into a sandboxed environment.

Where can you see the Isolation mode of a plugin

When you create a plugin you can choose two different types of isolation mode

  • Sandbox
  • None

You may have seen these when you are deploying plugins in the CRM Developer toolkit, it’s in the RegisterFile.crmregister file, you can see each assembly has

IsolationMode= “Sandbox”

You can also see what isolation mode of a plugin if you open the Plugin Registration Tool.

  1. open the Plugin Registration tool
  2. connect to CRM instance
  3. Right click on an Assembly and choose update
  4. Now see the Isolation mode

isolation mode

Confusion

When developers talk, naming and terms used can add confusion and slow down people’s understanding.

A plugin assembly has a setting called Isolation mode and this can be set to None or Sandboxed, but you will rarely hear any CRM developers use the term isolation mode.

Instead they will say things like these

  • A plugin is sandboxed
  • CRM online plugins must run in the sandbox
  • it’s a normal plugin

When a CRM Developer mention Sandbox/Sandboxed and plugin they mean the plugin has an isolation mode which equal “Sandbox”

CRM online plugins can only run with an isolation mode = sandboxed

A normal plugin is a plugin which has an isolation mode =  “none”

Often used but not really understood

CRM isolation mode is used all the time by all CRM developers who create plugins but often most CRM developers only have a vague idea of what Isolation mode means.

Most CRM Developers will have heard about Isolation mode with regards to CRM online.  The reason for this is CRM Plugins created for CRM Online organisations must have Isolation mode = “Sandboxed”

What is the Isolation mode?

The first (and best) place to start with understanding Isolation mode and Sandboxed plugins is with this great MSDN article which can be found in the CRM SDK (which should be the first place you look for documentation)

Plug-in isolation, trusts, and statistics

You will notice the isolation mode of a plugin is at the assembly level and not the individual plugin level.

This is why when you create a new plugin there is no setting for isolation mode because it’s at a DLL\project level and you can have many plugins inside one project (or inside one dll).

Isolation Environment

Plugins with an isolation level of “Sandbox” run in an isolated environment and as you can imagine this environment is more secure.  Key point

The sandbox is more secure and some actions are restricted

The restrictions are a bit of mystery, in the sense there is not one all encompassing list of code which will cause an error in a sandboxed plugin.  This can be very frustrating when you deploy a plugin in the sandbox and it throws an error, finding the cause of this can be difficult and frustrating.

The Plug-in isolation, trusts, and statistics article states

isolated environment, also known as a sandbox, a plug-in or custom activity can make use of the full power of the Microsoft Dynamics CRM SDK to access the organization web service. Access to the file system, system event log, certain network protocols, registry, and more is prevented in the sandbox.

The article gives a good description of what this means by saying Plugins deployed in the sandbox are partially trusted (e.g. you only partially trust the plugin and are limiting it’s powers) and plugins which are not in the sandboxed are fully trusted (by you the developer) and you are happy to let them interact with the file system, registry, call other dll’s and web services etc.

Sandboxed and non sandboxed plugins

I recently had some experience with sandboxed plugins because a project I was working on moved all the plugins out of the sandbox.  The first result was I couldn’t not update or publish any plugins because I wasn’t a Deployment admin

The second side effect is I remember the sandbox has its own service.  If you have ever installed CRM you notice there are Sandbox CRM Service and standard CRM Service.  Most CRM Developers know of the services when they do one of the many IISRESETS + Service restart, which usually happens if you have DLL’s in the GAC.  The sandbox service runs all the sandbox plugins.

The sandbox service runs all the sandbox plugins.

I was remote debugging, so instead of attaching the remote debugging to the

  • w3wp.exe – standard plugin
  • CRMASyncService.exe – if the plugin is asynchronous
  • Microsoft.Crm.Sandbox.WorkerProcess.exe – for sandbox plugins

One reason I personally don’t like remote debugging is if someone is debugging a standard plugin, then by debugging the w3wp they stop the whole server whilst and everyone else who is using it.  I have seen some scenarios where other developers and testers have had to stop whilst the one developer debugged his plugin (poor show).

To get around this you can change the plugin to sandboxed and then when you debug you only stop the sandbox service

Sandbox limitations

I have stated previously it’s difficult to know what the limitations are but here some of the limitations taken from the msdn article

  • Access to the file system (C Drive)
  • system event log
  • certain network protocols
  • registry
  • You cannot access any other DLL’s
  • IP addresses cannot be used
  •  Only the HTTP and HTTPS protocols are allowed.
  • In isolated mode you cannot call any external DLL’s\DLL’s in the GAC

This blog had some good restrictions in a bit more detail

  • Attempting to use the AppDomain.CurrentDomain.AssemblyResolve event
  • IO.Path.GetTempPath() [System.Security.Permissions.EnvironmentPermissionException]
  • Any filesystem access code [System.Security.Permissions.FileIOPermissionException]
  • Attempting to use the EventLog [System.Diagnostics.EventLogPermissionException]
  • Attempting to use IsolatedStorage [System.Security.Permissions.IsolatedStoragePermissionException]
  • Any references to Thread.CurrentThread caused a security failure.

Someone tweeted me a great article on security and sandboxed plugins

How to: Run Partially Trusted Code in a Sandbox

The article is fantastic but it does highlight the difficulty developers can experience using the CRM SDK, sometimes the information is there but it’s hard to find.

CRM Online limitations

I believe CRM online sandboxed plugins cannot use LINQ queries, which throws an error due to another transaction being created in the LINQ query.

Custom workflows cannot be used in the CRM online sandbox

Correction – You can call WCF webservices 

I originally put you couldn’t call webservices but I have been corrected thanks to a great comment from Andrii Butenko

To use webservices all you need is to use WebClient if possible like https://msdn.microsoft.com/en-us/library/gg509030.aspx

In case only WCF is available you can call it but you have to manually build binding https://mscrmmindfire.wordpress.com/2013/06/14/calling-external-web-service-from-a-crm-2011-plug-in/

CRM 2015 Online allows custom workflows

Another great comment has caused me to update this post.

Custom workflow activities can now be registered in isolation mode in CRM 2015 online

https://msdn.microsoft.com/en-us/library/gg334752.aspx

Example error

I came across an error which prompted me to write this blog post.  I was trying to serialize some fields and pass them between plugins using shared variables

This forum post below is the same error

https://social.microsoft.com/Forums/en-US/9ce3c4e6-0587-4913-89f8-f3942d7bac93/using-systemwebextensions-in-crm-plugin

Unhandled Exception:

System.MethodAccessException: Attempt by security transparent method ‘TestingSeam.CrmTesting.Execute(System.IServiceProvider)’ to access security critical method ‘System.Web.Script.Serialization.JavaScriptSerializer..ctor(

This error was unusual because it was complaining about access to a critical method.  I wondered why serialization was critical method but thinking about it, serialization must involve writing the data to disk and sandboxed plugins are not allowed to do this.

A Gotcha also occurred when someone changed the plugin to sandbox mode, it stopped the plugin working, so I had to leave a comment in the code to say, this plugin won’t work if the plugin is sandboxed.

Why put plugins in the sandbox

So the question is why would people choose to put plugins in the sandbox.

The most common reason is they are using CRM online and you have no choice because all plugins have to be

Runtime statistics are created  PluginTypeStatistic entity records. These records are populated within 30 minutes to one hour after the sandboxed custom code executes

https://msdn.microsoft.com/en-us/library/gg334752.aspx

This url has an interesting benefit

  1. If the sandbox worker process that hosts this custom code exceeds threshold CPU, memory, or handle limits or is otherwise unresponsive, that process will be killed by the platform. At that point any currently executing plug-in or custom workflow activity in that worker process will fail with exceptions. However, the next time that the plug-in or custom workflow activity is executed it will run normally. There is one worker process per organization so failures in one organization will not affect another organization.

Why haven’t you listed all errors

Some readers maybe dissapointed I haven’t listed all the methods and exact lines of code which will cause sandbox plugins to throw security errors.

Whilst writing this blog post I realised the reason Microsoft have listed all the causes of security errors in sandboxed plugins because there are potentially lots of them and if they tried to list them all, they would miss some. In fact I would say it’s impossible to list them all, so there is no benefit to trying.

The way to think about the sandbox is it’s a bit like a sandpit and the code is a child.  As soon as any code/child tries to get out of the sandpit we throw an error and a parent comes along, tells the child off and throws them back in the sandpit.

This is why sandboxed code is safer because it can’t get onto your server and cause havoc.

Summary

The limitations of sandboxed plugins can be a significant influencing factor for many CRM solutions to be on premise.

The limitation of not being able to call webservices and DLL’s in the GAC can be quite restrictive.

There is a solution using ILMERGE, which is a method of merging a number of different DLL’s into one DLL, which will allow you to use the plugin in a sandboxed environment.  I would be cautious about this approach because if you ask anyone who has done it, they will tell you it wasn’t easy and debugging a merged DLL can be impossible.

Here is a good article on ILMerge issues

26 thoughts on “Understanding Plugin sandbox mode

  1. a33iki February 6, 2015 / 7:41 am

    Hello,

    Good article but partially not correct:

    >>You cannot call any webservices from within a sandboxed plugin
    That’s absolutely not correct. To use webservices all you need is to use WebClient if possible like https://msdn.microsoft.com/en-us/library/gg509030.aspx
    In case only WCF is available you can call it but you have to manually build binding – https://mscrmmindfire.wordpress.com/2013/06/14/calling-external-web-service-from-a-crm-2011-plug-in/

    Liked by 1 person

    • Hosk February 6, 2015 / 10:54 am

      Thanks for the comment and the great links. I have updated the blog

      Like

    • Hosk February 6, 2015 / 12:15 pm

      Awesome, great comment

      I have had two great comments to this blog, where I have learnt some very interesting details about sandboxed plugins.

      They snuck that change into CRM 2015

      Like

  2. Mandar Joshi February 28, 2015 / 11:23 am

    Reblogged this on CRM Backlog and commented:
    Isolation was subject were i had lot of confusion, but with the simple explanation provided by Hosk’s blog, many things are clear now. Thanks Hosk for the article!

    Like

  3. Jeff Ballard March 23, 2015 / 6:13 pm

    Great article. A comment I hope will help.

    Regarding the serialization: you can use the System.Runtime.Serialization classes. I successfully used the DataContractJsonSerializer. One thing about that, though: you *must* make the types you’re serializing public. Typically, you can make them private *if* you decorate them with the [DataContract] and [DataMember] attributes, but that doesn’t work in partial trust. You’ll get an error similar to “The data contract type ‘NewCo.Plugins.CrmToSharePoint.Utility.SharePointResponse’ is not serializable in partial trust because it is not public.

    So you can do some serialization – at least from the System.Runtime.Serialization namespace.

    Like

    • Hosk March 23, 2015 / 6:54 pm

      Thanks for the comment Jeff.

      The logic would certainly make sense and I didn’t try adding a A data contract attributes.

      Very Interesting

      Like

  4. Jeff Ballard March 23, 2015 / 7:22 pm

    Meant to add one other thing. I am using Linq queries in CRM online in a plugin. It’s not in the plugin code directly, I have a static method in another class that creates a CRM context and runs a query.

    public static new_sheet GetSheet(Guid sheetId, IOrganizationService service)
    {
    using (var ctx = new CrmContext(service))
    {
    return (from c in ctx.new_sheetSet
    where c.Id == sheetId
    select c).SingleOrDefault();
    }
    }

    It works just fine. I much prefer early bound types even though it takes a little more effort to set up. (I do filter crmsvcutil to create just the types needed in the plugin to avoid bloat.)

    Like

  5. Guillermo Estevez January 21, 2017 / 2:21 am

    Hi Hosk,

    i hope you dont mind i linked this post in mine (https://www.linkedin.com/pulse/sandbox-vs-isolation-plugins-guillermo-est%C3%A9vez?trk=pulse_spock-articles)

    i found an issue while dealing with X509 Certificates and i make the mistake of registering them in Sandbox mode when i shouldnt.

    I think we all should be aware that X509 Certificates are stored in the file system, and therefore they can not be access when in Sandbox mode.

    Like

  6. Kjeld Poulsen February 18, 2018 / 9:42 am

    CRM Online Sandbox plugins can use Linq queries, and the request is participating in the current transaction.

    I am using it all the time.

    But thanks for walk through.

    Like

    • Hosk February 18, 2018 / 10:27 am

      When the article was written, you couldn’t use linq queries. Thanks for the comment, it will help people reading it now

      Like

  7. Nour April 25, 2018 / 7:29 pm

    You can write LINQ queries in sandboxed plugin .

    Like

Leave a reply to Hosk Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.