How to add backslash next to php magic constants? - php

I'm trying to check if file exists or not. I tried simple http URL for the task but file_exists() does not support (my php version is 5.5.12 and allow url fopen is activated ).
So i tried in different way and its working, see below
if(file_exists(__DIR__.'\email_template.php')) {
echo 'Template is available.';
}
Problem is that i'm adding template name dynamically and i need backslash between __DIR__ and $temp_name but i can't concatenate properly. I tried below
$__DIR = __DIR__.'\';
$__DIR = __DIR__.'"\"';
$__DIR = __DIR__."\";
But no one is working, its return syntac error. So can anyone guide me how can i fix the issue i would like to appreciate. Thank you

Try this:
$__DIR = __DIR__.'\\';
Backshlash is special char in PHP (and other languages as well), that is used for noting that chars after them should be interpreted in special way - and is named "escape char".
You do not want this to happen, so You should escape backshlas... By using one more backshlash. ;)
You can read more here.

Another option is to use the pre-defined constant DIRECTORY_SEPARATOR.
$__DIR = __DIR__ . DIRECTORY_SEPARATOR;
This way your code is more portable between operating systems, which may or may not be of concern to you.

Related

PHP str_replace not replacing a windows path string correctly

$search = 'C:\xampp1.7.7\htdocs\myproject\uploads/files/temp-ds-original';
$subject = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg';
echo str_replace($search, '', $subject);
It just prints $subject without doing any replacements. I thought it could be due to some php version issue as it was on a php 5.3 but then I moved to php 7.2 but still the same result. Not sure what's going wrong here?
Is it something to do with the slashes?
I have hardcoded string values above but in the actual script, I am using $f->getRealPath() to get subject and search. $f is an object of RecursiveIteratorIterator
EDIT
As soon as I posted this question, I could spot the issue as code highlighting made it quite clearer to see that slashes don't match - which means str_replace considers it a non-match. What I am trying to achieve is get relative path which in above example is \32bd76470cff973ec873d43a4e84dd2f.jpg ... the code is here at line 48 https://gist.github.com/bubba-h57/5117694
The above output is on a Windows machine but I will be using this script later on a Linux server. So I need to think about how to get the paths consistent so that str_replace can do the replacement correctly. $search is something I provide manually where $subject is being retrieved automatically using $f->getRealPath().
Update and Answer of my question
I don't believe this question is duplicate to the linked question. People are quick here to show off their skills without paying due attention to details. :)
It turned out to be a simple solution. All I need to do is use realpath() i.e. $search = realpath($search); which gives me the correct result.
Just so that it helps anyone -
$search = 'C:\xampp1.7.7\htdocs\myproject\uploads/files/temp-ds-original';
$subject = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg';
echo str_replace($search, '', $subject);
Output was:
C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original\32bd76470cff973ec873d43a4e84dd2f.jpg
However I was expecting to be:
\32bd76470cff973ec873d43a4e84dd2f.jpg
I failed to notice the slashes mismatch and therefore str_replace was not at fault at. Importantly, I wasn't trying to get the filename only which I could get from basename() or other methods so I needed to get the slashes right.
All I needed to was to use PHP's realpath() i.e.
$search = realpath($search);
That's it. However, you need to be careful that it only worked for me because I was parsing an actual path i.e. the folder in the $search existed on the disk. So, if you tried to parse a path string which is dummy or not a real directory, realpath() would return empty or false.
you have to do this
you have to use doble backslash if you use only one dont work !
result:
You could just use the same search always
(eg: $search = 'C:\xampp1.7.7\htdocs\myproject\uploads\files\temp-ds-original';)
then change the subject's slashes by using str_replace('/','\',$subject);
Or you could detect the OS and then use the matching $search
You can do this by checking the PHP Constant PHP_OS (Documentation in the link)
I hope that solves it.

Which special characters can cause a file path to be misinterpreted?

For example, there is function (pseudo code):
if ($_GET['path'] ENDS with .mp3 extension) { read($_GET['path']); }
but is it possible, that hacker in a some way, used a special symbol/method, i.e.:
path=file.php^example.mp3
or
path=file.php+example.mp3
or etc...
if something such symbol exists in php, as after that symbol, everything was ignored, and PHP tried to open file.php..
p.s. DONT POST ANSWERS about PROTECTION! I NEED TO KNOW IF THIS CODE can be bypassed, as I AM TO REPORT MANY SCRIPTS for this issue (if this is really an issue).
if something such symbol exists in php, as after that symbol, everything was ignored, and PHP tried to open file.php..
Yes, such a symbol exists; it is called the 'null byte' ("\0").
Because in C (the language used to write the PHP engine) the end of a 'string' is signalled by the null byte. So, whenever a null byte is encountered, the string will end.
If you want the string to end with .mp3 you should manually append it.
Having said that, it is, generally speaking, a very bad idea to accept a user supplied path from a security standpoint (and I believe you are interested in the security aspect of this, because you originally posted this question on security.SE).
Consider the situation where:
$_GET['path'] = "../../../../../etc/passwd\0";
or a variation on this theme.
The leading concept in programming is "Don't trust user input". So the main problem in your case is not a special character its how you work with your data. So you shouldn't use a path given by a user because the user can manipulate the path or other variables.
To escape a user input to prevent bad characters you can use htmlspecialchars or you can filter your get input with filter_input something like that:
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
WE CAN'T TELL IF YOU IF THE CODE CAN BE "BYPASSED" BECAUSE YOU'VE NOT GIVEN US ANY PHP CODE
As to the question of whether its possible to trick PHP into processing a file it shouldn't based on the end of the string, then the answer is only if there is another file somewhere else which has the same ending. However, by default, PHP will happily read from URLs using the same functionality as reading from local files, consider:
http://yourserver.com/yourscript.php?path=http%3A%2F%2Fevilserver.com%2Fpwnd_php.txt%3Ffake_end%3Dmp3

