Restrict FileSystemObject to it's virtual dir
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Web Servers reviews > IIS server support > IIS Server Security > Restrict FileSystemObject to it's virtual dir




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    Restrict FileSystemObject to it's virtual dir  
Dallo


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-06-04 12:50 PM

Hi everybody,
i've to configure on a single win2003 machine a lot dinamic web site.
I'd like to protect each site from interference of other sites scripts that
uses, for example, filesystemobject method.
In other words, i dont want asp script using FSO of a site can access,
modify or delete files on other sites.
Is there a way to restrict FSO to it's virtual directory?


tnx to everyone








[ Post a follow-up to this message ]



    Re: Restrict FileSystemObject to it's virtual dir  
Tom Kaminski [MVP]


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-06-04 12:50 PM

"Dallo" <dallo.s@libero.it> wrote in message
news:cevhq9$pg6$1@carabinieri.cs.interbusiness.it...
> Hi everybody,
> i've to configure on a single win2003 machine a lot dinamic web site.
> I'd like to protect each site from interference of other sites scripts
that
> uses, for example, filesystemobject method.
> In other words, i dont want asp script using FSO of a site can access,
> modify or delete files on other sites.
> Is there a way to restrict FSO to it's virtual directory?

Make sure each site uses a different IUSR account.

--
Tom Kaminski IIS MVP
http://www.microsoft.com/windowsser...ty/centers/iis/
http://mvp.support.microsoft.com/
http://www.iisfaq.com/
http://www.iistoolshed.com/ - tools, scripts, and utilities for running IIS
http://www.tryiis.com







[ Post a follow-up to this message ]



    Re: Restrict FileSystemObject to it's virtual dir  
Adam Hammouda


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-18-04 10:57 PM

