Allowing relative file imports

Daniel Keep daniel.keep.lists at gmail.com
Wed Mar 25 15:43:21 PDT 2009



Walter Bright wrote:
> Daniel Keep wrote:
>> It should be noted that this is really no different to executing
>> arbitrary code on a machine.  That said, compiling a program is not
>> typically thought of as "executing" code, so some restrictions in this
>> case would probably be prudent.
> 
> Here's the scenario I'm concerned about. Let's say you set up a website
> that instead of supporting javascript, supports D used as a scripting
> language. The site thus must run the D compiler on the source code. When
> it executes the resulting code, that execution presumably will run in a
> "sandbox" at a low privilege level.
> 
> But the compiler itself will be part of the server software, and may run
> at a higher privilege.

If you're thinking of something like ASP.NET for D, whereby the server
executes a D compiler, then I think this would be a serious design flaw
of the software; the D compiler itself should be executing with the
absolute minimum permissions necessary to function, and preferably in a
VM or a jail.

> The import feature could possible read any file
> in the system, inserting it into the executable being built. The running
> executable could then supply this information to the attacker, even
> though it is sandboxed.
> 
> This is why even using the import file feature must be explicitly
> enabled by a compiler switch, and which directories it can read must
> also be explicitly set with a compiler switch. Presumably, it's a lot
> easier for the server software to control the compiler switches than to
> parse the D code looking for obfuscated file imports.

Well, my proposal should -improve- security because currently it's
possible to read any file the compiler has access to simply by compiling
via a Makefile or any other build process.

If the code cannot set command-line switches, then there's no
difference, so let's ignore that case.  Let's assume the code CAN set
switches.  There's nothing to stop it doing this:

> dmd -J/etc evil.d && evil

> module evil;
> const PASSWD = cast(char[]) import("passwd");
> import std.stdio;
> void main()
> {
>     writefln("200 OK\nContent-Type: text/plain\n");
>     writef("%s", PASSWD);
> }

Hence why I proposed a whitelist in sc.ini itself.  This way, you can't
trick the compiler (either by controlling the command-line or by
tricking the user) into giving you the sensitive file directly.

By disallowing symlinks, you also remove the ability to "escape" a
directory tree.

Finally, the requirement for a ".dimport" or "_dimport" file or
something ensures that folders have to explicitly cleared for file
imports.  Combined with the whitelist and removal of symlinks, it should
be more or less impossible to get access to a file you shouldn't.

Perhaps it might be worthwhile to do a mock compiler (that just attempts
to read a provided filename using a -J switch) with these semantics and
see if it's possible to exploit it in any way...

  -- Daniel



More information about the Digitalmars-d mailing list