PHP removing backslash from code submitted through $_POST - php

I have a code editor block and and submitting code like the following:
$something = "Link";
However, when I submit it the string that gets output is missing the backslash escape characters and I get:
$something = "Link";
...which obviously isn't correct. I've figured out that it has to do with magic_quotes_gpc and when turned "On" works properly. My goal is for the application to be able to be installed easily on multiple hosts and I'd like to avoid having to turn on magic_quotes_gpc on every instance.

Link Here
Magic Quotes are depreciated and going
to be removed in PHP6. If you still
want your code to be portable, no
warnings etc, as of PHP52 you can use
the following code.
<?php
foreach ($_GET as $key => &$val)
$val = filter_input(INPUT_GET, $key);
foreach ($_POST as $key => &$val)
$val = filter_input(INPUT_POST, $key);
?>
The above will retrieve an-escaped
GETs and POSTs regardless system
settings. It can also be used for
$_COOKIES and others.

Try double escaping:
$something = "Link";

The addslashes()-method might be what you're looking for.
However, if you want to directly put those values in a Database, you can use the mysql_real_escape_string()-method or you go with a Prepared Statement.

Related

Strip Apostrophes from URL

[EDIT] I am placing the comment I entered near the bottom of this post to, hopefully avoid further down votes.
This was a pretty basic question stemming from my misunderstanding of what exactly $_REQUEST is. My understanding was that it was an index that referenced $_POST and $_GET (and $_COOKIE). However, I found that $_REQUEST is, itself, an array, so I simply changed the variables in $_REQUEST. Not an optimal solution, but a solution, nonetheless. It has the added advantage that the $_GET variables, with the apostrophes still there, are available. Perhaps not the best practice, but please note before you down vote that I have very little control over this data - coming in from one API and going out to another.
I have an API currently in use. We have a problem with some customers sending apostrophes in the URL. My question is how best to strip the apostrophes within the URL array. Perhaps using array_walk or something similar?
So that $_REQUEST[Customer] == "O'Henry's"
Becomes $_REQUEST[Customer] == "OHenrys"
EDIT: Judging from some of the answers here, I believe I need to explain a little better. This is an API that is already written and is the preliminary interface for another AS400 API. I have nothing to do with building the URL. I am receiving it. All I am concerned about is removing the apostrophes, without changing any other code. So the best way is to go through the array. In the body of the code, the variable references are all using $_REQUEST[]. I COULD go in and change those to $_GET[] if absolutely necessary but would rather avoid that.
This Works
foreach($_REQUEST as $idx => $val)
{
$_REQUEST[$idx] = str_replace("'" , '' , $val);
}
However, I am a little leery of using $_REQUEST in that manner. Does anyone see a problem with that. (Replacing $_REQUEST with $_GET does not work)
For some use cases, it might make sense to store a "clean" or "pretty" version of the name. In that case, you may want to standardize to a case and have a whitelist of characters rather than a blacklist consisting of just single quotes. Use a regex to enforce this, perhaps similar to this one:
preg_replace("/[^[:alnum:][:space:]]/u", '', $string);
If you do that, consider if it is necessary to differentiate between different customers named O'Henrys, O'Henry's, OHenrys, O'henry's, and so on. Make sure your constraints are enforced by the app and the database.
The array_walk_recursive function is a reasonable way to hit every item in an array:
function sanitize(&$item, $key)
{
if (is_string($item)) {
// apply whitelist constraints
}
}
array_walk_recursive($array, 'sanitize');
It's hard to tell without more context, but it seems possible you may be asking the wrong question / solving the wrong problem.
Remember that you can almost always escape "special" characters and render them a non-issue.
In an HTML context where a single quote might cause problems (such as an attribute value denoted by single quotes), escape for HTML using htmlspecialchars or a library-specific alternative:
<?php
// some stuff
$name = "O'Henry's";
?><a data-customer='<?=htmlspecialchars($name, ENT_QUOTES|ENT_HTML5);?>'>whatever</a><?php
// continue
For JavaScript, encode using json_encode:
<?php
// some stuff
$name = "O'Henry's";
?><script>
var a = <?=json_encode($name);?>
alert(a); // O'Henry's
</script>
For SQL, use PDO and a prepared statement:
$dbh = new PDO('mysql:host=localhost;dbname=whatever', $user, $pass);
$name = "O'Henry's";
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name) VALUES (:name)");
$stmt->bindParam(':name', $name);
$stmt->execute();
For use in a URL query string, use urlencode:
<?php
// some stuff
$name = "O'Henry's";
?>whatever<?php
// continue
For use in a URL query path use rawurlencode:
<?php
// some stuff
$name = "O'Henry's";
?>whatever<?php
// continue
Libraries and frameworks will provide additional ways to escape things in those and other contexts.
If you want them removing altogether as an illegal character:
<?php foreach($myArray as $idx => $val){
$myArray[$idx] = str_replace("'" , '' , $val);
}
?>
However this shouldn't be your solution to SQL Inserts etc.. Better off using mysqli::real_escape_string OR prepared statements
This was a pretty basic question stemming from my misunderstanding of what exactly $_REQUEST is. My understanding was that it was an index that referenced $_POST and $_GET (and $_COOKIE). However, I found that $_REQUEST is, itself, an array, so I simply changed the variables in $_REQUEST. Not an optimal solution, but a solution, nonetheless. It has the added advantage that the $_GET variables, with the apostrophes still there, are available. Not the best practice, though.
EDIT:
Reading the edits you made on your question, the best solution for you is str_replace(). But no need to loop through your array, the 3rd parameter can be an array !
This will strip apostrophes of every item in $foo:
$foo = [
"O'Henry's",
"D'Angleterre"
];
$foo = str_replace("'", "", $foo);
If you really need to remove the apostrophes use str_replace():
$foo = "O'Henry's";
$foo = str_replace("'", "", $foo);
// OUTPUT: OHenrys
If you can keep them, you better encode them. urlencode() may be a way to do:
$foo = urlencode($foo);
// OUTPUT: O%27Henry%27s
If you build this URL from an array you could use http_build_query():
$foo = [
'Customer' => "O'Henry's"
];
$foo = http_build_query($foo);
// OUTPUT: Customer=O%27Henry%27s