A long while back, I wrote this piece of code you may find useful;
It was supposed to provide a custom "FileSystemObject" implementation which
would not allow users to break out of their root directory in a web hosting
environment.
It's been so long I can't really recall how I did things exactly, but if I
had to guess:
-Disable native FileSystemObject support [through the registry, I think?
]
-Then register the .NET assembly with IIS through the command line ["reg
asm
/tlb /codebase [assemblypath]" maybe ?]

I had imported the ASPTypeLibrary and Scripting dll's, which must be
referenced when compiling the project.
I also believe the entire FileSystemObject API is implemented below in the
encapsulating classes.
your users would then instantiate the "FileSystemObject" with a:
Server.CreateObject("Custom.FileSystemObject") instead of
...("Scripting.FileSystemObject")

If you find it helpful, do with it what you please 

using System;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;

using ASPTypeLibrary; // COM Interoped ASP       Classes.
using Scripting;      // COM Interoped Scripting Classes.

namespace Custom {
/**
* FileSystemObject - File Implementation.
*/
public sealed class File : Scripting.File {
internal FileSystemObject fso;
internal Scripting.File   file;

public File(FileSystemObject fso, Scripting.File file) {
this.fso  = fso;
this.file = file;
}

public FileAttribute Attributes {
get {
return file.Attributes;
} set {
file.Attributes = value;
}
}

public DateTime DateCreated {
get {
return file.DateCreated;
}
}

public DateTime DateLastAccessed {
get {
return file.DateLastAccessed;
}
}

public DateTime DateLastModified {
get {
return file.DateLastModified;
}
}

public Drive Drive {
get {
throw new NotSupportedException();
}
}

public string Name {
get {
return file.Name;
} set {
file.Name = value;
}
}

public Scripting.Folder ParentFolder {
get {
return new Folder(fso, file.ParentFolder);
}
}

public string Path {
get {
return file.Path;
}
}

public string ShortName {
get {
return file.ShortName;
}
}

public string ShortPath {
get {
return file.ShortPath;
}
}

public object Size {
get {
return file.Size;
}
}

public string Type {
get {
return file.Type;
}
}

/* Added for backwards compatibility. */
public void Copy(string destination) {
fso.CopyFile(Path, destination);
}

public void Copy(string destination, bool overwrite) {
fso.CopyFile(Path, destination, overwrite);
}

/* Added for backwards compatibility. */
public void Delete() {
fso.DeleteFile(Path);
}

public void Delete(bool force) {
fso.DeleteFile(Path, force);
}

public void Move(string destination) {
fso.MoveFile(Path, destination);
}

/* Added for backwards compatibility. */
public TextStream OpenAsTextStream() {
return fso.OpenTextFile(Path);
}

/* Added for backwards compatibility. */
public TextStream OpenAsTextStream(short mode) {
return fso.OpenTextFile(Path, mode);
}

/* Added for backwards compatibility. */
public TextStream OpenAsTextStream(short mode, short format) {
return fso.OpenTextFile(Path, mode, false, format);
}

public TextStream OpenAsTextStream(IOMode mode, Tristate format) {
return fso.OpenTextFile(Path, mode, false, format);
}
}

/**
* FileSystemObject - Files Implementation.
*/
public sealed class Files : Scripting.Files {
internal FileSystemObject  fso;
internal Scripting.Files   files;

public Files(FileSystemObject fso, Scripting.Files files) {
this.fso   = fso;
this.files = files;
}

public int Count {
get {
return files.Count;
}
}

public IEnumerator GetEnumerator() {
return files.GetEnumerator();
}

public Scripting.File this[object id] {
get {
return new File(fso, files[id]);
}
}
}

/**
* FileSystemObject - Folder Implementation.
*/
public sealed class Folder : Scripting.Folder {
internal FileSystemObject fso;
internal Scripting.Folder dir;

public Folder(FileSystemObject fso, Scripting.Folder dir) {
this.fso = fso;
this.dir = dir;
}

public FileAttribute Attributes {
get {
return dir.Attributes;
} set {
dir.Attributes = value;
}
}

public DateTime DateCreated {
get {
return dir.DateCreated;
}
}

public DateTime DateLastAccessed {
get {
return dir.DateLastAccessed;
}
}

public DateTime DateLastModified {
get {
return dir.DateLastModified;
}
}

public Drive Drive {
get {
throw new NotSupportedException();
}
}

public Scripting.Files Files {
get {
return new Files(fso, dir.Files);
}
}

public bool IsRootFolder {
get {
return dir.IsRootFolder;
}
}

public string Name {
get {
return dir.Name;
} set {
dir.Name = value;
}
}

public Scripting.Folder ParentFolder {
get {
Folder folder = null;
try {
DirectoryInfo parent = new DirectoryInfo(Path);
parent = new
DirectoryInfo(fso.GetDirectoryPath(parent.Parent.FullName, true));
folder = new Folder(fso, dir.ParentFolder);
} catch {
folder = null;
}

return folder;
}
}

public string Path {
get {
return dir.Path;
}
}

public string ShortName {
get {
return dir.ShortName;
}
}

public string ShortPath {
get {
return dir.ShortPath;
}
}

public object Size {
get {
return dir.Size;
}
}

public Scripting.Folders SubFolders {
get {
return new Folders(fso, dir.SubFolders);
}
}

public string Type {
get {
return dir.Type;
}
}

/* Added for backwards compatibility. */
public void Copy(string destination) {
fso.CopyFolder(Path, destination);
}

public void Copy(string destination, bool overwrite) {
fso.CopyFolder(Path, destination, overwrite);
}

/* Added for backwards compatibility. */
public void Delete() {
fso.DeleteFolder(Path);
}

public void Delete(bool force) {
fso.DeleteFolder(Path, force);
}

public void Move(string destination) {
fso.MoveFolder(Path, destination);
}

/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename) {
return fso.CreateTextFile(System.IO.Path.Combine(Path, filename));
}

/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename, bool overwrite) {
return fso.CreateTextFile(System.IO.Path.Combine(Path, filename),
overwrite);
}

public TextStream CreateTextFile(string filename, bool overwrite, bool
unicode) {
//FileInfo file = new FileInfo(fso.GetFilePath(filename));
//return dir.CreateTextFile(file.FullName, overwrite, unicode);
return fso.CreateTextFile(System.IO.Path.Combine(Path, filename),
overwrite, unicode);
}
}

/**
* FileSystemObject - Folders Implementation.
*/
public sealed class Folders : Scripting.Folders {
internal FileSystemObject  fso;
internal Scripting.Folders folders;

public Folders(FileSystemObject fso, Scripting.Folders folders) {
this.fso     = fso;
this.folders = folders;
}

public Scripting.Folder Add(string filename) {
throw new NotSupportedException();
}

public int Count {
get {
return folders.Count;
}
}

public IEnumerator GetEnumerator() {
return folders.GetEnumerator();
}

public Scripting.Folder this[object id] {
get {
return new Folder(fso, folders[id]);
}
}
}

