You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Marc Slemko <ma...@znep.com> on 1998/07/04 02:20:07 UTC

FindFirstFile

On Win32, we can use FindFirstFile on a filename to get the actual name of
a file on the filesystem and compare against what we think the name should
be. 

Performance sucks, it doesn't deal with directories unless you do it for
each component and it still may not be right.

Don't know if it is worth doing, and it isn't there right way to fix this
crap, but it could be useful.


Re: FindFirstFile

Posted by Alexei Kosut <ak...@leland.Stanford.EDU>.
On Sat, 4 Jul 1998, Ben Laurie wrote:

> > This has the added benefit of not screwing up dots and slashes in
> > PATH_INFO, as the current os_canonical_filename() does.
> 
> No it doesn't! That's what I spent all that energy on fixing!

Well, trailing dots in PATH_INFO are currently removed. That code should
probably be moved into sub_canonical_filename().

> However, I'm beginning to agree with you. Actually, I seem to remember I
> started out agreeing but went astray somewhere down the line. 

There are two issues as far as I can tell:

1. There are some filenames that Windows treats as the same, e.g.,
trailing dots and spaces, and case stuff. These we *can* silently rewrite
(though see point 2). Then there are characters (< > " : / \) and
other thingies (aux, con, etc...) that are "reserved" by the OS, and we
shouldn't try to read from. There is no legal way for a filename to
contain a colon, for example, so we should reject requests that contain
them. This would prevent the ::$DATA problem, for example (although we
don't appear to be vulnerable to to right now).

2. On Unix there's a tighter associativity between URLs and filenames,
since a filename can be described uniquely. i.e., consider the following:

DocumentRoot /foo
Redirect /old /new

On Unix, there is no way to access the /foo/old directive, even though it
is in the document root. On Win32, I can access /old%20, /old., or even
/OLD and get to the directory I presumably was trying to remove access to.

Of course, the proper thing to do is to realize that anything within a
public document space is subject to access, and either remove /foo/old, or
add

<Directory /foo/old>
order allow,deny
deny from all
</Directory>

But...

> But I think that throwing stuff out for non-matching case is probably
> going too far.

I agree, since the "canonical" name as far as the Windows *user* is
concerned (i.e., what appears in Windows Explorer) could be lower or upper
case, regardless of what Apache thinks. Of course, this throws off my
argument for not silently canonicalizing names as per point 2 above, since
any URL manipulation you could get around with dots or spaces, you could
also get around by changing case.

*sigh*

I dunno.

-- Alexei Kosut <ak...@stanford.edu> <http://www.stanford.edu/~akosut/>
   Stanford University, Class of 2001 * Apache <http://www.apache.org> *



Re: FindFirstFile

Posted by Ben Laurie <be...@algroup.co.uk>.
Alexei Kosut wrote:
> 
> On Sat, 4 Jul 1998, Marc Slemko wrote:
> 
> > Oh.
> >
> > So if you do FindFirstFile on one of the varient names for a file, does it
> > give the real name or the varient?
> 
> The variant. Its only use here is to "confirm" that the file really
> exists, I suppose. If it did canonicalize the filename, then the way
> os_canonical_filename() uses it would, too.
> 
> > If it gives the varient, then it is screwed to hell.
> 
> Nah, it works as well as the rest of Windows.
> 
> I've been looking at
> mk:@ivt:pdwbase/native/sdk/win32/sys/src/filesio_4.htm ("Filename
> Conventions") and related documentation, and all I have to say is "blah".
> 
> I am now seriously thinking that os_canonical_filename(), instead of
> silently rewriting filenames to conform to Apache's idea of what a file
> should look like, should only confirm that it does. If not, it should
> return NULL and Apache can return a 403, log "%s is not a canonical form
> of a filename" and get on with life.
> 
> That would make the function simpler, too... toss out any filename with
> one of < > | " or : (none of which are valid, except the colon as a drive
> seperator), toss out any filename that has a dot or a space at the end of
> a path segment, and run GetFullPathName() on each segment, and if it
> doesn't match, toss it out. It might even check QueryDosDevice() to make
> sure someone isn't trying to mess with devices (although I don't think
> that works anyway).
> 
> This has the added benefit of not screwing up dots and slashes in
> PATH_INFO, as the current os_canonical_filename() does.

No it doesn't! That's what I spent all that energy on fixing! However,
I'm beginning to agree with you. Actually, I seem to remember I started
out agreeing but went astray somewhere down the line.

But I think that throwing stuff out for non-matching case is probably
going too far.

Cheers,

Ben.

-- 
Ben Laurie            |Phone: +44 (181) 735 0686| Apache Group member
Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org/
and Technical Director|Email: ben@algroup.co.uk |
A.L. Digital Ltd,     |Apache-SSL author     http://www.apache-ssl.org/
London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache/

WE'RE RECRUITING! http://www.aldigital.co.uk/recruit/

Re: FindFirstFile

Posted by Ben Laurie <be...@algroup.co.uk>.
Marc Slemko wrote:
> 
> On Sat, 4 Jul 1998, Alexei Kosut wrote:
> 
> > On Sat, 4 Jul 1998, Marc Slemko wrote:
> >
> > > Oh.
> > >
> > > So if you do FindFirstFile on one of the varient names for a file, does it
> > > give the real name or the varient?
> >
> > The variant. Its only use here is to "confirm" that the file really
> > exists, I suppose. If it did canonicalize the filename, then the way
> > os_canonical_filename() uses it would, too.
> >
> 
> Does _findfirst do the same thing?
> 
> (who the hell names public APIs starting with _'s for fun?)

Isn't it a standards thing? Leading _ means "the standard sort of
mentions this, but without quite standardising it" doesn't it? So things
like open are properly spelt _open.

Cheers,

Ben.

-- 
Ben Laurie            |Phone: +44 (181) 735 0686| Apache Group member
Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org/
and Technical Director|Email: ben@algroup.co.uk |
A.L. Digital Ltd,     |Apache-SSL author     http://www.apache-ssl.org/
London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache/

WE'RE RECRUITING! http://www.aldigital.co.uk/recruit/

Re: FindFirstFile

Posted by Dean Gaudet <dg...@arctic.org>.

On Sat, 4 Jul 1998, Marc Slemko wrote:

> Does _findfirst do the same thing?
> 
> (who the hell names public APIs starting with _'s for fun?)

Any C compiler vendor following the rules.  If they named it findfirst() 
they'd collide with both the user's namespace and ANSI's namespace.

Dean


Re: FindFirstFile

Posted by Marc Slemko <ma...@znep.com>.
On Sat, 4 Jul 1998, Alexei Kosut wrote:

> On Sat, 4 Jul 1998, Marc Slemko wrote:
> 
> > Oh.  
> > 
> > So if you do FindFirstFile on one of the varient names for a file, does it
> > give the real name or the varient?
> 
> The variant. Its only use here is to "confirm" that the file really
> exists, I suppose. If it did canonicalize the filename, then the way
> os_canonical_filename() uses it would, too.
> 

Does _findfirst do the same thing?

(who the hell names public APIs starting with _'s for fun?)


Re: FindFirstFile

Posted by Marc Slemko <ma...@znep.com>.

On Sat, 4 Jul 1998, Alexei Kosut wrote:

> On Sat, 4 Jul 1998, Marc Slemko wrote:
> 
> > Oh.  
> > 
> > So if you do FindFirstFile on one of the varient names for a file, does it
> > give the real name or the varient?
> 
> The variant. Its only use here is to "confirm" that the file really
> exists, I suppose. If it did canonicalize the filename, then the way
> os_canonical_filename() uses it would, too.

But... but.... but... but... it can't do that!  I would have never
imagined it doing that.  Broken is one thing, but that... that... that... 

Sigh.


Re: FindFirstFile

Posted by Alexei Kosut <ak...@leland.Stanford.EDU>.
On Sat, 4 Jul 1998, Marc Slemko wrote:

> Oh.  
> 
> So if you do FindFirstFile on one of the varient names for a file, does it
> give the real name or the varient?

The variant. Its only use here is to "confirm" that the file really
exists, I suppose. If it did canonicalize the filename, then the way
os_canonical_filename() uses it would, too.

> If it gives the varient, then it is screwed to hell.

Nah, it works as well as the rest of Windows.

I've been looking at
mk:@ivt:pdwbase/native/sdk/win32/sys/src/filesio_4.htm ("Filename
Conventions") and related documentation, and all I have to say is "blah".

I am now seriously thinking that os_canonical_filename(), instead of
silently rewriting filenames to conform to Apache's idea of what a file
should look like, should only confirm that it does. If not, it should
return NULL and Apache can return a 403, log "%s is not a canonical form
of a filename" and get on with life.

That would make the function simpler, too... toss out any filename with
one of < > | " or : (none of which are valid, except the colon as a drive
seperator), toss out any filename that has a dot or a space at the end of
a path segment, and run GetFullPathName() on each segment, and if it
doesn't match, toss it out. It might even check QueryDosDevice() to make
sure someone isn't trying to mess with devices (although I don't think
that works anyway).

This has the added benefit of not screwing up dots and slashes in
PATH_INFO, as the current os_canonical_filename() does.

I'll see about a patch tonight. June 24th has passed, but there are enough
concerns with this that I think we should aim for 1.3.1, with all the
Win32 security fixes we can muster, ASAP.

-- Alexei Kosut <ak...@stanford.edu> <http://www.stanford.edu/~akosut/>
   Stanford University, Class of 2001 * Apache <http://www.apache.org> *



Re: FindFirstFile

Posted by Marc Slemko <ma...@worldgate.com>.
Oh.  

So if you do FindFirstFile on one of the varient names for a file, does it
give the real name or the varient?

If it gives the varient, then it is screwed to hell.

If it gives the real name, then why (aside from directories) do we have to
worry about that in another place?

On Sat, 4 Jul 1998, Ben Laurie wrote:

> Marc Slemko wrote:
> > 
> > On Win32, we can use FindFirstFile on a filename to get the actual name of
> > a file on the filesystem and compare against what we think the name should
> > be.
> 
> Errr ... we already do (use FindFirstFile, that is, not compare). Not
> sure at what point you want to use it, though?
> 
> Cheers,
> 
> Ben.
> 
> -- 
> Ben Laurie            |Phone: +44 (181) 735 0686| Apache Group member
> Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org/
> and Technical Director|Email: ben@algroup.co.uk |
> A.L. Digital Ltd,     |Apache-SSL author     http://www.apache-ssl.org/
> London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache/
> 
> WE'RE RECRUITING! http://www.aldigital.co.uk/recruit/
> 


Re: FindFirstFile

Posted by Ben Laurie <be...@algroup.co.uk>.
Marc Slemko wrote:
> 
> On Win32, we can use FindFirstFile on a filename to get the actual name of
> a file on the filesystem and compare against what we think the name should
> be.

Errr ... we already do (use FindFirstFile, that is, not compare). Not
sure at what point you want to use it, though?

Cheers,

Ben.

-- 
Ben Laurie            |Phone: +44 (181) 735 0686| Apache Group member
Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org/
and Technical Director|Email: ben@algroup.co.uk |
A.L. Digital Ltd,     |Apache-SSL author     http://www.apache-ssl.org/
London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache/

WE'RE RECRUITING! http://www.aldigital.co.uk/recruit/