473,399 Members | 3,302 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

file:// streams: writing a custom wrapper

Hi!

Here is the problem: I'd like to restrict local filesystem stream
operations to one directory just like a root jail.

fopen('/file.bin') would actually open /some/path/file.bin.

One goal of this behavior is to prevent Xinclude instructions to point
to "out of application directory" files when processed by the XSLT
processor, among other things.

I've been reading all I can about streams and wrappers and came to the
conclusion that one have no possibility of rewriting a stream wrapper
for the file:// scheme. Even if we can unregister the built-in wrapper
and register a custom one, we have no way to do the actual on-disk
stream operations within that wrapper.

My idea was to:

1. register a custom scheme that would use the built-in wrapper used to
handle the file:// wrapper. That could even be something dynamic to
prevent 3rd-party XML documents to use that unrestricted scheme. let's
say we give it a static name and call it "file.full://".

2. write a wrapper rejecting operations on files outside of the allowed
jailed directory. that wrapper would use the file.full:// scheme to
actually write/read data, after having mapped jailed paths to real
filesystem paths.

Here is an example:

1. An XML document needs "/dir/file.xml" to be xinclude'd by the XSLT
processor.

2. The custom file:// wrapper receives the request and maps
"/dir/file.xml" to "/var/www/data-jail/dir/file.xml". It then uses the
file.full:// scheme to pass the request to the real wrapper. This means
that what I wanted was a situation where "file:///dir/file.xml" is
equivalent to "file.full:///var/www/data-jail/dir/file.xml".

As already said, file.full could be dynamic to prevent the XML document
from using the unrestricted wrapper.

Ideally, PHP would provide the classes that handle the built-in schemes.
Imagine that 'BuiltInFileWrapper' is the class that handle file://
streams by default:

<?php
stream_wrapper_unregister('file');
stream_wrapper_register('file', 'CustomRestrictedFileWrapper');
stream_wrapper_register('file.full', 'BuiltInFileWrapper');
?>

In this example my CustomRestrictedFileWrapper class may still actually
handle the read/write operations through the file.full scheme.

Is there any solution to simulate this? How can I get that behavior?

Another less important question is: is it possible to register another
default scheme than file://?

Thank you very much for your help,

Julien.
May 19 '06 #1
9 3437
Julien Biezemans wrote:
Hi!

Here is the problem: I'd like to restrict local filesystem stream
operations to one directory just like a root jail.

fopen('/file.bin') would actually open /some/path/file.bin.

One goal of this behavior is to prevent Xinclude instructions to point
to "out of application directory" files when processed by the XSLT
processor, among other things.

I've been reading all I can about streams and wrappers and came to the
conclusion that one have no possibility of rewriting a stream wrapper
for the file:// scheme. Even if we can unregister the built-in wrapper
and register a custom one, we have no way to do the actual on-disk
stream operations within that wrapper.

My idea was to:

1. register a custom scheme that would use the built-in wrapper used to
handle the file:// wrapper. That could even be something dynamic to
prevent 3rd-party XML documents to use that unrestricted scheme. let's
say we give it a static name and call it "file.full://".

2. write a wrapper rejecting operations on files outside of the allowed
jailed directory. that wrapper would use the file.full:// scheme to
actually write/read data, after having mapped jailed paths to real
filesystem paths.

Here is an example:

1. An XML document needs "/dir/file.xml" to be xinclude'd by the XSLT
processor.

2. The custom file:// wrapper receives the request and maps
"/dir/file.xml" to "/var/www/data-jail/dir/file.xml". It then uses the
file.full:// scheme to pass the request to the real wrapper. This means
that what I wanted was a situation where "file:///dir/file.xml" is
equivalent to "file.full:///var/www/data-jail/dir/file.xml".

As already said, file.full could be dynamic to prevent the XML document
from using the unrestricted wrapper.

Ideally, PHP would provide the classes that handle the built-in schemes.
Imagine that 'BuiltInFileWrapper' is the class that handle file://
streams by default:

<?php
stream_wrapper_unregister('file');
stream_wrapper_register('file', 'CustomRestrictedFileWrapper');
stream_wrapper_register('file.full', 'BuiltInFileWrapper');
?>

