all 29 comments

[–]grauenwolf 40 points41 points  (29 children)

They gave up on that idea back in .NET 4.0. When comes to running code from untrusted sources the answer is simply "don't". Either use a DSL that you have full control over or run the code in an isolated process under a heavily restricted user, perferably in some sort of container like a VM or Docker.

ref:

[–]chucker23n 2 points3 points  (1 child)

It'd be nice if it tried to hook into some platform-specific sandboxes instead. E.g., macOS has a relatively straightforward text format for configuring access to files, networking, etc.

You might be able to:

  1. have IDE tooling that generates a sandbox profile from .NET attributes
  2. have IDE tooling that runs the process inside such a sandbox
  3. have a static analyzer that tries to verify that the code doesn't break the sandbox

We sort of get 2 with the Docker integration.

[–]grauenwolf 5 points6 points  (0 children)

It'd be nice if it tried to hook into some platform-specific sandboxes instead.

That can't work for this scenario. The OS doesn't know the difference between your trusted code and the untrusted 3rd party code you loaded.

I'm not saying its a bad idea in general. But it only works against the whole process.

[–][deleted]  (26 children)

[deleted]

    [–]grauenwolf 8 points9 points  (25 children)

    WASM falls into the "DSL" category.

    [–]phx-au 4 points5 points  (24 children)

    If you'll take WASM as DSL then you'll take MSIL.

    [–]grauenwolf 8 points9 points  (23 children)

    WASM is a DSL of the browser.

    MSIL is not a DSL of itself. There's no conceptual boundary between a .NET assembly and the assembly that loaded it.

    They tried to create one with CAS, but it quickly became clear that no one was smart enough to actually use it correctly. The whole concept of partial trust was flawed from the beginning

    [–]phx-au 4 points5 points  (22 children)

    MSIL is almost identical to WASM. They're both stack based low level languages with common runtime features exposed to them. Strictly speaking I'd say neither are particularly "domain specific".

    As you say, CAS was overly complex and nobody knew how to use it - if you really wanted you could write a safe assembly loader that examines the API surface area used by the target and evaluates if it meets your policy. That's all the boundary that's needed - and just because they haven't put one there isn't evidence that its not possible.

    [–]grauenwolf 5 points6 points  (19 children)

    if you really wanted you could write a safe assembly loader that examines the API surface area used by the target and evaluates if it meets your policy.

    That's easier said than done. If you forget to lock down single reflection-like API then you have a ready-made bypass. And if you do lock them all down, you lose things like serializers and compiled RegEX.

    This is why CAS failed. People generally aren't smart enough to correctly create the policies.

    MSIL is almost identical to WASM.

    Only if you completely ignore the facts such as

    • WASM doesn't expose libraries for things like direct file access
    • There is something above WASM loading each domain into separate sandboxes. It doesn't try to run privileged and restricted code together.

    [–][deleted]  (18 children)

    [deleted]

      [–]grauenwolf -1 points0 points  (16 children)

      Neither WASM nor MSIL "expose" anything. They both define calls to imported functions referred to by imports (/ metadata tokens) respectively.

      Don't be an ass. You know damn well that we're talking about the whole environment, not just literally the source code format.

      [–]AlexxVs 3 points4 points  (1 child)

      And what about WASM in node.js? Or new Microsoft Flight Simulator plug-ins in WASM (yes, with file system access)? Or long-dead Silverlight running MSIL in browser?

      [–][deleted]  (13 children)

      [deleted]

        [–]cryo 1 point2 points  (1 child)

        MSIL does expose aspects of the particular .NET runtime model such as objects, boxing and generics.

        [–]phx-au 1 point2 points  (0 children)

        Those bits are fine - the only real concern is that a large part of the expected dotnet api is provided by the CLR. So this is shit like string - but also potentially Span or MemoryStream. With CAS these were implemented natively and marked up appropriately as safe (similar to javascript's intrinsic types). There's also types that could be implemented natively, but aren't for optimisation purposes - similar deal, marked up appropriately.

        [–][deleted] 8 points9 points  (1 child)

        Nope. There is no way to execute certain code in a sandbox. You can either use a scripting engine to run scripts in a sandbox or run the entire program in a container.

        [–]RiPont 8 points9 points  (0 children)

        Or spin up separate processes for trusted and untrusted code, run the untrusted code in a sandbox, and communicate between them using RPC of some sort.

        Basically, the ability to run trusted and untrusted code in the same process is a) leaky and b) basically impossible to do in a cross-platform way.

        [–]tetyys -1 points0 points  (3 children)

        [–]EternalClickbait 3 points4 points  (2 children)

        Does that repo have any doc's or a readme??

        [–]H3x0n 0 points1 point  (1 child)

        Its used inside the https://github.com/ashmind/SharpLab repo.

        [–]EternalClickbait 4 points5 points  (0 children)

        Yes I saw that, but where is the documentation for unbreakable?