PHP; encode and decode functions produce the same output - php

Sanitising some user input;
function html_mysql_sanitise($data) {
if(get_magic_quotes_gpc()) {
$data = stripslashes($data);
}
$data = htmlentities($data, ENT_QUOTES);
$data = htmlspecialchars($data, ENT_QUOTES);
return mysql_real_escape_string($data);
}
$_POST['data'] = html_mysql_sanitise($_POST['data']);
echo $_POST['data'];
echo html_entity_decode(htmlspecialchars_decode($_POST['data']));
echo html_entity_decode($_POST['data'], ENT_NOQUOTES);
echo htmlspecialchars_decode($_POST['data'], ENT_NOQUOTES);
$_POST['data'] is set to;
test<d#'!;ta>
The output of this is;
test<d#'!;ta>
test
test<d#'!;ta>
test<d#'!;ta>
Why do the last two produce the same result, and the 2nd one is part of the posted data? Since the last two seem to produce the desired result, which should I use?
Thank you.

Why re-invent the wheel... use this:
http://htmlpurifier.org/docs
Or this:
http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/index.php
Both good at exactly what you want to do.

Related

Prevent an link becoming double encoded in PHP

I have the following URL in a MySQL database for a PHP application - part of our system allows a user to edit their previous post with these links and save - however as the url gets encoded again when a user edits this is then breaks the url as displayed below.
Is there an easy way or existing PHP function to determine if the string already has been encoded and to alter the string to remove the unwanted characters so it remains in the expected output below.
Expected output
url:https://r5uy4lmtdqka6a1rzyexlusfl-902rjcrzfe6k93co7a644-tom.s3.eu-west-2.amazonaws.com/Carbon%20Monoxide/Summer%20CO%20Campaign/CO%20Summer%202022/CO%20Summer%20you%20can%20smell%20the%20BBQ%20-%20600x600.jpg
Actual output
url:https://r5uy4lmtdqka6a1rzyexlusfl-902rjcrzfe6k93co7a644-tom.s3.eu-west-2.amazonaws.com/Carbon%2520Monoxide/Summer%2520CO%2520Campaign/CO%2520Summer%25202022/CO%2520Summer%2520you%2520can%2520smell%2520the%2520BBQ%2520-%2520600x600.jpg
As suggested in comments, double decode, then encode (only the query string part).
<?php
$str = "https://r5uy4lmtdqka6a1rzyexlusfl-902rjcrzfe6k93co7a644-tom.s3.eu-west-2.amazonaws.com/Carbon%2520Monoxide/Summer%2520CO%2520Campaign/CO%2520Summer%25202022/CO%2520Summer%2520you%2520can%2520smell%2520the%2520BBQ%2520-%2520600x600.jpg";
$str = "https://r5uy4lmtdqka6a1rzyexlusfl-902rjcrzfe6k93co7a644-tom.s3.eu-west-2.amazonaws.com/Carbon%20Monoxide/Summer%20CO%20Campaign/CO%20Summer%202022/CO%20Summer%20you%20can%20smell%20the%20BBQ%20-%20600x600.jpg";
function fix_url($str)
{
$arr = explode('/', $str, 4);
$qs = $arr[3]; // add if at all check?
while (true) {
$decoded = urldecode($qs);
if ($decoded == $qs) {
break;
}
$qs = $decoded;
}
$encoded = urlencode($decoded);
$result = $arr[0] . '//' . $arr[2] . $encoded;
return $result;
}
echo fix_url($str);

do I need to sanitize input displayed to the user?

I'm learning about making my site more secure and am using mysqli's escape function to sanitize input going into SQL queries and am using htmlspecialchars() on input coming from the database (or get/post requests) echoing out onto the page.
But, any text coming from the database to display to the user looks bad because certain characters are escaped with slashes and it shows <br /> or \r\n instead of doing a line break. I can strip the slashes, of course, but shouldn't the mysqli string escape function change the escaped characters back once it is put into the database?
Am I not supposed to use htmlspecialchars to sanitize output being displayed to the user? Or should this not be happening (in which case there must be something weird going on to the data going in)?
I still want line breaks so I'm having to do a string replace. I made the function below as a replacement for just htmlspecialchars(). But I'm not seeing anything about having to do this online anywhere so I'm afraid maybe I'm doing something wrong. :-/
function display($data) {
$new = str_replace('\r\n',"<br />",$data);
$new = str_replace('\n',"<br />",$new);
$new = str_replace('\r',"<br />",$new);
$new = stripslashes($new);
$newer = htmlspecialchars($new);
$search = array('<b>', '</b>', '<i>', '</i>', '<u>', '</u>', '\r\n', '<br />');
$replace = array('<b>', '</b>', '<i>', '</i>', '<u>', '</u>', '<br />', '<br />');
$newest = str_replace($search, $replace, $newer);
return $newest;
}
Here's what I'm using to sanitize the input going into the database:
function escape($data) {
global $conn;
connect();
$data = stripslashes($data);
$data = $conn->real_escape_string($data);
$conn->close();
$data = str_replace(chr(0), '', $data);
return $data;
}
function sanitize($data) {
$data = trim($data);
$data = strip_tags($data);
$data = escape($data);
$data = htmlspecialchars($data);
return $data;
}

