[IronPython] Re strict imports

Dino Viehland dinov at microsoft.com
Wed Sep 3 06:44:30 CEST 2008


I thought that one had gotten fixed but maybe it hasn't or maybe it changed while I'm on vacation - I was looking at beta 4 sources and removing the things I thought we had changed since then.  Either way it should be easy to fix but I'll have to talk to the DLR guys when I'm back from vacation on Thursday :)

From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Leo Carbajal
Sent: Tuesday, September 02, 2008 9:06 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Re strict imports

The PAL stuff looks scary! Ok, not really, but I'll have to look at it when I'm not close to falling asleep. The benefits here are pretty nice, but probably not something I want to muck with half-heartedly.

The stack trace for this one is as follows:
System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0<http://2.0.0.0>, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
   at System.Scripting.Com.ComMetaObject.IsComObject(Object obj)
   at System.Scripting.Actions.MetaAction.Bind[T](Object[] args)
   at System.Scripting.Actions.CallSite`1.CreateNewRule(Rule`1 originalMonomorphicRule, Object[] args)
   at System.Scripting.Actions.CallSite`1.UpdateAndExecute(Object[] args)
   at System.Scripting.Actions.UpdateDelegates.Update2[T,T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at <module>$1##1(Closure , Scope , LanguageContext )
   at System.Scripting.Runtime.OptimizedScriptCode.InvokeTarget(LambdaExpression code, Scope scope)
   at System.Scripting.SourceUnit.Execute(Scope scope, ErrorSink errorSink)
   at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)
   at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)
   at IronPythonShell.Program.Main(String[] args) in C:\Users\Leo\Documents\Visual Studio 2008\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 63
The action that failed was:
LinkDemand
The type of the first permission that failed was: System.Security.Permissions.SecurityPermission
The first permission that failed was:
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0<http://2.0.0.0>, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>

I'm running the exact same file you mentioned, with the exact same changes to the assembly. I'll paste it here, in case I'm missing something ridiculously obvious, since the contents of the Main method are now rather small:

            PermissionSet pset = new PermissionSet(PermissionState.None);
            pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
            pset.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
            pset.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, AppDomain.CurrentDomain.BaseDirectory));
            AppDomainSetup domainSetup = new AppDomainSetup();
            domainSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

            // create the sandboxed domain
            AppDomain sandbox = AppDomain.CreateDomain(
                "Sandboxed Domain",
                AppDomain.CurrentDomain.Evidence,
                domainSetup,
                pset,
                CreateStrongName(Assembly.GetExecutingAssembly()));


            StringBuilder script = new StringBuilder();
            script.AppendLine("i = 200");
            script.AppendLine("while i > 0:    i = i - 1");
            script.AppendLine("print \"Done in the second verse. Yes?\"");

            try
            {
                ScriptRuntime runtime = ScriptRuntime.Create(sandbox);
                ScriptEngine engine = runtime.GetEngineByFileExtension("py");
                ScriptScope scope = engine.CreateScope();

                ScriptSource source = engine.CreateScriptSourceFromString(script.ToString(), System.Scripting.SourceCodeKind.Statements);
                source.Execute(scope);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.ReadKey();

On Tue, Sep 2, 2008 at 9:49 PM, Dino Viehland <dinov at microsoft.com<mailto:dinov at microsoft.com>> wrote:

To allow access to the imports the next step in this will be providing your own PlatformAdapationLayer.  You'll need to subclass ScriptHost and specify that type as the HostType for a ScriptRuntimeSetup.  Your PAL can then provide access to a limited file system or a virtual file system from which the files are imported.  All of the IronPython import logic will then go through the PAL - you could check out the Silverlight PAL (BrowserPAL.cs) for an example.



For me the loop/print is working w/ just Execution permission.  I've just taken your original Program.cs, added APTCA, restricted the permissions to Execution, and removed full trust from the Ipy/DLR DLLs.  What's the stack trace of the exception here?



From: users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com> [mailto:users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com>] On Behalf Of Leo Carbajal
Sent: Tuesday, September 02, 2008 7:26 PM

To: Discussion of IronPython
Subject: Re: [IronPython] Re strict imports



Dino,

Thanks for the advice on Security Transparent. The IO permission seems necessary in order to load scripts from a file, as is the actual plan in the end - the example I attached not withstanding. Also, for some reason scripts fail unless I grant the UnmanagedCode flag, in addition to Execution. This is kind of problematic since UnmanagedCode allows me to do:

import clr
clr.AddReference("mscorlib.dll")
import System
from System import Environment
Environment.Exit(9)

Which I think is kinda bad. =\

Without UnmanagedCode imports don't work and even this won't work:

i = 200
while i > 0:
    i = i - 1
print "Done in the second verse. Yes?"

Print by itself works, though, and other functions such as Environment.CommandLine and such are correctly stopped unless called through a method I expose that asserts the appropriate permission set. Still, that Exit thing is rather crippling. Unfortunately the application I'm building will be run by the type of people that have too much time on their hands, I'm not sure how to plug that kind of hole without resorting to filtering each file for 'naughty' commands.

---
LC

On Tue, Sep 2, 2008 at 9:10 PM, Dino Viehland <dinov at microsoft.com<mailto:dinov at microsoft.com>> wrote:

To avoid the link demands you can mark your assembly as being SecurityTransparent - see http://blogs.msdn.com/shawnfa/archive/2005/08/31/458641.aspx.  That will force link demands from your assembly to turn into full demands which will fail when they hit the untrusted script code.  And full demands will of course also fail normally.



Also just a couple of other comments: You (probably) shouldn't be marking IronPython/IronPython.Modules/Microsoft.Scripting/Microsoft.Scripting.Core as full trust - we're also security critical so we don't need to be trusted at all.  You also probably don't want to be granting reflection or file-io - pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); should be sufficient for what you're doing so far.



Finally if you need to occasionally elevate permissions in your object model you can mark your assembly as SecurityCritical and then have individual methods which are audited and elevate appropriately.  But you also might just want to restrict the surface area by not having many public types other than the object model you're exposing.



From: users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com> [mailto:users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com>] On Behalf Of Leo Carbajal
Sent: Tuesday, September 02, 2008 6:33 PM

To: Discussion of IronPython
Subject: Re: [IronPython] Re strict imports



Ok, so I think I misunderstood what a LinkDemand was, as well as the fact that the exception I'm getting is expected behavior.


I added the [assembly: AllowPartiallyTrustedCallers] attribute to my assembly and now things work fine outside of the debug environment. From what I (now) understand, using the LinkDemand attribute is so that the partially trusted assembly (i.e. the scripts) can't access that method. Does that sound right to you guru types? To test this I imported System.Windows.Forms and tried to call the MessageBox.Show() method which failed while running in the domain, as expected. When I removed the LinkDemand from the ScriptableItem class the calls to it in the script also worked fine.

So all I have to do is decorate the classes I don't want to be imported from my assembly into the script with LinkDemands, I think? Is there some way to reverse that, I.E. some way that I can decorate the classes I want to be accessible rather than the other way around? I suppose another alternative is to create the ScriptableItem wrappers in their own assembly and just reference that, as well as make it callable by partially trusted callers, while leaving my own assembly alone and thus off-limits to an import.

I will play with it some more, I think. I'm sorry to have wasted some of your time. =\

---
LC

On Tue, Sep 2, 2008 at 7:38 PM, Leo Carbajal <desleo at gmail.com<mailto:desleo at gmail.com>> wrote:

This is a condensed version. You'll have to sign the assembly or you'll get an error at the domain creation step, other than that this should run just by starting a new console application, adding the IPY and DLR DLLs, and then copying and pasting this file over the default generated code.

Even after starting a new project to make sure my sample builds I still observe the same behavior.

---
LC



On Tue, Sep 2, 2008 at 6:36 PM, Curt Hagenlocher <curt at hagenlocher.org<mailto:curt at hagenlocher.org>> wrote:

Do you have a simple reproduction that doesn't include any of your domain-specific code?

On Tue, Sep 2, 2008 at 4:30 PM, Leo Carbajal <desleo at gmail.com<mailto:desleo at gmail.com>> wrote:

So here's a strange wrinkle,

when I run this with the debugger (unmodified except for adding the IronPython assemblies as full-trust on the domain) it works fine and as expected. If I run it without the debugger attached it gives me the same exception as before, when I catch the exception myself I also get this tidbit:

The assembly or AppDomain that failed was:
Microsoft.Scripting, Version=1.0.0.4000, Culture=neutral, PublicKeyToken=31bf3856ad364e35
The Zone of the assembly that failed was:
MyComputer
The Url of the assembly that failed was:
file:///B:/Code/IronPythonShell/IronPythonShell/bin/Debug/Microsoft.Scripting.DLL

If I build and compile the code as Release instead of Debug I get:

System.Runtime.Serialization.SerializationException: Type 'System.Scripting.SourceUnit' in assembly 'Microsoft.Scripting.Core, Version=1.0.0.4000, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not marked as serializable.

   at Microsoft.Scripting.Hosting.ScriptRuntime.ExecuteFile(String path)

   at IronPythonShell.Program.Main(String[] args) in B:\Code\IronPythonShell\IronPythonShell\Program.cs:line 54

It's a little beyond odd to me, but like I said before I fear I don't fully understand what's going on behind the goo. The only consolation is that I can at least built out my scripting system in working form and later run it under a more trusted domain for production by simply removing the domain from the Runtime.Create() constructor and then adding it later. (At least, I hope this is the case)

---
Leo C.



On Tue, Sep 2, 2008 at 4:50 PM, Shri Borde <Shri.Borde at microsoft.com<mailto:Shri.Borde at microsoft.com>> wrote:

The CLR doesn't dump out full exception information on SecurityExceptions in partial trust - you can get a lot more information if you look at the exception in a debugger, or if you Assert for FullTrust before doing a ToString on the permission.  Once you do that, you should be able to get more data including the demanded permission and the assembly which caused the demand to fail, instead of the message saying "The granted set of the failing assembly was:" which does not say which assembly is causing the problem.



Also, can you try adding IronPython.dll and IronPython.Modules.dll to the fullTrustAssemblies argument to AppDomain.CreateDomain<http://msdn.microsoft.com/en-us/library/ms130766.aspx>?



Thanks,

Shri







_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com





_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20080902/df5caff3/attachment.html>


More information about the Ironpython-users mailing list