Confusion about mysql_real_escape_string and strip_slashes

I have users entering their name, as in: O'riley.
Before I enter this data into the MySQL DB, I run mysql_real_escape_string.
Problem is, when I then select this data for display and use later, it comes out as: O\'riley.
Obviously, this is the intended operation. What I'm wondering is if there's someway to be sure I can store it in the DB (still safely escaping possible malicious code), so that I don't have to use strip_slashes() on the output EVERY time I call the data throughout the entire web app? Or, am I missing something here?
Thanks.
UPDATE
Please refer to the comments in Deceze's answer.
No, it's not the intended operation to store the string as "O\'riley"; it should only be escaped in the query, but not stored this way. I'll guess that PHP puts in the backslash through Magic Quotes, and you escape it again to make it stick.
Disable Magic Quotes.
I personally always turn off magic quotes because it is doing something I haven't told it to do. If you dont have the ability to turn it off, consider including this code at the top of all of your pages.
if (get_magic_quotes_gpc()) {
function strip_array($var) {
return is_array($var)? array_map("strip_array", $var):stripslashes($var);
}
$_POST = strip_array($_POST);
$_SESSION = strip_array($_SESSION);
$_GET = strip_array($_GET);
}
If you have magic quotes disabled, and in the case that get_magic_quotes_gpc returned 1 and you did something like #Michael shows and this still occurs, magic quotes runtime may be enabled.
Magic quotes runtime will add slashes to strings when doing database queries and even when writing to files. To disable this in the currently executing script, do:
if(function_exists('get_magic_quotes_runtime') && get_magic_quotes_runtime())
{
set_magic_quotes_runtime(false);
}
You can also disable this configuration option through php.ini as well, if you can do so. However, if you can't disable it through php.ini permanently, you may need to add # before get_magic_quotes_runtime and set_magic_quotes_runtime as PHP may through E_DEPRECATED errors if error_reporting is set to log such errors (and this will get fairly annoying).
Alright, here's what you need to do. First, based on the comments, from other questions:
ISOLATE
You need to determine what is causing the problem. Is it the server? Is it some hidden code somewhere? What? Some programmers may include code like this on a configuration page:
<?php if (isset($_POST))
foreach ($_POST as $key => $value) $_POST[$key] = addslashes($value);
?>
So here are some checks to see if it is the server. This is about as solid a way of checking as possible. Create a NEW page. Leave it entirely blank and add this code:
<?php print_r($_POST); ?>
<form action="" method="POST">
<input type="text" name="test" value="O'riley" />
<input type="submit" name="submit" value="submit" />
</form>
Save it and load it in the browser. Hit submit. See if the slash is added still.
If it is still adding it, you need to troubleshoot your server / configuration. If it's a server you're paying for, you need to tell them to fix it or shove it. If it's your own server, then you're going to need to do some messing / googling to figure out how to turn off magic quotes.
If there are no quotes showing up, then there is definitely some code adding slashes to your post variables. It might not be as obvious as the code above, however. You need to run a search on your code for "addslashes", "mysql_real_escape_string", and possibly "str_replace". If you find one of these, you need to disable it. But be advised this may break other parts of your site that are assuming this action is taking place. You're other option for storing it in the database is to do a function similar to the code above, but instead, run stripslashes on it. Then you can run mysql_real_escape_string on it later. (A bit more unneeded overhead.)
Use
var_dump(get_magic_quotes_gpc());
somewhere near the actual use of the posted data to see if the Magic Quotes are really off.
Also some weird frameworks may add said quotes for you so grep your code for addslashes and other escape_string-like functions.
I would honestly suggest the use of PDO.
PDO employs the use of prepare and execute statements, which in turn adds security and removes some extra headache.
$pdo = new PDO();
$stm = $pdo->prepare('INSERT... (LastName) VALUES (:LastName)');
$stm->execute(array(':LastName' => "O'Rily"));
$stm->fetchAssoc(PDO::FETCH_ASSOC);
You no longer will need to worry about removing the escaping slashes as well as securing basic sql injection tactics.
It's possible magic quotes are turned on in your httpd.conf or in a virtual host declaration.
The exact location and file will depend on OS and distro. I'd check Apache configuration files for the php_flag setting.
Just use clean the data before inserting in to database,
function check_input($value)
{
if( get_magic_quotes_gpc() )
{
$value = stripslashes( $value );
}
//check if this function exists
if( function_exists( "mysql_real_escape_string" ) )
{
$value = mysql_real_escape_string( $value );
}
//for PHP version < 4.3.0 use addslashes
else
{
$value = addslashes( $value );
}
return $value;
}
$cleandata = check_input($value);
$sql = "INSERT INTO `table_name` SET `field_name`='".$cleandata."'";
While fetching the data and show into it use stripslashes($val)
Thank you everyone for the answers. I will award the +50 out, but I wanted to tell my real solution here, all which people did help with...
I was performing mysql_real_escape_string on all of the data AS SOON as it posted (before any processing). So, a slash was added to escape the ' character that was submitted. This, we know is normal.
However, there was no reason that the backslash \ should show up in the DB entry, right? The escape was there to be sure the ' was entered.
Turns out, AFTER escaping, I would then save the variable to be reloaded to the page in the session, in case the user had an error that PHP found while validating all of the form fields. In this case, the user's input (formerly O'riley was now printed to their screen as O\'riley. Then, the user didn't catch this - so they would often just fix their error that PHP caught during validation (unrelated to the name field), and thus the O\'riley would land in the database because mysql_real_escape_string would escape the characters.
Lesson:
When processing a form, FIRST save data for form-refill use. SECOND validate form fields. THIRD escape the data for processing into the database.
Or better yet, use PDO and avoid this =).
Comments welcome. THANKS ALL!

