Add php function to all POSTs and REQUESTs variables - php

I have a very old client who is now having issues with security because of the MYSQL Injection. This client does not have enough money to change his PHP database functions to PDO or MYSQLI. Nevertheless, he suggested that he wants a function that prevents mysql injuction. He is fully aware that the function is not perfect. But, he does not have any other temporary way right now. the function that I wrote for him is called safe();. Here comes my question. How can I apply the function to all POSTs and REQUESTs in his site. His site has many files, it will take hours to change. is there anything that I can add in the Header of every file that applies my function to all POSTs and REQUESTs variables?
something that maybe looks like this :
$_POST[*] = safe($_POST[*]);
Of course, the above code does not work. but I hope you get the idea.

You can use array_map, but I doubt it'll be perfect solution:
$final = array_map( "mysql_real_escape_string", $_POST );

In the end $_POST and $_GET are just arrays.
You could do a foreach like
foreach ($_POST as $key => $value) {
safe($value);
}
if they have old php servers etc. So if you have a general file that is included over the whole website and the "normal" functions aren't an option, this could be the back-up plan.

You are describing the infamous Magic Quotes, which are still available if the server is older than PHP/5.4.0 (which I presume is the case).
Please note that they affect all POST data, including that which is not going to be injected in a SQL query.
If you prefer your safe() function, you can simply write a simple script that makes the change and call it via auto_prepend_file.

Possible duplicate of https://stackoverflow.com/questions/15664021/php-escaping-vars-posted-through-var-and-got-by-postvari-with-a-meth
As I was told, there's no universal method, but you can give it a try through foreaching the $_POST array

Related

How can I parse multipart/form-data from an HTTP PUT request into an associative array in PHP?

I'm trying to write a REST API in PHP from the ground up for my website, partly as a learning exercise, partly to develop a codebase that I can reference later in case I forget how something works.
To my dismay, I've discovered that PHP has no $_PUT superglobal.
Remembering that Laravel makes GET/PUT/POST/DELETE distinctions, I figured Laravel must have code to handle HTTP PUT requests correcly, but no, in fact, it depends on a hidden form field with the value "_PUT" to specify the action to take.
Without the need to process files, is there any way to take multipart/form-data and parse it into an associative array in a similar fashion to $_POST, such that it is foreach iterable?
Here is what I tried and it simply doesn't work. I'm not understanding what the extra data is that is sent, must be related to the PHP session?
parse_str(file_get_contents("php://input"), $_PUT);
foreach ($_PUT as $key => $value)
{
unset($_PUT[$key]);
$_PUT[str_replace('amp;', '', $key)] = $value;
}
$_REQUEST = array_merge($_REQUEST, $_PUT);
foreach($_PUT as $key=>$value){
$ani->state[$key]['value'] = $value;
}
What I end up getting out of this looks like this: (I am pretty sure I can beat this into what I want, but I don't think what I come up with is going to be robust enough to trust not to break all the time.)
So as not to anger anyone, the code I'm using came directly from here: https://joshtronic.com/2014/06/01/how-to-process-put-requests-with-php/
I tried to spin my own, which ended up looking very similar to his, minus merging the body back into the request, which I still don't completely understand the purpose of.
My solution is now simply to not use multipart/form-data and instead use application/x-www-form-urlencoded. I don't know if this decision will haunt me later on down the road but it solves my problem for now. I can still use this for my API as in JavaScript I can specify the content type as such:
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
I'd be very interested in knowing why PHP doesn't add a $_PUT superglobal?

What is the correct (safe) alternative to PHP import_request_variables?

Full disclosure: I'm not a PHP programmer, rather a Javascript/Node programmer, but I'm trying to help a friend fix a fatal PHP error on their site.
To wit,
Fatal error: Call to undefined function import_request_variables()
I've looked it up and import_request_variables() is deprecated.
The relevant piece of code is this -- I noticed that the developer seems to have tried out the more modern form (?) and abandoned it.
import_request_variables("pgc", "re_");
//extract($_GET, EXTR_PREFIX_ALL, "pgc");
//extract($_POST, EXTR_PREFIX_ALL, "pgc");
//extract($_GET, EXTR_PREFIX_ALL, "re_");
//extract($_POST, EXTR_PREFIX_ALL, "re_");
I found a solution on Stack Overflow here Php import_request_variable stopped working, that suggests using that same extract method
extract($_GET, EXTR_PREFIX_ALL, 'p');
extract($_POST, EXTR_PREFIX_ALL, 'p');
Is this the correct method to follow? I've read in other posts (e.g. here) that this could lead to security errors, as does the PHP documentation here
Warning
Do not use extract() on untrusted data, like user input (e.g. $_GET, $_FILES).
and that it's best to import the variables specifically, but I'm not sure that I'm adept enough at PHP to go through all the code and figure out where each variable is being used...
What's the best way to solve this issue swiftly and securely?
Thanks for any help!
EDIT:
This is the code where the variables are used, for what it's worth
if ($re_sub && $re_sec) { $content="./$re_sec/$re_sub.php";}
else if ($re_sec) { $content="./$re_sec/index.php";}
else { $content="./home.php";}
Wow. import_request_variables went away in PHP5, that was a LONG time ago... hope you are upgrading to 7!
Anyway, it seems that you are basically trying to form POST and the content of the post determine the URL the user is sent to. Since you can't trust user input (or shouldn't anyway) you check what is sent in the $_POST array against a whitelist. Depending on how many sections and sub-sections you have, that whitelist can be hard coded, kept in a separate include file, stored in a database, etc.
Given a structure like
home
sec1
sec1sub1
sec1sub2
sec1sub3
sec2
sec2sub1
sec2sub2
sec2sub3
sec3
sec3sub1
sec3sub2
sec3sub3
You can do something like loop through your whitelist and see if a matching POST variable was sent, if so add it to the URL.
$url="/";
$whitelist=array();
$whitelist['cars']=array("compact","sedan","sportscar");
$whitelist['trucks']=array("diesel","4x4");
$whitelist['suvs']=array("crossovers","domestic","import");
foreach($whitelist as $k=>$v){
if(isset($_POST[$k])){
$url=$url."/".$k;
foreach($v as $subv){
if(isset($_POST[$subv])){
$url=$url."/".$subv;
}
}
}
}
header("location :".$url);

