i use this code to export data from table ,but if its have url in db its give wrong format
ex {"site_url":"tiger","site_name":"hassan:\/\/tiger-sat.net\/nn.mp4"}
should be hassan://tiger-sat.net/nn.mp4
any know how to fix please ,,,
<?php
//PDO is a extension which defines a lightweight, consistent interface for accessing databases in PHP.
$db=new PDO('mysql:dbname=db;host=localhost;','root','pass');
//here prepare the query for analyzing, prepared statements use less resources and thus run faster
$row=$db->prepare('select * from channel');
$row->execute();
$json_data=array();
foreach($row as $rec)
{
$json_array ['site_url']=$rec ['site_url'];
$json_array['site_name']=$rec['site_name'];
//here pushing the values in to an array
array_push($json_data,$json_array);
}
//built in PHP function to encode the data in to JSON format
echo json_encode($json_data);
?>
It's not wrong . json_encode function is just escape the data and it's 100% valid and should not create any difference and it's even better to have escaped data. but in case you don't want to escape the data and have php > 5.4 or more you can use
echo json_encode($json_data, JSON_UNESCAPED_SLASHES);
instead.
But in case you have a php < 5.4 you can use the following code instead :
$encoded = json_encode($json_data);
$unescaped = preg_replace_callback('/\\\\u(\w{4})/', function ($matches) {
return html_entity_decode('&#x' . $matches[1] . ';', ENT_COMPAT, 'UTF-8');
}, $encoded);
echo $unescaped;
Another alternative is to use :
echo str_replace('\\/', '/', json_encode($json_data));
I would recommend to update your stack and get on a newer PHP version.
If your just needing to remove the extra slashes from the URL itself, then try stripslashes()
$example = 'hassan:\/\/tiger-sat.net\/nn.mp4';
echo stripslashes($example);
Result:
hassan://tiger-sat.net/nn.mp4
Another Option
$example = 'hassan:\/\/tiger-sat.net\/nn.mp4';
echo str_replace ( '\\' , '' , $example );
Result:
hassan://tiger-sat.net/nn.mp4
However, stripslashes does this exact same thing and would be the better option, it is what the function was made for, stripping backslashes..
If your needing to remove slashes throughout the whole JSON, then I would update PHP and use JSON_UNESCAPED_SLASHES.
You need to be careful if you aren't going to escape the slashes, they are there for a reason. If you are taking data from the JSON and using it in an SQL query, you could open yourself up to an SQL injection. So you would (and should) be using sanitized queries by using MySQLi or PDO, and prepared statements.
Depending on the use and need, I would not use JSON_UNESCAPED_SLASHES and strip the slashes when/where needed.
Last Note: preg_replace, and other forms of regular expressions, should be a last resort... Usually, they are for things way more trivial than simply removing a \ from strings. If you just need to remove a character (ie: ) then there are better ways than regular expressions.
Related
[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
Trying to save serialized string to SQL, but then i am having problems with unserializing it because of quotes.
Example, string is "te'st", after serialize we have
s:5:"te'st";
But to save it to SQL we need to add slashes, and i am doing
serialize(addslashes($string))
after this, in our MySQL db we have
s:6:"te'st";
And this is the problem. s:6 means we have 6 symbols string, but our "te'st" is only 5, so when we trying to unserialize it, we getting error.
How to solve it? Tried htmlspecialchars and mysql_real_escape_string
Update:
How i use mysql_real_escape_string
mysql_query("INSERT INTO `table`(`string`) VALUES ('" . serialize(array('iId' =>$aSqlResult['typeID'], 'sName' => mysql_real_escape_string($sScanResultLine))) . "')");
You should pass the data through the escape function after the serialization, not before - which is what you are doing now.
$serialized = mysql_real_escape_string(serialize($data));
Use a parameterised query with PDO or MySQLi and you can forget about the escaping altogether.
You're making a mistake I've seen many making. A bit of a fundamental misunderstanding of how escaping functions and should be used.
You cannot simply chain escape functions and end up with something that's perfect for any context. Your mistake is simple..
You're doing two things:
Serializing an object ( a string in this case )
Saving that into the database.
So before you save it to the database, you must make sure that your value is properly escaped. DO THIS WITH MYSQLI! The mysql_ functions are dead.
The equivalent is mysqli::real_escape_string.
But most importantly.. (sorry for dragging this on)..
serialize modifies the output, it can return a whole bunch of things.. quotes, 0x00's and this is not allowed in mysql queries.
So real_escape_string must obviously be the last step! First serialize, and the escape the output of that function. You did the exact opposite.
In your case the mysql_real_escape_string() is the way to go. It have to work, unless you did it somehow wrong (note: you need to be connected to DB before calling that function). And in fact you should use mysqli_ or PDO, not a mysql_ extension which is now deprecated. Using htmlspecialchars() is simply using wrong tool for the task.
Code should be like this:
mysql_real_escape_string( serialize( $string ) );
{$row['info']}
How do I use stripslashes() php function on this?
I've tried :
stripslashes({$row['info']}), doesnt work and this: {stripslashes($row['info'])}
Neither work.
Do I have to use a $var first??
Thanks
stripslashes returns the modified string, leaving its argument unchanged. You have to assign the result to a variable:
$var = stripslashes($row['info']);
That said, why are you doing this? You almost certainly shouldn't be. There is no reason to strip slashes on data coming from the database, unless you've double-escaped the slashes when the data was inserted.
Your question is somewhat confusing.
stripslashes() takes parameter and converts backslashed symbols to normal ones. more over, it does not affect the parameter. it returns stripped version.
so $result = stripslashes($source) or $row["info"] in your case.
$var = stripslashes($row['info']);
is more correct. Or in string, use it like this
echo "something".stripslashes($row['info'])." some more thingy";
It almost seems, that you are using heredoc syntax because of your {}. Question, is why? Are you seriously displaying your results like this?:
echo <<<my_results
Info: {$row['info']}
my_results;
Well, since that is cool way to do so then here is your fix:
$row_info = stripslashes($row['info']);
echo <<<my_results
Info: {$row_info}
my_results;
However, I do not recommend that approach. Rather do it like this:
echo 'Info:' . stripslashes($row['info']);
Because {stripslashes($row['info'])} doesn't work indeed and stripslashes({$row['info']}) is an anecdote!
I'm putting together a site, (we're already using javascript to prevalidate on the client side). However after getting tired of writing mysql_real_escape_string every other line. I wrote this class that only has two functions mainly focused on sanitising data in user-input/sql. My question is, what are ways to achieve easier input-sanitizing and while improving code readability?
<?php
class Safe {
function userinput($string){
$string = strip_tags($string);
$string = htmlspecialchars($string);
return $string;
}
function sql ($string){
$sqlstuff = Array("union", "select", "update", "delete", "outfile", "create");
$string = Safe::str($string);
$string = mysql_escape_string($string);
$string = str_ireplace($sqlstuff, "", $string);
return $string;
}
}
?>
Sorry, this is going to sound harsh, but your class is completely broken.
You should not be using htmlspecialchars for sanitizing input, it is only useful for escaping output. You do not need to encode HTML for insertion to the database nor should you. Only using htmlspecialchars when sending output to the browser
You should not be stripping tags from your input, you should be leaving them alone and again using htmlspecialchars when you output that data later to insure HTML tags are escaped and not interpreted by the browser
You should not be using mysql_escape_string or mysql_real_escape_string, you should be using PDO. If you are writing a new site there is absolutely no reason not to start out correctly and use PDO. Do it.
You should not be filtering out "union", "select", etc, that's dumb. Those words can appear in regular English language, and they're harmless if you're properly escaping quotes which PDO will handle for you.
Again, sorry for the harsh tone of this answer, but scrap the entire thing and use PDO. There is literally nothing salvageable here.
It's a good idea to use a class like that, particularily if it simplifies input handling. There's however a few points I'd like to comment on:
You should use mysql_real_escape_string instead of the PHP3 mysql_escape_string.
The first function should be called html or something. userinput sounds to vague and misrepresentative.
HTML escaping needs more parameters htmlspecialchars($str, ENT_QUOTES, "UTF-8") to be perfectly safe
The blacklisting of dangerous SQL keywords is not a good idea. It hints at a wrong approach to using SQL queries (if you receive queries via HTTP requests, that's your problem).
Also you should not attempt to filter them. Instead detected them, write to the error/security log, and die() immediately. If there is an attempt to circumvent security, there's no point in attempting any "cleaning" of the request.
You can also use filter_* functions that are bundled with PHP and provide you with the mechanism to filter request parameters according to specific filtering rules.
With few extra tricks, you could even filter arrays of different types of data (thanks to erisco!).
class sanitizer {
public function sanitizeValues($values, $filters) {
$defaultOptions=FILTER_FLAG_NO_ENCODE_QUOTES | FILTER_FLAG_STRIP_LOW | FILTER_NULL_ON_FAILURE;
$filters=(array)$filters;
$values=(array)$values;
foreach ($filters as $key => $filter) {
if($parts=explode('/', $key)){
$v=&$values;
foreach ($parts as $part){
$v=&$v[$part];
}
$filter=(array)$filter;
$filter[1]=isset($filter[1])?$filter[1]:$defaultOptions;
$v=filter_var($v, $filter[0], $filter[1]);
// consider if you really need this here instead of PDO
// $v=mysql_real_escape_string($v);
}
else{
$values[$key]=isset($values[$key]) ? filter_var($values[$key], $filter[0], $filter[1]) : null;
}
}
return $values;
}
}
$manager=sanitizer::sanitizeValues($_GET['manager'], array(
'manager/managerID'=>FILTER_VALIDATE_INT,
'manager/username'=>FILTER_SANITIZE_STRING,
'manager/name'=>FILTER_SANITIZE_STRING,
'manager/email'=>FILTER_SANITIZE_STRING,
'manager/phone'=>FILTER_SANITIZE_STRING,
'manager/bio'=>FILTER_SANITIZE_STRING,
'manager/enabled'=>FILTER_VALIDATE_BOOLEAN,
'manager/password'=>FILTER_SANITIZE_STRING));
This will produce an array complete with all the needed fields based on the 'manager' parameter in _GET, with all values filtered and, optionally, escaped.
I have one "go" script that fetches any other script requested and this is what I wrote to sanitize user input:
foreach ($_REQUEST as $key => $value){
if (get_magic_quotes_gpc())
$_REQUEST[$key] = mysql_real_escape_string(stripslashes($value));
else
$_REQUEST[$key] = mysql_real_escape_string($value);
}
I haven't seen anyone else use this approach. Is there any reason not to?
EDIT - amended for to work for arrays:
function mysql_escape($thing) {
if (is_array($thing)) {
$escaped = array();
foreach ($thing as $key => $value) {
$escaped[$key] = mysql_escape($value);
}
return $escaped;
}
// else
if (get_magic_quotes_gpc()) $thing = stripslashes($thing);
return mysql_real_escape_string($thing);
}
foreach ($_REQUEST as $key => $value){
$_REQUEST[$key] = mysql_escape($value);
}
I find it much better to escape the data at the time it is used, not on the way in. You might want to use that data in JSON, XML, Shell, MySQL, Curl, or HTML and each will have it's own way of escaping the data.
Lets have a quick review of WHY escaping is needed in different contexts:
If you are in a quote delimited string, you need to be able to escape the quotes.
If you are in xml, then you need to separate "content" from "markup"
If you are in SQL, you need to separate "commands" from "data"
If you are on the command line, you need to separate "commands" from "data"
This is a really basic aspect of computing in general. Because the syntax that delimits data can occur IN THE DATA, there needs to be a way to differentiate the DATA from the SYNTAX, hence, escaping.
In web programming, the common escaping cases are:
1. Outputting text into HTML
2. Outputting data into HTML attributes
3. Outputting HTML into HTML
4. Inserting data into Javascript
5. Inserting data into SQL
6. Inserting data into a shell command
Each one has a different security implications if handled incorrectly. THIS IS REALLY IMPORTANT! Let's review this in the context of PHP:
Text into HTML:
htmlspecialchars(...)
Data into HTML attributes
htmlspecialchars(..., ENT_QUOTES)
HTML into HTML
Use a library such as HTMLPurifier to ENSURE that only valid tags are present.
Data into Javascript
I prefer json_encode. If you are placing it in an attribute, you still need to use #2, such as
Inserting data into SQL
Each driver has an escape() function of some sort. It is best. If you are running in a normal latin1 character set, addslashes(...) is suitable. Don't forget the quotes AROUND the addslashes() call:
"INSERT INTO table1 SET field1 = '" . addslashes($data) . "'"
Data on the command line
escapeshellarg() and escapeshellcmd() -- read the manual
--
Take these to heart, and you will eliminate 95%* of common web security risks! (* a guess)
If you have arrays in your $_REQUEST their values won't be sanitized.
I've made and use this one:
<?php
function _clean($var){
$pattern = array("/0x27/","/%0a/","/%0A/","/%0d/","/%0D/","/0x3a/",
"/union/i","/concat/i","/delete/i","/truncate/i","/alter/i","/information_schema/i",
"/unhex/i","/load_file/i","/outfile/i","/0xbf27/");
$value = addslashes(preg_replace($pattern, "", $var));
return $value;
}
if(isset($_GET)){
foreach($_GET as $k => $v){
$_GET[$k] = _clean($v);
}
}
if(isset($_POST)){
foreach($_POST as $k => $v){
$_POST[$k] = _clean($v);
}
}
?>
Your approach tries to sanitize all the request data for insertion into the database, but what if you just wanted to output it? You will have unnecessary backslashes in your output. Also, escaping is not a good strategy to protect from SQL exceptions anyway. By using parametrized queries (e.g. in PDO or in MySQLi) you "pass" the problem of escaping to the abstraction layer.
Apart from the lack of recursion into arrays and the unnecessary escaping of, say, integers, this approach encodes data for use in an SQL statement before sanitization. mysql_real_escape_string() escapes data, it doesn't sanitize it -- escaping and sanitizing aren't the same thing.
Sanitization is the task many PHP scripts have of scrutinizing input data for acceptability before using it. I think this is better done on data that hasn't been escaped. I generally don't escape data until it goes into the SQL. Those who prefer to use Prepared Statements achieve the same that way.
One more thing: If input data can include utf8 strings, it seems these ought to be validated before escaping. I often use a recursive utf8 cleaner on $_POST before sanitization.