How to add mysql_real_escape_string to this code?

I am unsure as to how to add escape string to the $_POST['scan'] I used
$var = mysql_real_escape_string($_POST['scan']);
And then swapped it with the $_POST['scan'] in the code but it won't work. It just shows me blank screen.
foreach ($_POST['scan'] as $key => $value1) {
echo "$value1, ";
}
mysql_real_escape_string($str) is used for escaping SQL queries, not for displaying to the user. You may like to use htmlentities($str) or htmlspecialchars($str) instead.
try: print_r($_POST);
to see what you are getting in your post variables. Are you even passing an array via $_POST['scan'] or any data at all? As someone else alluded to, mysql_real_escape_string is to be used on a string prior to inserting into mysql, and hopefully after the string has been validated/sanitized.

PHP - magic quotes gpc and stripslashes question

Okay my hosting company has magic_quotes_gpc turned ON and I coded my PHP script using stripslashes() in preparation of this. But now the hosting company says its going to turn magic_quotes_gpc OFF and I was wondering what will happen now to my data now when stripslashes() is present should I go through all my millions of lines of code and get rid of stripslashes()? or leave the stripslashes() function alone? will leaving the stripslashes() ruin my data?
Your code should use get_magic_quotes_gpc to see if magic quotes are enabled, and only strip slashes if they are. You should run a block of code similar to the following in exactly one place, shared by all your scripts; if you're using stripslashes in multiple places you're doing it wrong.
// recursively strip slashes from an array
function stripslashes_r($array) {
foreach ($array as $key => $value) {
$array[$key] = is_array($value) ?
stripslashes_r($value) :
stripslashes($value);
}
return $array;
}
if (get_magic_quotes_gpc()) {
$_GET = stripslashes_r($_GET);
$_POST = stripslashes_r($_POST);
$_COOKIE = stripslashes_r($_COOKIE)
$_REQUEST = stripslashes_r($_REQUEST);
}
I would start going through and removing stripslashes(). You can do this ahead of time by testing for magic_quotes_gpc and only calling stripslahes() if it is needed.
meagar has the correct answer.
But to traverse the situation, you need something like Notepad++ with a Search within files function. Copy a snippet of meagar's code and search for stripslashes()