/**
* FileSystemObject - FileSystemObject Implementation.
*/
public sealed class FileSystemObject : Scripting.FileSystemObject {
private Scripting.FileSystemObject FSO;
private ScriptingContext           Context;
private Request                    Request;
private Server                     Server;
private DirectoryInfo              RootDirectory;

public FileSystemObject() : base() {
Request = null;
Context = null;
Server  = null;

RootDirectory = null;
// Initialize internal Scripting.FileSystemObject.
FSO = new Scripting.FileSystemObject();
}

/**
* Entrypoint function called by IIS with the current ScriptingContext.
*/
public void onStartPage(ScriptingContext Context) {
try {
this.Context = Context;
if(Context == null) {
throw new ArgumentNullException("Context");
}

this.Request = Context.Request; //
(RequestClass)Marshal.CreateWrapperOfType(Request, typeof(RequestClass));
if(Request == null) {
throw new ArgumentNullException("Request");
}

this.Server  = Context.Server;
if(Server == null) {
throw new ArgumentNullException("Server");
}

string path = String.Empty;
IStringList list = (IStringList)Request.ServerVariables["URL"];
if(list != null && list.Count == 1) {
path = list[1].ToString(); // Reminder: VB/ASP Arrays are not
zero-based.
} else {
throw new ArgumentNullException("List");
}

if(path == null || path.Length == 0) {
throw new ArgumentNullException("Path");
}

while(path.StartsWith("/")) {
path = path.Substring(1, path.Length - 1);
}

if(path.IndexOf("/") <= 0) {
throw new Exception();
}

path = "/" + path.Substring(0, path.IndexOf("/")) + "/";

RootDirectory = new DirectoryInfo(Server.MapPath(path));
if(RootDirectory == null || !(RootDirectory.Exists)) {
throw new ArgumentNullException("RootDirectory");
}
} catch {
throw new Exception("Unable to initialize Custom.FileSystemObject");
}
}

public Drives Drives {
get {
throw new NotSupportedException();
}
}

public string BuildPath(string path1, string path2) {
return FSO.BuildPath(path1, path2);
}

/* Added for backwards compatibility. */
public void CopyFile(string source, string destination) {
CopyFile(source, destination, true);
}

public void CopyFile(string source, string destination, bool overwrite)
{
CheckInitialized();
FileInfo srcFile = new FileInfo(GetFilePath(source, true));
srcFile.CopyTo(destination, overwrite);
}

/* Added for backwards compatibility. */
public void CopyFolder(string source, string destination) {
CopyFolder(source, destination, true);
}

public void CopyFolder(string source, string destination, bool
overwrite) {
CheckInitialized();
DirectoryInfo srcDir = new DirectoryInfo(GetDirectoryPath(source,
true));
InternalDirectoryCopy(srcDir, GetDirectoryPath(destination),
overwrite);
}

public Scripting.Folder CreateFolder(string filename) {
CheckInitialized();
DirectoryInfo dir = new  DirectoryInfo(GetDirectoryPath(filename)
);
return new Folder(this, FSO.CreateFolder(dir.FullName));
}

/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename) {
return CreateTextFile(filename, false);
}

/* Added for backwards compatibility. */
public TextStream CreateTextFile(string filename, bool overwrite) {
return CreateTextFile(filename, overwrite, false);
}

public TextStream CreateTextFile(string filename, bool overwrite, bool
unicode) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename));
return FSO.CreateTextFile(file.FullName, overwrite, unicode);
}

/* Added for backwards compatibility. */
public void DeleteFile(string filename) {
DeleteFile(filename, true);
}

public void DeleteFile(string filename, bool force) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename, true));
file.Delete();
}

/* Added for backwards compatibility. */
public void DeleteFolder(string filename) {
DeleteFolder(filename, true);
}

public void DeleteFolder(string filename, bool force) {
CheckInitialized();
DirectoryInfo dir = new  DirectoryInfo(GetDirectoryPath(filename,

true));
dir.Delete(true);
}

public bool DriveExists(string path) {
throw new NotSupportedException();
}

public bool FileExists(string filename) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename));
return file.Exists;
}

public bool FolderExists(string filename) {
CheckInitialized();
DirectoryInfo dir = new  DirectoryInfo(GetDirectoryPath(filename)
);
return dir.Exists;
}

public string GetAbsolutePathName(string path) {
return FSO.GetAbsolutePathName(path);
}

public string GetBaseName(string path) {
return FSO.GetBaseName(path);
}

public Drive GetDrive(string path) {
throw new NotSupportedException();
}

public string GetDriveName(string path) {
throw new NotSupportedException();
}

public string GetExtensionName(string path) {
return FSO.GetExtensionName(path);
}

public Scripting.File GetFile(string filename) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename, true));
return new File(this, FSO.GetFile(file.FullName));
}

public string GetFileVersion(string path) {
return FSO.GetFileVersion(path);
}

