Re: [PHP] Comparing strings... need advice. :)

2006-08-29 Thread Ivo F.A.C. Fokkema
On Mon, 28 Aug 2006 19:39:49 -0400, Robert Cummings wrote:
 On Mon, 2006-08-28 at 16:50 +0200, Ivo F.A.C. Fokkema wrote:
 On Mon, 28 Aug 2006 09:47:02 +0100, Stut wrote:
  Micky Hulse wrote:
  I am looking for the most secure/efficient way to compare these two
  strings:
  
  /folder1/folder2/folder3/folder4/
  /folder1/folder2/folder3/folder4/file.php
  
  Basically I am trying to setup as many security features as possible for
  a simplistic (home-grown/hand-coded) CMS...
  
  This appears to work:
  
  $haystack = '/folder1/folder2/folder3/folder4/someFileName.php';
  $needle = '/folder1/folder2/folder3/folder4/';
  if(substr_count($haystack, $needle) === 1) echo yea;
  
  Before making changes to someFileName.php I want to make sure it is
  within the allowed path ($needle).
  
  First of all make sure you are sending both strings through realpath
  (http://php.net/realpath) to remove any symbolic links and relative
  references. Then you can compare the two strings. The way you're doing
  it will work but it's probably not very efficient. This is what I use...
  
  $valid = (strcmp($needle, substr($haystack, 0, strlen($needle))) == 0);
  
 
 Personally, this seems simpler to me:
 
 $valid = (dirname($haystack) == $needle);
 
 But the way the above folders are presented, it should become
 
 $valid = (dirname($haystack) == rtrim($needle, '/'));
 
 less simple already... Possibly, this is not the best solution for some
 reason I don't know. If so, I would like to know :)
 
 The above technique doesn't allow for sub-directories. It only allows
 for files within the needle directory.

Ah, thanks. Misunderstood the question, then. Thought just checking if
it's a file in that directory was what's needed.

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-29 Thread Micky Hulse

Ivo F.A.C. Fokkema wrote:

Ah, thanks. Misunderstood the question, then. Thought just checking if
it's a file in that directory was what's needed.


You were right. :)

I did not plan on looking-in anything other than one or two hard-coded 
folder locations. But, it is good to know the details. ;)


Thanks again for the help...

Time for me to hit the hay. I have een geeking-out for way too long today.

Cheers,
Micky

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Stut
Micky Hulse wrote:
 I am looking for the most secure/efficient way to compare these two
 strings:
 
 /folder1/folder2/folder3/folder4/
 /folder1/folder2/folder3/folder4/file.php
 
 Basically I am trying to setup as many security features as possible for
 a simplistic (home-grown/hand-coded) CMS...
 
 This appears to work:
 
 $haystack = '/folder1/folder2/folder3/folder4/someFileName.php';
 $needle = '/folder1/folder2/folder3/folder4/';
 if(substr_count($haystack, $needle) === 1) echo yea;
 
 Before making changes to someFileName.php I want to make sure it is
 within the allowed path ($needle).