How to get pg_escape_literal on PHP 5.3?

I am developing some project, where I have postgre database. PHP is 5.3 (cannot be updated, because it is quite big webpage), so pg_escape_literal is not supported. I google everything about it, but didn't find anything interesting - couldn't find some PHP escape_literal function. I also tried pg_escape_string, but as far as I tested it, it doesn't work (when I printed whole string, escaped by pg_escape_string, it shows some slashes, which broke sql statement, and any removal with functions didn't work).
EDIT: I found this, but I don't know if this is really just what escape_literal does -
https://searchcode.com/codesearch/view/11003494/
pg_escape_literal($dbcnx, $string) should be equivalent to:
"'" . pg_escape_string($dbcnx, $string) . "'"

PHP Parse INI File gives me error about equal sign

I'm trying to parse out an INI file that has a URL as one of the variables to parse. Problem is, the URL contains a '=' in it, and parse_ini_file spits out an error. I tried to escape the character, but to no avail. Does this happen to anybody else? And if so, has anybody fixed it?
Have you enclosed the value in quotes? It shouldn't be a problem to have = in the value as long as you have quotes around your value. Example:
key1="http://www.google.com?q=test";
much better would be use INI_SCANNER_RAW as 3rd parameter of parse_ini_file
parse_ini_file($file, true, INI_SCANNER_RAW);
I had the same problem and it drove me insane! The problem ended up being something silly ... I had created the .ini file in Windows, using a file that I renamed to .ini. Apparently there was some markup left which was seen by PHP, but not in my Notepad++.
I deleted the .ini and created one on my Linux host. This resolved the problem. If you're using WAMP or XAMPP on Windows, try to create a new file with just notepad, which disregards any markup.
I know this is an old topic, but I ended up here looking for the same problem, so it might help someone else.
Here is a quick solution to fix parse_ini_* problems with equality sign. You can use also regex, exploding arrays, etc.
function parseIniFile($file) {
if (!is_file($file)) return null;
$iniFileContent = file_get_contents($file);
return parseIniString($iniFileContent);
}
/* solves the equalitiy sign problem */
function parseIniString($iniFileContent==''){
$iniArray = array();
$iniFileContentArray = explode("\n", $iniFileContent);
foreach ($iniFileContentArray as $iniFileContentArrayRow){
$iniArrayKey = substr($iniFileContentArrayRow, 0, strpos($iniFileContentArrayRow, '='));
$iniArrayValue = substr($iniFileContentArrayRow, (strpos($iniFileContentArrayRow, '=')+1));
$iniArray[$iniArrayKey] = $iniArrayValue;
}
return $iniArray;
}

is_file($_GET) and security

I'm using this code on top of my PHP file for loading cached files and I'm worried whether it's secure enough:
//quick! load from cache if exists!
if (is_file('cache/'.($cachefile=basename('/',$_GET['f']))))
{
header('content-type: text/css');
require('cache/'.$cachefile);
die(); //ALL OK, loaded from cache
}
EDIT: I would also like to know if it isn't, how is it exploitable and how to rewrite it in safe manner.
EDIT 2: I edited code, from previous code, I don't know how I could thought that is_file will filter bad paths >.<
EDIT 3: Changed it again, so it uses basename() instead of end(explode()) and also changed inclusion from repeating the code into assigning the value into variable during first comparison (or file check).
I never just include($_GET), but today, I somehow thought is_file will filter out paths, that may harm my system. I don't know how.
Thank you
I could send $_GET['f'] = '../../database_passwords.xml' ...
Use basename to eliminate anything but the last segment of the passed path. Alternatively, construct the path, then compute the absolute path that corresponds and check if it's still within cache/.
BAD!
What about:
page.php?f=../../../../../etc/password
Never do such things
Check f against a white list or specific pattern like "[a-z]+.php"
No it isn't. I could put '../../anypath' in $_GET['f'] and gain access to any file on your server, even those outside your www root.
[edit]
It would be a lot safer if you would check for '/' and other invalid characters in the value. It is pretty safe if that filename only contains alphanumeric characters and . and _.

Categories