display user input without \n\r

I use functions (check(removeTags($data))) to save the text in mysql database:
function check($data){
if (get_magic_quotes_gpc()) {
$data = stripslashes($data);
}
$data =addcslashes( mysql_real_escape_string($data) , "%_" );
return $data;
}
function removeTags($data){
$data=trim($data);
$data=strip_tags($data);
return $data;
}
I use this function to display text above was saved to the user.
function output($data){
return htmlspecialchars($data,ENT_QUOTES,"UTF-8");
}
But Unwanted character are added to the text.replace newline('<br/>') with "\r\n".
I use stripslashes but it didn't worked ( replace '\r\n' with 'nr' ).
I use str_replace("\r\n", "<br />",$data) but it didn't worked too.
how can i remove '\r\n' ?
edit
see this outputting \r\n after text is decoded - PHP .
but user input is not encoded with that function ( like encode ),user input language is persian (Arabic).
For remove all new line characters from string use:
function check($data) {
if (get_magic_quotes_gpc()) {
$data = stripslashes($data);
}
// this will remove all \n\r from output what you asked in question
$data = str_replace(array("\r", "\n"), '', $data);
// in case you want new line in place of \n\r use line below
// $data = nl2br($data);
$data = addcslashes(mysql_real_escape_string($data) , "%_");
return $data;
}
...
Make sure you use this on clean user input. Before addslashes or other escaping methods. After escaping EOL characters became "\\r\\n" and str_replace will not work on them.

PHP json_decode does not work

I am trying the following code to receive JSON . However the decode does not give a result. It works for a copy of the same string with escape slashes.
<?php
$input = file_get_contents('php://input');
logToFile("post.txt",$input);
#Output: {"id":"id1","model":"model1","version":"v1","software":["s1","s2","s3"]}
$data = json_decode($input,true);
logToFile("post.txt",$data['version']);
#Output:Empty result
### Works
$data1 = json_decode("{\"id\":\"id1\",\"model\":\"model1\",\"version\":\"v1\",\"software\":[\"s1\",\"s2\",\"s3\"]}",true);
logToFile("post.txt",$data1['version']);
#Output:v1
function logToFile($filename,$msg)
{
$fd=fopen($filename,"a");
$str="[".date("Y/m/d h:i:s")."]".$msg;
fwrite($fd,$str."\n");
fclose($fd);
}
?>
I am using PHP 5.4. So it's not a problem in magic quotes. Any help?
I don't think the problem is with the json_decode.
$input = '{"id":"id1","model":"model1","version":"v1","software":["s1","s2","s3"]}';
$data = json_decode($input,true);
echo $data['version'];
Works fine.
So if you go:
echo "<pre>";
print_r( $input );
echo "</pre>";
After you get the $input from the file. Does it appear OK ?

best way to encode javascript with php for ajax?

The following PHP function outputs JS:
function dothething( $data ){
$res = "
<div id=\"blah\">
Here's some stuff, ". $data['name'] ."
</div>";
echo "$('#container').html('". $res ."');";
}
This function is called via jQuery's $.ajax(), using dataType: 'script' ... so whatever is echoed runs like a JS function. There's more to it of course, but my question has to do with encoding. The ajax will fail when $res contains newlines or apostrophes. So adding this above the echo seems to be working for now:
$res = str_replace("\n", "\\n", addslashes($res));
Is this the best way to format the PHP variable $res to yield valid javascript for ajax?
Is there anything else I should add in there?
In your case I would use json_encode() over anything else:
echo "$('#container').html(" . json_encode($res) . ");";
When applied to a string value, it will automatically encapsulate it with double quotes and escape anything inside that would otherwise cause a parse error.
Try this,
if(count($result)>0) {
$status = 0;
} else {
$status = 1;
}
$json['status'] = $status;
$json['result'] = $output;
print(json_encode($json));

Categories