First of all make sure you are sending both strings through realpath
(http://php.net/realpath) to remove any symbolic links and relative
references. Then you can compare the two strings. The way you're doing
it will work but it's probably not very efficient. This is what I use...

$valid = (strcmp($needle, substr($haystack, 0, strlen($needle))) == 0);

-Stut

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Micky Hulse

Stut wrote:

First of all make sure you are sending both strings through realpath
(http://php.net/realpath) to remove any symbolic links and relative
references. Then you can compare the two strings. The way you're doing
it will work but it's probably not very efficient. This is what I use...

$valid = (strcmp($needle, substr($haystack, 0, strlen($needle))) == 0);


Awsome! Thanks for the info. Reading-up on realpath right now. I 
appreciate the tips/example code.  :)


Have a great day/night.

Cheers,
Micky

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread David Tulloh
Micky Hulse wrote:
 Hi,
 
 I am looking for the most secure/efficient way to compare these two
 strings:
 
 /folder1/folder2/folder3/folder4/
 /folder1/folder2/folder3/folder4/file.php
 
 Basically I am trying to setup as many security features as possible for
 a simplistic (home-grown/hand-coded) CMS...
 
 This appears to work:
 
 $haystack = '/folder1/folder2/folder3/folder4/someFileName.php';
 $needle = '/folder1/folder2/folder3/folder4/';
 if(substr_count($haystack, $needle) === 1) echo yea;
 
 Before making changes to someFileName.php I want to make sure it is
 within the allowed path ($needle).
 
 I would appreciate any advice. Even RTFM is cool.  :D
 

Using your technique I would try an attack like:
'/etc/passwd;/folder1/folder2/folder3/folder4/' or
'/folder1/folder2/folder3/folder4/../../../../etc/passwd'
or some other variant depending on how you then use the file.


I'm a big fan of lists of allowed files, typically I use aliases too.
$allow_files = array('page' = '/folder/.../filename.php').
This list can be automatically generated and used by mod_rewrite to
boost speed.
By using a fixed list of files like this it's impossible to be attacked
on your filename.


Assuming you don't want to go that strong and want to allow your users
to set the filename you have to try and lock down the path.  By not
allowing them to change the path you can hold them in the directory you set.
Check for any / characters and reject or strip them out.
Use '/folder1/folder2/.../'.$file.
It's vital if you do this that you don't allow any way to upload files
in to the directory you execute from.

If you want to allow them to set the path or part of the path then the
check gets far more complicated.  You have to catch .. and // patterns,
ensuring that you don't combine to form a // and catch cases like
'.\./'.  If you need to have multiple directories I would strongly
suggest using dynamically generated fixed lists.


David

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Ivo F.A.C. Fokkema
On Mon, 28 Aug 2006 09:47:02 +0100, Stut wrote:

 Micky Hulse wrote:
 I am looking for the most secure/efficient way to compare these two
 strings:
 
 /folder1/folder2/folder3/folder4/
 /folder1/folder2/folder3/folder4/file.php
 
 Basically I am trying to setup as many security features as possible for
 a simplistic (home-grown/hand-coded) CMS...
 
 This appears to work:
 
 $haystack = '/folder1/folder2/folder3/folder4/someFileName.php';
 $needle = '/folder1/folder2/folder3/folder4/';
 if(substr_count($haystack, $needle) === 1) echo yea;
 
 Before making changes to someFileName.php I want to make sure it is
 within the allowed path ($needle).
 
 First of all make sure you are sending both strings through realpath
 (http://php.net/realpath) to remove any symbolic links and relative
 references. Then you can compare the two strings. The way you're doing
 it will work but it's probably not very efficient. This is what I use...
 
 $valid = (strcmp($needle, substr($haystack, 0, strlen($needle))) == 0);
 

Personally, this seems simpler to me:

$valid = (dirname($haystack) == $needle);

But the way the above folders are presented, it should become

$valid = (dirname($haystack) == rtrim($needle, '/'));

less simple already... Possibly, this is not the best solution for some
reason I don't know. If so, I would like to know :)

Ivo

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Robert Cummings
On Mon, 2006-08-28 at 09:47 +0100, Stut wrote:
 Micky Hulse wrote:
  I am looking for the most secure/efficient way to compare these two
  strings:
  
  /folder1/folder2/folder3/folder4/
  /folder1/folder2/folder3/folder4/file.php
  
  Basically I am trying to setup as many security features as possible for
  a simplistic (home-grown/hand-coded) CMS...
  
  This appears to work:
  
  $haystack = '/folder1/folder2/folder3/folder4/someFileName.php';
  $needle = '/folder1/folder2/folder3/folder4/';
  if(substr_count($haystack, $needle) === 1) echo yea;
  
  Before making changes to someFileName.php I want to make sure it is
  within the allowed path ($needle).
 
 First of all make sure you are sending both strings through realpath
 (http://php.net/realpath) to remove any symbolic links and relative
 references. Then you can compare the two strings. The way you're doing
 it will work but it's probably not very efficient. This is what I use...
 
 $valid = (strcmp($needle, substr($haystack, 0, strlen($needle))) == 0);

?php

function isAllowedPath( $needle, $haystack )
{
$needle   = realpath( $needle ).'/';
$haystack = realpath( $haystack );

return (strpos( $haystack, $needle ) === 0);
}

?

It is VERY important that you append the trailing slash onto the needle
path returned by realpath otherwise it will match more than you expect.
Stut didn't point that out so I thought I'd make sure you caught it.
Also I'm not sure why Stut used 3 function calls when one suffices :)

Cheers,
Rob.
-- 
..
| InterJinn Application Framework - http://www.interjinn.com |
::
| An application and templating framework for PHP. Boasting  |
| a powerful, scalable system for accessing system services  |
| such as forms, properties, sessions, and caches. InterJinn |
| also provides an extremely flexible architecture for   |
| creating re-usable components quickly and easily.  |
`'

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Micky Hulse

Wow, thanks for all the great information folks (Stut, Ivo, Rob, and David.)

I really appreciate all of the top-notch advice and expert information. :D

Looks like I have a lot to think about...

Currently, I hard-code the paths to the folders that house the files I 
want my CMS to edit (via a config file.) The script then iterates 
through the directory and adds all files of a specific type to a 
dropdown menu. The user can then choose one of the files to edit and 
load that file into a textarea... After changes are made, the 
content/code gets saved back to the same file/location.


I do have an uploads folder, but it is in a different location on the 
server. I do not allow the user to create new files (I would have to do 
that manually)... it is a /very/ basic CMS.


Anyway, looks like I have some great info to work with. Thanks again 
everyone for sharing your expertise.


Much appreciated all. Have an excellent day.
Cheers,
Micky

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Robert Cummings
On Mon, 2006-08-28 at 16:50 +0200, Ivo F.A.C. Fokkema wrote:
 On Mon, 28 Aug 2006 09:47:02 +0100, Stut wrote:
 
  Micky Hulse wrote:
  I am looking for the most secure/efficient way to compare these two
  strings:
  
  /folder1/folder2/folder3/folder4/
  /folder1/folder2/folder3/folder4/file.php
  
  Basically I am trying to setup as many security features as possible for
  a simplistic (home-grown/hand-coded) CMS...
  
  This appears to work:
  
  $haystack = '/folder1/folder2/folder3/folder4/someFileName.php';
  $needle = '/folder1/folder2/folder3/folder4/';
  if(substr_count($haystack, $needle) === 1) echo yea;
  
  Before making changes to someFileName.php I want to make sure it is
  within the allowed path ($needle).
  
  First of all make sure you are sending both strings through realpath
  (http://php.net/realpath) to remove any symbolic links and relative
  references. Then you can compare the two strings. The way you're doing
  it will work but it's probably not very efficient. This is what I use...
  
  $valid = (strcmp($needle, substr($haystack, 0, strlen($needle))) == 0);
  
 
 Personally, this seems simpler to me:
 
 $valid = (dirname($haystack) == $needle);
 
 But the way the above folders are presented, it should become
 
 $valid = (dirname($haystack) == rtrim($needle, '/'));
 
 less simple already... Possibly, this is not the best solution for some
 reason I don't know. If so, I would like to know :)

The above technique doesn't allow for sub-directories. It only allows
for files within the needle directory.

Cheers,
Rob.
-- 
..
| InterJinn Application Framework - http://www.interjinn.com |
::
| An application and templating framework for PHP. Boasting  |
| a powerful, scalable system for accessing system services  |
| such as forms, properties, sessions, and caches. InterJinn |
| also provides an extremely flexible architecture for   |
| creating re-usable components quickly and easily.  |
`'

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Robert Cummings
On Mon, 2006-08-28 at 16:28 -0700, Micky Hulse wrote:
 Wow, thanks for all the great information folks (Stut, Ivo, Rob, and David.)
 
 I really appreciate all of the top-notch advice and expert information. :D
 
 Looks like I have a lot to think about...
 
 Currently, I hard-code the paths to the folders that house the files I 
 want my CMS to edit (via a config file.) The script then iterates 
 through the directory and adds all files of a specific type to a 
 dropdown menu. The user can then choose one of the files to edit and 
 load that file into a textarea... After changes are made, the 
 content/code gets saved back to the same file/location.
 
 I do have an uploads folder, but it is in a different location on the 
 server. I do not allow the user to create new files (I would have to do 
 that manually)... it is a /very/ basic CMS.
 
 Anyway, looks like I have some great info to work with. Thanks again 
 everyone for sharing your expertise.

How are these saved files then imported into the content? Are they
included or do you retrieve the contents using something like file(),
file_get_contents(), or fread() and then echo it? If you are using
include or require on a file whose contents are based on web input
content then you are opening up a can of security worms since anyone
with access tot he CMS could embed PHP code in the content and do
anything for which the webserver has permissions.

Cheers,
Rob.
-- 
..
| InterJinn Application Framework - http://www.interjinn.com |
::
| An application and templating framework for PHP. Boasting  |
| a powerful, scalable system for accessing system services  |
| such as forms, properties, sessions, and caches. InterJinn |
| also provides an extremely flexible architecture for   |
| creating re-usable components quickly and easily.  |
`'

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Micky Hulse

Hi Robert,

Robert Cummings wrote:

How are these saved files then imported into the content? Are they
included or do you retrieve the contents using something like file(),
file_get_contents(), or fread() and then echo it? If you are using


Currently I am using readfile() (plus some other security checking) to 
display the contents of the edited files. I setup my script to only 
allow specific file types (txt, html, htm).



include or require on a file whose contents are based on web input
content then you are opening up a can of security worms since anyone
with access tot he CMS could embed PHP code in the content and do
anything for which the webserver has permissions.


Thanks for pointing that out. Now that you mention it, I should probably 
re-work my code to use a different method of page inclusion. I am pretty 
concerned about security breaches... what are your thoughts on 
readfile()? Would you suggest I use file(), file_get_contents(), or 
fread() instead?


Thanks for the help Robert, I really appreciate your time.  :)

Cheers,
Micky

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Robert Cummings
On Mon, 2006-08-28 at 17:07 -0700, Micky Hulse wrote:
 Hi Robert,
 
 Robert Cummings wrote:
  How are these saved files then imported into the content? Are they
  included or do you retrieve the contents using something like file(),
  file_get_contents(), or fread() and then echo it? If you are using
 
 Currently I am using readfile() (plus some other security checking) to 
 display the contents of the edited files. I setup my script to only 
 allow specific file types (txt, html, htm).
 
  include or require on a file whose contents are based on web input
  content then you are opening up a can of security worms since anyone
  with access tot he CMS could embed PHP code in the content and do
  anything for which the webserver has permissions.
 
 Thanks for pointing that out. Now that you mention it, I should probably 
 re-work my code to use a different method of page inclusion. I am pretty 
 concerned about security breaches... what are your thoughts on 
 readfile()? Would you suggest I use file(), file_get_contents(), or 
 fread() instead?

Readfile works great, it's the same as file_get_contents() and then
issuing an echo. You may want to also stored content generated by web
users outside of the web tree. There may not be any issue with how you
have things now, but imagine down the road someone using your system
enables PHP processing on .html files and then someone created content
with PHP tags and accesses it directly from their browser... boom, same
security hole.

 Thanks for the help Robert, I really appreciate your time.  :)

No problem :)

Cheers,
Rob.
-- 
..
| InterJinn Application Framework - http://www.interjinn.com |
::
| An application and templating framework for PHP. Boasting  |
| a powerful, scalable system for accessing system services  |
| such as forms, properties, sessions, and caches. InterJinn |
| also provides an extremely flexible architecture for   |
| creating re-usable components quickly and easily.  |
`'

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Comparing strings... need advice. :)

2006-08-28 Thread Micky Hulse

Robert Cummings wrote:

Readfile works great, it's the same as file_get_contents() and then


Ah, good to hear.  :D


issuing an echo. You may want to also stored content generated by web
users outside of the web tree. There may not be any issue with how you
[...]
with PHP tags and accesses it directly from their browser... boom, same
security hole.


Ah! Yes, good idea.  :)

I think I will work this in to my script/system. Like I said, I am very 
concerned about security. I would have used a pre-built CMS like 
Textpattern or Wordpress, but the server I am on does not have database 
support.  :(


Anyway, many thanks for the tips Rob and all! You guys/gals rock!

Cheers,
Micky

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP] Comparing strings... need advice. :)

2006-08-27 Thread Micky Hulse

Hi,

I am looking for the most secure/efficient way to compare these two strings:

/folder1/folder2/folder3/folder4/
/folder1/folder2/folder3/folder4/file.php

Basically I am trying to setup as many security features as possible for 
a simplistic (home-grown/hand-coded) CMS...


This appears to work:

$haystack = '/folder1/folder2/folder3/folder4/someFileName.php';
$needle = '/folder1/folder2/folder3/folder4/';
if(substr_count($haystack, $needle) === 1) echo yea;

Before making changes to someFileName.php I want to make sure it is 
within the allowed path ($needle).


I would appreciate any advice. Even RTFM is cool.  :D

Many TIA,
Cheers,
Micky

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php