Allowing relative file imports

Daniel Keep daniel.keep.lists at gmail.com
Wed Mar 25 05:28:04 PDT 2009


There seem to have been a few tickets thus far from people wanting to do
relative file imports using the -J switch.  Walter has stated that this
is explicitly disallowed as a defensive measure, which is fine.

I was going to post the following as an enhancement request, but I
thought it might be better if it was discussed first.

TLDR: relative paths should be safe if we disallow symlinks, disallow -J
to be used except for a small whitelist and require a specially-named
file to be present in any imported directory.

Disclaimer: I'm not a security guru.

  -- Daniel

There have been at least two reports thus far (2103 and 2759) of people
attempting to use relative imports with the -J compile-time file import
feature.

It has been stated that this is explicitly disabled due to security
concerns.

I suggest that adding relative paths (provided paths cannot escape the
base directory) is not less secure; it should already be possible to
read an arbitrary file using the feature.

Let us assume relative paths are allowed, and that the path is
"collapsed" to remove all parent (..) references, and clipped to the
base directory.  The only way to "escape" this directory is for one of
three things to happen:

1. there is a symlink to a parent directory in the import path,
2. there is a device of interest mounted in the import path or
3. the user was tricked into specifying a higher directory in the first
place.

Clearly, #3 is already a problem: one could always specify -J/etc in a
Makefile to read any system configuration file that the user has access
to.  #2 is only a problem if the compiling user is an administrator and
tremendously stupid, which is not so much an issue with DMD but with the
user.  #1 is something which could also be done in a Makefile.

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.

Therefore, I believe the following should be sufficient to ensure
relative paths are safe to include:

1. Ensure that symlinks are NOT followed.  This also applies under
Windows for junctions and symlinks (I believe it should be enough to use
GetFileAttributesEx on each path component and reject it if it has the
FILE_ATTRIBUTE_REPARSE_POINT attribute, although I cannot verify this
with XP; see
http://blogs.msdn.com/oldnewthing/archive/2004/12/27/332704.aspx).

2. Disallow -J to be the root of any drive or filesystem, and only allow
-J to be used from the following roots: %USERPROFILE% for Windows and ~
for *nix.  Possibly, this should be configured or overridable in sc.ini;
an extendible whitelist would be good.

3. Require that any directory you attempt to read from using file
imports MUST have either a "_import" or ".import" file (or whatever name
seems appropriate) present in it.

The first should prevent symlinks from being a potential attack vector,
the second should prevent most casual malicious behaviour, and the third
will ensure that the user not only have read access but WRITE access as
well (or whoever owns the directory explicitly allowed for D file imports.)

This should hopefully be sufficient to allow for relative imports.



More information about the Digitalmars-d mailing list