Joomla: correct way to sanitize file data

I am writing import script from csv files and I need to validate data, most of the data is strings so I want to use something like Jinput to sanitize it.
Is there is something Joomla already have for this purpose?
It would be ideal to have something like
$field = JSanitizer::get($data/*array with data*/, "fieldname"/*name of field*/,
'string'/*type of data*/, 'null'/*default value*/);
Also I would need it to work both in Joomla 2.5 and 3.0 versions.
You are probably looking for JFilterInput::clean() This would work as follows:
$field = JFilterInput::clean($data[$fieldname], 'filter');
This does not give a way to set a default value, so you would have to handle that afterwards. This should be the same filtering that is typically done with JInput as well as on JForm elements if you write custom components.
I can't seem to find a good list of all the filters, but you can see an old version of the source here: http://docs.joomla.org/API16:JFilterInput/clean. Most recent version of the function starts at line 162 here: https://github.com/joomla/joomla-cms/blob/master/libraries/joomla/filter/input.php
Note also that you want to pull the field out of the data array yourself. You can actually send it the entire array without a filter setting and it should at least check the entire array for XSS and other issues. If you want more nuanced filtering for integers and such, it would best to do it field by field.
$field = JFilterInput::clean($data[$fieldname], 'filter');
will fire a notice
"Non-static method JFilterInput::clean() should not be called statically"
You should initiate this with JFilterInput::getInstance() first and call it dynamically e.g.:
$field = JFilterInput::getInstance()->clean($data[$fieldname], 'filter');
Tom
You should read Joomla docs and use something like this before parsing file : $string = JRequest::getString( 'description' );
This should work across all version since 1.5
There has been some github projects to implement html purifier as plugin, i found this, but havent chance to tested it, but it should work though.

Formatting the POST array to an SQL insert\update string in codeigniter 2

I'm trying to automate form creation and submission in codeigniter.
Basically what I want is to find a way to go over all the data in the POST array and format it correctly to an insert or update sql query.
The problem is I don't know how to access to whole POST array in CI, all I know of is the $this->input->post(field_name) way which only gives you a specific field.
Ideally I would want to send the POST array to the $this->db->insert_string() or $this->db->update_string() to do the job for me.
I know I can still use the php native $_POST array, but this is not recommended and not as secure as CI's input class.
Anyone know a way to do this?
Thanks,
Amos
Eventually I found out that the input class cleans the $_POST array automatically (not talking about XSS cleaning) and so the only advantage to use $this->input->post(something) is that it checks if that key exists.
Since I need the whole array I don't need that check and can safely use $this->db->insert_string($_POST).
If I you do want XSS cleaning you can either turn it on globally in the config or use geocine's answer (I would go for a mix of the 2 examples he gave).
Another way to go if you want the whole array with XSS cleaning and without it turned on globally is to go with WanWizard's Input library extension found here: http://codeigniter.com/forums/viewthread/172705/#821150
foreach($_POST as $key => $value) {
$value = $this->input->post($key);
//do something
}
or
$keys = array_keys($_POST);
for($i=0,$max=count($keys);$i<=$max;$i++)
{
$value = $this->input->xss_clean($_POST[$keys[$i]]);
//do something
}

How does one script call another?

Suppose you have access to a script which will print or echo an ID string, given a name string, i.e., something like:
http://www.example.com/script.php?name=aNameString
outputing an ID string.
I want to create a script which will allow me to retrieve anIDString, given that I already have a variable holding aNameString, i.e., something like this pseudocode:
$name="Homer Simpson";
$id='www.example.com/script.php?name=$name';
Can you help me understand how I'd do this? ... Thanks, as always!
If you are writing code on the same domain, for security reasons you might consider the include() or require() functions instead, and implementing what you need as a function in php. This way, there is no risk to your server being fed rubbish data and crashing your application.
If you need to pull data from another script do so with care, especially a server that isn't trusted. That said, you can do it with either: http://uk.php.net/curl or http://us2.php.net/manual/en/function.file-get-contents.php, the latter of which looks easier to me.
Try requiring the file, but remember, you'll need to call the function later.
<?php
$name = 'Homer Simpson';
require 'script.php';
?>
That will make the global variable $name, accessible by script.php
However, if it isn't your server, you will need to use a tool like curl to fetch the page.
In the simplest case, you can use the HTTP wrappers to get the output:
$html = file_get_contents('http://www.example.com/script.php?name=aNameString');
and them take the $html apart, unless you meant something different by "outputing an ID string", it output raw text and not html.

Categories