public string GetFileName(string path) {
return FSO.GetFileName(path);
}

public Scripting.Folder GetFolder(string filename) {
CheckInitialized();
DirectoryInfo dir = new  DirectoryInfo(GetDirectoryPath(filename,

true));
return new Folder(this, FSO.GetFolder(dir.FullName));
}

public string GetParentFolderName(string path) {
return FSO.GetParentFolderName(path);
}

public Scripting.Folder GetSpecialFolder(SpecialFolderConst
specialFolder) {
throw new NotSupportedException();
}

public TextStream GetStandardStream(StandardStreamTypes streamType, bool
unicode) {
throw new NotSupportedException();
}

public string GetTempName() {
return FSO.GetTempName();
}

public void MoveFile(string source, string destination) {
CheckInitialized();
FileInfo srcFile = new FileInfo(GetFilePath(source, true));
srcFile.MoveTo(GetFilePath(destination));
}

public void MoveFolder(string source, string destination) {
CheckInitialized();
DirectoryInfo srcDir = new DirectoryInfo(GetDirectoryPath(source,
true));
srcDir.MoveTo(GetDirectoryPath(destination));
}

/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename) {
return OpenTextFile(filename, 1);
}

/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename, short mode) {
return OpenTextFile(filename, mode, false);
}

/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename, short mode, bool create)
{
return OpenTextFile(filename, mode, create, 0);
}

/* Added for backwards compatibility. */
public TextStream OpenTextFile(string filename, short smode, bool
create, short sformat) {
IOMode   mode   = IOMode.ForReading;
Tristate format = Tristate.TristateFalse;

if(smode == 1) {
mode = IOMode.ForReading;
} else if(smode == 2) {
mode = IOMode.ForWriting;
} else if(smode == 8) {
mode = IOMode.ForAppending;
}

if(sformat == -2) {
format = Tristate.TristateUseDefault;
} else if(sformat == -1) {
format = Tristate.TristateTrue;
} else if(sformat == 0) {
format = Tristate.TristateFalse;
}

return OpenTextFile(filename, mode, create, format);
}

public TextStream OpenTextFile(string filename, IOMode mode, bool
create, Tristate format) {
CheckInitialized();
FileInfo file = new FileInfo(GetFilePath(filename));
return FSO.OpenTextFile(file.FullName, mode, create, format);
}



// Internal Operations.
internal string GetFilePath(string relpath) {
return GetFilePath(relpath, false);
}

internal string GetFilePath(string relpath, bool checkExists) {
CheckInitialized();

string path = null;
try {
FileInfo file = (Path.IsPathRooted(relpath)) ? new FileInfo(relpath)
: new FileInfo(Path.Combine(RootDirectory.FullName, relpath));
if(file == null || (checkExists && !(file.Exists))) {
throw new ArgumentNullException("File");
}

if(!(file.Directory.FullName.StartsWith(RootDirectory.FullName))) {
throw new Exception("Error: Hacking attempt");
}

path = file.FullName;
} catch {
throw new Exception("Custom.FileSystemObject Path Error");
}

return path;
}

internal string GetDirectoryPath(string relpath) {
return GetDirectoryPath(relpath, false);
}

internal string GetDirectoryPath(string relpath, bool checkExists) {
CheckInitialized();

string path = null;
try {
DirectoryInfo dir = (Path.IsPathRooted(relpath)) ? new
DirectoryInfo(relpath) : new
DirectoryInfo(Path.Combine(RootDirectory.FullName, relpath));
if(dir == null || (checkExists && !(dir.Exists))) {
throw new ArgumentNullException("Dir");
}

if(!(dir.FullName.StartsWith(RootDirectory.FullName))) {
throw new Exception("Error: Hacking attempt");
}

path = dir.FullName;
} catch {
throw new Exception("Custom.FileSystemObject Path Error");
}

return path;
}

// Private Helper Operations.
private void CheckInitialized() {
if(!((FSO != null && Request != null && Context != null && Server !=
null && RootDirectory != null && RootDirectory.Exists))) {
throw new Exception("Custom.FileSystemObject not initialized.");
}
}

private void InternalDirectoryCopy(DirectoryInfo source, string
destination, bool overwrite) {
if(source == null) {
return;
}

foreach(FileSystemInfo fso in source.GetFileSystemInfos()) {
string destName = Path.Combine(source.FullName, fso.Name);
if(fso is FileInfo) {
System.IO.File.Copy(fso.FullName, destName, overwrite);
} else if(fso is DirectoryInfo) {
Directory.CreateDirectory(destName);
 InternalDirectoryCopy((DirectoryInfo)fso
, destName, overwrite);
}
}
}
}
}