In this example my CustomRestrictedFileWrapper class may still actually
handle the read/write operations through the file.full scheme.

Is there any solution to simulate this? How can I get that behavior?

Another less important question is: is it possible to register another
default scheme than file://?

Thank you very much for your help,

Julien.


Actually, I think this is a job better suited for the Apache configuration. Try
alt.apache.configuration

You may also be able to do some of it at the OS (assuming you're using a version
of Unix/Linux).

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
May 19 '06 #2
Jerry Stuckle wrote:

Actually, I think this is a job better suited for the Apache
configuration. Try alt.apache.configuration

You may also be able to do some of it at the OS (assuming you're using a
version of Unix/Linux).


How can apache help me there? I don't see the point. Please note that I
need full local filesystem access in some internal parts of the
application. The "jailed" wrapper is meant to be used as the default
file:// scheme handler but internal stuffs will need the unrestricted
wrapper (accessed under a different scheme than the default one, for
example).

Someone pointed me to open_basedir ini instruction, but this also causes
_any_ stream function to be restricted to the specified directory, which
is not acceptable.

For example, I have a class autoload function that needs to access a
directory outside the jail.

I know, that's tricky. But I'm convinced that PHP could improve its
stream wrappers support by supplying built-in wrapper classes. At the
moment, being able to register a custom file:// scheme handler is almost
of no use at all as there is now way to actually read and write the
files within the custom wrapper.

Julien.
May 19 '06 #3
Julien Biezemans wrote:
Jerry Stuckle wrote:
Actually, I think this is a job better suited for the Apache
configuration. Try alt.apache.configuration

You may also be able to do some of it at the OS (assuming you're using a
version of Unix/Linux).

How can apache help me there? I don't see the point. Please note that I
need full local filesystem access in some internal parts of the
application. The "jailed" wrapper is meant to be used as the default
file:// scheme handler but internal stuffs will need the unrestricted
wrapper (accessed under a different scheme than the default one, for
example).

Someone pointed me to open_basedir ini instruction, but this also causes
_any_ stream function to be restricted to the specified directory, which
is not acceptable.

For example, I have a class autoload function that needs to access a
directory outside the jail.

I know, that's tricky. But I'm convinced that PHP could improve its
stream wrappers support by supplying built-in wrapper classes. At the
moment, being able to register a custom file:// scheme handler is almost
of no use at all as there is now way to actually read and write the
files within the custom wrapper.

Julien.


Julien,

The Apache configuration can help because Apache is handling the file:// schema
- and you can use it to restrict access, redirect from one directory to another,
etc. However, fopen() does not use Apache - it goes straight to the OS, so
Apache configuration restrictions will not affect it.

Again, try alt.apache.configuration.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
May 19 '06 #4
Julien Biezemans wrote:
I know, that's tricky. But I'm convinced that PHP could improve its
stream wrappers support by supplying built-in wrapper classes. At the
moment, being able to register a custom file:// scheme handler is almost
of no use at all as there is now way to actually read and write the
files within the custom wrapper.


Have you try stream_wrapper_restore()? The idea is to restore the
original wrapper, open the file, then unregister it again.

May 19 '06 #5
Jerry Stuckle wrote:

Julien,

The Apache configuration can help because Apache is handling the file://
schema - and you can use it to restrict access, redirect from one
directory to another, etc. However, fopen() does not use Apache - it
goes straight to the OS, so Apache configuration restrictions will not
affect it.

Again, try alt.apache.configuration.


Thank you.

However I'm still not convinced that it will be of any help. In what
parts oh PHP does apache file:// scheme handling apply? I guess it
concerns includes/requires, stuffs like that? One of the main purposes
of what I'm asking is to restrict file accesses within the built-in PHP
XSLT processor and it makes use of the PHP stream system which is, like
you said, independent of apache.

I'm going to dig the apache docs though. But I doubt it will be my answer.

Thanks again,

