Suppose, I have a variable $var1 which contains the followings:
$var1="../sidebar_items/uploaded_files/notices/circular.pdf";
Now, I want to create another variable $var2 which will hold the following value:
$var2="../dev/sidebar_items/uploaded_files/notices/circular.pdf";
I want to create $var2 with the help of $var1 via string manipulation. Is it possible to do so? How will I achieve that?
Just use str_replace(). It returns the changed string but doesn't change the original variable so you can store the result in a new variable:
$var2 = str_replace('../', '../dev/', $var1);
It looks like you're allowing users to upload files and saving the filenames. That's potentially very dangerous depending on how you're dealing with them; if you are taking their string value and doing file system operations against it, you could end up with a user uploading a file with a name like ../../../../../usr/bin/php and risking allowing a delete operation against that file (if your permissions are set up really, really poorly) or, perhaps more realistically, using path manipulation to delete, modify, or overwrite any file owned by the web server user. index.php would be an obvious target.
You should consider keeping both paths in separate constants rather than using string manipulation to turn one into the other at runtime. You should also consider renaming user-uploaded files, or at least being very careful about how you store them with regard to naming based on how you access them in your code.
you could also use strtr() function of PHP
$var2 = strtr($var1, '../', '../dev/');
I'd approach it by separating out the file name using basename() and then having a variable which has the path to the dev directory. This allows you to change it to all sorts rather than limiting it to a minor change...
$var1="../sidebar_items/uploaded_files/notices/circular.pdf";
$devpath = "../dev/sidebar_items/uploaded_files/notices/";
echo $devpath.basename($var1);
gives...
../dev/sidebar_items/uploaded_files/notices/circular.pdf
Related
Why use basename() in PHP scripts if what this function is actually doing may be written in 2 lines:
$subFolders = preg_split("!\\\|\\/!ui", $path); // explode on `\` or `/`
$name = array_pop($subFolder); // extract last element's value (filename)
Am I missing something?
However I guess this code above may not work correctly if file name has some \ or / in it. But that's not possible, right?
PHP may run on many different systems with many different filesystems and naming conventions. Using a function like basename() guarantees (or at least, is supposed to guarantee) a correct result regardless of the platform. This increases the code's portability.
Also, compare a simple basename() call to your code - which is more readable, and more obvious to other programmers in regards to what it is supposed to do?
basically what i want to do is:
include($_SERVER['REQUEST_URI']);
Problem is, that this is not safe.
It would be safe, if it would point to "/allowed/directory/" or it's subdirectories.
So i test for that with startsWith("/allowed/directory/").
However I'm still afraid of something like:
"allowed/directory/../../bad/directory"
Is there a way to check whether a string points to a specific directory or one of it's subdirectories in php?
(Basically apply all the /../ - or am i missing another security flaw?)
PHP function realpath() should remove the ../ /// from the path.
Though you are right, this can be a fairly dangerous operation. IMO the paths should be restricted to a known set of characters (like "a-zA-Z_" and / ). Also, path strings should be limited to a known size (like 256 chars).
Once you've determined the prefix is correct, you can use preg_match like this:
if(preg_match("#^[A-Za-z0-9/]+#", $string) {
// correct
}
else {
// incorrect
}
The variable part you're checking (non-static part) you typically want to be just alpha numeric.
As long as you're using include to include local PHP fils and properly validate your input (keeping that input simple) you should be fine. Just be extremely careful and test things throughly. You typically want to avoid passing user input into sensitive functions such as include. But with a framework, it's sometimes difficult to avoid that.
Another thing you could do is have a list of valid inputs to do an exact comparison. You could have this in an ini file and load it with parse_ini_file. This is usually the safest thing to do, just a little more work. You can also use a PHP file with an array, which works better with APC.
Firstly - some background. We have a config.php file which lists several variables and settings in this format:
$MY_EMAIL_ADDRESS = 'test#test.com';
$MY_WEBSITE = 'www.test.com';
$SOMETHING_ELSE = 'foobar';
I would like to replace them with more sensible (and secure) names as part of an array, throughout the entire PHP project. Mostly so we can do this more securely: Get PHP variable value via Ajax with variable name as parameter
We have also forgotten some of these variables names, so that they are used throughout the project, but possibly not documented - hence doing a search one-by-one will prove difficult.
Is there a way I can search the php files for any values that start with a dollar sign ($) and then are made up of only upper case letters and possibly underscores?
$MY_SETTING_NAME
We could then either build a list and update manually, or build some kind of script to replace things with a more sensible way of working:
$CONFIG['MY_SETTING_NAME']
Thank you!
You can use get_defined_vars function which will return all variables as array.
Please look at php.net website for example
I know finding alternatives to eval() is a common topic, but I'm trying to do something I've not done before. I am processing known-format CSV files, and I have built rules for how the data will be handled depending on the source columns available.
Here is a simplified example of what I'm doing. In this example, $linedata represents a single row of data from the CSV file. $key["type"] points to the column I need the data from. If this column holds the value of "IN", I want $newcol set to "individual", else "organization".
$key["type"] = 12;
$linedata[12] = 'IN';
$rule = '($linedata[($key["type"])] == "IN" ? "individual" : "organization");';
eval ('$newcol = ' . $rule);
So $rule stores the logic. I can run a filter on the $linedata array to try and protect from malicious code coming from the CSV files, but I wonder if there is a better way to store and process rules like this?
You cannot store arbitrary PHP in a CSV file and then expect it to work without calling eval (or similar functionality).
The safe way to do what you're asking for is to treat the file as data, not code.
This is why languages like BBCode exist: you can't have an inert language trigger active features directly, so you create an easy-to-interpret mini-scripting-language that lets you achieve what you want.
In other words, you cannot store active "rules" in the file without interpreting them somehow, and you cannot simultaneously allow them to contain arbitrary PHP and be "safe". So you can either attempt to parse and restrict PHP (don't, it's tough!) or you can give them a nice easy little language, and interpret that. Or, better yet, don't store logic in data files.
I was wrong.
I can be wrong, however create_function may be good enough.
http://www.php.net/manual/en/function.create-function.php
I would like to know if I can use a gt function on a variable with php?
eg. : echo _($var);
Feel free to. But you need to make sure the possible contents of the variable makes it into .po/.mo files. (one of the ways to do assure it is to create a dummy file never processed except for by xgettext, containing _("translate me"); expressions).
I don't think gettext will recognize a variable since it scans the source code. If you want to include variables in a string, it's better to use
sprintf()
For example
echo sprintf(_("There are %d results!"), $numResults);
In gettext, the translator will see
There are %d results!
so therefore it can easily be translated as long as he/she knows that %d is a variable. When the script gets executed, gettext will first replace the translation, and then sprintf will insert the variable $numResults. Good luck! I just got done internationalizing my site.