[ Post a follow-up to this message ]



    RE: Restrict FileSystemObject to it's virtual dir  
FKeller


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
10-26-04 01:47 AM

Hello Dallo

I wonder if you got it to work with the desired security?

I did see that there is a very ingenious ASP-script going around. Even on
big providers you can go with it to all drives, even C:\WINNT and \SYSTEM32
and read, change, delete or upload whatever you want. So as I did see even
big providers have not the needed security and are in danger. How did you
implement the security that users cannot go out of there root? Hackers event
use file upload possibilities in websites to upload the tool and use it then
.

Thanks for help,

Fritz Keller

"Dallo" wrote:

> Hi everybody,
> i've to configure on a single win2003 machine a lot dinamic web site.
> I'd like to protect each site from interference of other sites scripts tha
t
> uses, for example, filesystemobject method.
> In other words, i dont want asp script using FSO of a site can access,
> modify or delete files on other sites.
> Is there a way to restrict FSO to it's virtual directory?
>
>
> tnx to everyone
> 
>
>
>





[ Post a follow-up to this message ]



    RE: Restrict FileSystemObject to it's virtual dir  
FKeller


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
10-26-04 01:47 AM

Hello Dallo

I wonder if you got it to work with the desired security?

I did see that there is a very ingenious ASP-script going around. Even on
big providers you can go with it to all drives, even C:\WINNT and \SYSTEM32
and read, change, delete or upload whatever you want. So as I did see even
big providers have not the needed security and are in danger. How did you
implement the security that users cannot go out of there root? Hackers event
use file upload possibilities in websites to upload the tool and use it then
.

Thanks for help,

Fritz Keller

"Dallo" wrote:

> Hi everybody,
> i've to configure on a single win2003 machine a lot dinamic web site.
> I'd like to protect each site from interference of other sites scripts tha
t
> uses, for example, filesystemobject method.
> In other words, i dont want asp script using FSO of a site can access,
> modify or delete files on other sites.
> Is there a way to restrict FSO to it's virtual directory?
>
>
> tnx to everyone
> 
>
>
>





[ Post a follow-up to this message ]



    Re: Restrict FileSystemObject to it's virtual dir  
David Wang [Msft]


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
10-28-04 07:47 AM

Scripting.FileSystemObject does not support any such policy.  Web Servers
implement such "rooted" policies, but it only applies to the Web Server and
not scripts run by the Web Server (same reasoning).

You will have to rely on NTFS ACLs to prevent mingling between apps.

In general, "app isolation" is done through NTFS ACLs (i.e. if directory1 is
ACLd only to user1 and directory2 is ACLd only to user2, an app running as
user2 can only access directory2 but not directory1).

You can do this on IIS6 in a couple of ways:
1. Creating an Application Pool for each application, with a unique AppPool
Identity and Anonymous User/Authentication.  This effectively binds code run
by that AppPool to the configured AppPool/Anonymous identity(s).
2. Use unique AnonymousUser identity for every application for isolation.
This has a weakness in that if the script code can call "RevertToSelf", it
can gain access to the process identity, which by default already have
access to everything (you're relying on impersonation as isolation).

If you allow users to upload and run arbitrary code on the server, then you
must use Application Pools with unique AppPool Identity to isolate users
from each other.  The users must execute code in separate processes or else
they'd share something in common.

--
//David
IIS
This posting is provided "AS IS" with no warranties, and confers no rights.
//
"FKeller" <Fritz Keller@discussions.microsoft.com> wrote in message
news:A96D650B-CB7F-4D7D-A2B8-AC33BA528364@microsoft.com...
Hello Dallo

I wonder if you got it to work with the desired security?

I did see that there is a very ingenious ASP-script going around. Even on
big providers you can go with it to all drives, even C:\WINNT and \SYSTEM32
and read, change, delete or upload whatever you want. So as I did see even
big providers have not the needed security and are in danger. How did you
implement the security that users cannot go out of there root? Hackers event
use file upload possibilities in websites to upload the tool and use it
then.

Thanks for help,

Fritz Keller

"Dallo" wrote:

> Hi everybody,
> i've to configure on a single win2003 machine a lot dinamic web site.
> I'd like to protect each site from interference of other sites scripts
that
> uses, for example, filesystemobject method.
> In other words, i dont want asp script using FSO of a site can access,
> modify or delete files on other sites.
> Is there a way to restrict FSO to it's virtual directory?
>
>
> tnx to everyone
> 
>
>
>







[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 10:20 AM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register