Julien.
May 19 '06 #6
Chung Leong wrote:
Julien Biezemans wrote:
I know, that's tricky. But I'm convinced that PHP could improve its
stream wrappers support by supplying built-in wrapper classes. At the
moment, being able to register a custom file:// scheme handler is almost
of no use at all as there is now way to actually read and write the
files within the custom wrapper.


Have you try stream_wrapper_restore()? The idea is to restore the
original wrapper, open the file, then unregister it again.


Euręka! Am I an idiot or what? Sometimes we look for complex solutions
while there is an easy one :)

I guess it will work. I'm going to try this tonight.

Thank you !

Julien.
May 19 '06 #7
Julien Biezemans wrote:

Euręka! Am I an idiot or what? Sometimes we look for complex solutions
while there is an easy one :)

I guess it will work. I'm going to try this tonight.

Thank you !

Julien.


Segfaults, segfaults, segfaults. The first stream being read by my
encapsulating wrapper does work but following streams just make PHP crash.

What a pity.
May 21 '06 #8
Julien Biezemans wrote:
Julien Biezemans wrote:
Euręka! Am I an idiot or what? Sometimes we look for complex solutions
while there is an easy one :)

I guess it will work. I'm going to try this tonight.

Thank you !

Julien.


Segfaults, segfaults, segfaults. The first stream being read by my
encapsulating wrapper does work but following streams just make PHP crash.

What a pity.


Upgraded from 5.1.2 to 5.1.4 and the segfaults disappeared :D
May 21 '06 #9
I just wanted to share my experience: the wrappers do the job very well.

I have built a wrapper which jails local file streams to a specific
directory. This allows the following behavior:

<?php
$fh = fopen('/catalog/main.xml', 'r');
?>

Actually opens up '/srv/app_root/catalog/main.xml'. Internal functions
are authorized to open non jailed files by using the dynamic
free.file-XX:// stream scheme (where XX are changing figures). This
prevents XML document to refer to out-of-jail documents within Xinclude
elements or other proprietary stuffs.

As libxml PHP extension makes use of streams:

<?php
DOMDocument::load('/catalog/main.xml');
?>

Does work too, that's really nice.

Remember that I had to upgrade from PHP 5.1.2 to 5.1.4 to prevent
strange segfaults in the wrappers.

Maybe this can inspire someone.

Julien.
May 22 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: sb | last post by:
I think streams are nice, but what do you do when you have to write to or, even worse, read from a FILE*, for example a UNIX stream? C++ streams can not be created from FILE*'s or have them...
6
by: radnoraj | last post by:
Hi, I am sucessfull in redirecting console output to a file. but in this case nothing is displayed on the console, cout output is written to file without display. how do write the output to...
16
by: ben beroukhim | last post by:
I have huge number of legacy code which use standard files functions. I would like to pass a memory pointer rather than a FILE pointer. I am trying to use FILEs in the code to refer to memory...
3
by: frustrated | last post by:
I am trying to share a file stream between two threads, but havent got a clue as to how to do it. The first thread will be reading the file, and the second thread will(/might) be writing to the...
1
by: Daniel Oberhoff | last post by:
Hello all, I am writing a util framework to operate on matlab mat files because I don't want to link to matlab for this and I didn't like the available c-implementation. also i wanted to use...
1
AdrianH
by: AdrianH | last post by:
Assumptions I am assuming that you know or are capable of looking up the functions I am to describe here and have some remedial understanding of C programming. FYI Although I have called this...
30
by: SpreadTooThin | last post by:
Damn.. FILE *fp was just sooo much easier than C++ file i/o... I just don't get it.. really! filebuf, istream, ostream, ifstream, ofstream, iosteam... what the f&(){( do I use to do binary file...
0
by: Julien Biezemans | last post by:
Hi everyone, I've written a file:// scheme stream wrapper that acts like chroot() (but is more flexible, does not require root privileges and works on any platform). Everything works just fine...
3
by: =?Utf-8?B?TG9yZW4=?= | last post by:
I’m trying to encrypt and decrypt a file in vb.net. I am using the TripleDESCryptoServiceProvider encryption found in System.Security.Cryptography. Below is the code for my Encrypt and Decrypt...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.