Baffled by PHP escaping of double-quotes in HTML forms

I have a simple PHP script I use to front-end an SQLite database. It's nothing fancy or complex. But I have noticed from looking at the records in the database that anything I enter in a form-field with double-quotes comes across in the form-processing as though I'd escaped the quotes with a backslash. So when I entered a record with the title:
British Light Utility Car 10HP "Tilly"
what shows up in the database is:
British Light Utility Car 10HP \"Tilly\"
I don't know where these are coming from, and what's worse, even using the following preg_replace doesn't seem to remove them:
$name = preg_replace('/\\"/', '"', $_REQUEST['kits_name']);
If I dump out $name, it still bears the unwanted \ characters.
You have most probably magic_quotes_gpc set to on in php.ini. If you want to avoid that and use your own regex, make a check like this:
if (get_magic_quotes_gpc())
{
$mytext = stripslashes($your_text);
}
// and your further code....
This means your server has magic_quotes_gpc enabled.
You can use ini_set() to disable this setting, or you can create a method to filter the $_REQUEST values()
function getRequest($key)
{
$val = $_REQUEST[$key];
if(get_magic_quotes_gpc() == 1) {
$val = stripslashes($val);
}
return $val;
}
echo getRequest('kits_name');
Is it possible magic quotes are enabled on the server?
You probably have magic quotes turned on.
You should disable these as it's bad practice and is deprecated.
View this doc to learn how to disable them.
Well because of lack of good answers.
As they said above, it is because magic quotes on.
You have to get rid of these slashes before inserting your data.
So, to get rid of it you can use either .htaccess (if any) with these settings
php_flag magic_quotes_gpc 0
php_flag magic_quotes_runtime 0
or make it manually, with code like this
if ( get_magic_quotes_gpc( ) ) {
$_GET = array_map_recursive('stripslashes', $_GET) ;
$_POST = array_map_recursive('stripslashes', $_POST) ;
$_COOKIE = array_map_recursive('stripslashes', $_COOKIE) ;
$_REQUEST = array_map_recursive('stripslashes', $_REQUEST) ;
if (isset($_SERVER['PHP_AUTH_USER'])) stripslashes($_SERVER['PHP_AUTH_USER']);
if (isset($_SERVER['PHP_AUTH_PW'])) stripslashes($_SERVER['PHP_AUTH_PW']);
}
if your php version doesn't support array_map_recursive function, you can use a recursive function like this one
function strips(&$el) {
if (is_array($el))
foreach($el as $k=>$v)
strips($el[$k]);
else $el = stripslashes($el);
}
or write your own one
You can use this code co cleanse your existing data
As for
If I dump out $name, it still bears
the unwanted \ characters.
it may be result of wrong use htmlspecialchars function

Categories