Output user content to JavaScript variable (avoid XSS) - javascript

I need to do the following:
<?php
$userContentFromDatabase = 'Some string that may contain "double quotes" ';
?>
<script type="text/javascript">
var userContent = "<?= $userContentFromDatabase ?>";
</script>
How can I avoid the double quotes from interfering with the JavaScript code?

Use json_encode() on the PHP side and return an object as this will take care of all of the slashes and what not that might break your code.
Or just add slashes using str_replace() if you think that the only problem area will be the double quotes.

You need more escaping than that if you want to safely output user data in a javascript variable. See rule 3 https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.233_-_JavaScript_Escape_Before_Inserting_Untrusted_Data_into_JavaScript_Data_Values

Related

JavaScript functions breaking with comma in string from PHP [duplicate]

This question already has answers here:
How do I pass variables and data from PHP to JavaScript?
(19 answers)
Closed 8 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
What is the easiest way to encode a PHP string for output to a JavaScript variable?
I have a PHP string which includes quotes and newlines. I need the contents of this string to be put into a JavaScript variable.
Normally, I would just construct my JavaScript in a PHP file, à la:
<script>
var myvar = "<?php echo $myVarValue;?>";
</script>
However, this doesn't work when $myVarValue contains quotes or newlines.
Expanding on someone else's answer:
<script>
var myvar = <?php echo json_encode($myVarValue); ?>;
</script>
Using json_encode() requires:
PHP 5.2.0 or greater
$myVarValue encoded as UTF-8 (or US-ASCII, of course)
Since UTF-8 supports full Unicode, it should be safe to convert on the fly.
Note that because json_encode escapes forward slashes, even a string that contains </script> will be escaped safely for printing with a script block.
encode it with JSON
function escapeJavaScriptText($string)
{
return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\")));
}
I have had a similar issue and understand that the following is the best solution:
<script>
var myvar = decodeURIComponent("<?php echo rawurlencode($myVarValue); ?>");
</script>
However, the link that micahwittman posted suggests that there are some minor encoding differences. PHP's rawurlencode() function is supposed to comply with RFC 1738, while there appear to have been no such effort with Javascript's decodeURIComponent().
The paranoid version: Escaping every single character.
function javascript_escape($str) {
$new_str = '';
$str_len = strlen($str);
for($i = 0; $i < $str_len; $i++) {
$new_str .= '\\x' . sprintf('%02x', ord(substr($str, $i, 1)));
}
return $new_str;
}
EDIT: The reason why json_encode() may not be appropriate is that sometimes, you need to prevent " to be generated, e.g.
<div onclick="alert(???)" />
<script>
var myVar = <?php echo json_encode($myVarValue); ?>;
</script>
or
<script>
var myVar = <?= json_encode($myVarValue) ?>;
</script>
Micah's solution below worked for me as the site I had to customise was not in UTF-8, so I could not use json; I'd vote it up but my rep isn't high enough.
function escapeJavaScriptText($string)
{
return str_replace("\n", '\n', str_replace('"', '\"', addcslashes(str_replace("\r", '', (string)$string), "\0..\37'\\")));
}
Don't run it though addslashes(); if you're in the context of the HTML page, the HTML parser can still see the </script> tag, even mid-string, and assume it's the end of the JavaScript:
<?php
$value = 'XXX</script><script>alert(document.cookie);</script>';
?>
<script type="text/javascript">
var foo = <?= json_encode($value) ?>; // Use this
var foo = '<?= addslashes($value) ?>'; // Avoid, allows XSS!
</script>
You can insert it into a hidden DIV, then assign the innerHTML of the DIV to your JavaScript variable. You don't have to worry about escaping anything. Just be sure not to put broken HTML in there.
You could try
<script type="text/javascript">
myvar = unescape('<?=rawurlencode($myvar)?>');
</script>
Don’t. Use Ajax, put it in data-* attributes in your HTML, or something else meaningful. Using inline scripts makes your pages bigger, and could be insecure or still allow users to ruin layout, unless…
… you make a safer function:
function inline_json_encode($obj) {
return str_replace('<!--', '<\!--', json_encode($obj));
}
htmlspecialchars
Description
string htmlspecialchars ( string $string [, int $quote_style [, string $charset [, bool $double_encode ]]] )
Certain characters have special significance in HTML, and should be represented by HTML entities if they are to preserve their meanings. This function returns a string with some of these conversions made; the translations made are those most useful for everyday web programming. If you require all HTML character entities to be translated, use htmlentities() instead.
This function is useful in preventing user-supplied text from containing HTML markup, such as in a message board or guest book application.
The translations performed are:
* '&' (ampersand) becomes '&'
* '"' (double quote) becomes '"' when ENT_NOQUOTES is not set.
* ''' (single quote) becomes ''' only when ENT_QUOTES is set.
* '<' (less than) becomes '<'
* '>' (greater than) becomes '>'
http://ca.php.net/htmlspecialchars
I'm not sure if this is bad practice or no, but my team and I have been using a mixed html, JS, and php solution. We start with the PHP string we want to pull into a JS variable, lets call it:
$someString
Next we use in-page hidden form elements, and have their value set as the string:
<form id="pagePhpVars" method="post">
<input type="hidden" name="phpString1" id="phpString1" value="'.$someString.'" />
</form>
Then its a simple matter of defining a JS var through document.getElementById:
<script type="text/javascript" charset="UTF-8">
var moonUnitAlpha = document.getElementById('phpString1').value;
</script>
Now you can use the JS variable "moonUnitAlpha" anywhere you want to grab that PHP string value.
This seems to work really well for us. We'll see if it holds up to heavy use.
If you use a templating engine to construct your HTML then you can fill it with what ever you want!
Check out XTemplates.
It's a nice, open source, lightweight, template engine.
Your HTML/JS there would look like this:
<script>
var myvar = {$MyVarValue};
</script>

Passing PHP variables as strings to javascript

Somehow my php function, which creates a button, which calls a javascript function, does not pass the php variables as strings.
function addTableEntry($id, $name)
{
echo('<tr>
<td>'.$id.'</td>
<td>'.$name.'</td>
<td>Manage group
</tr>');
}
addTableEntry(1,"livingroom");
The function activateGroupSettingsOverlay() always gets called with (1, livingroom) whenever it is clicked and i get an error "livingroom is undefined".
How can i pass $name as a String? I tried to put quotes around it (like this: '.$id.',"'.$name.'", but that did not work.
You have to "escape" quotes inside a string if you want them to persist:
echo '..... onClick="activateGroupSettingsOverlay('.$id.',\''.$name.'\')"....'
The important thing are the backslashes before the (single) quotes.
The reason it wasn't working is because you were not including quotes in the javascript.
While other answers "fix" the issue they don't really explain it, to be clear this line
<td>Manage group
Is output like this
<td>Manage group
As is, the livingroom does not have quotes and so javascirpt is treating it as a variable, hence the undefined error. To fix it you want it to look like this when output.
<td>Manage group
Modifying this line is all you have to change
<td>Manage group
Adding the single quotes \' with escaping.
Personally for things like this I like to use what is called a HEREDOC or NEWDOC
<<<HTML HTML; and <<<'HTML' HTML; respective. HEREDOC is like using a " and new doc is like using ' in that you cannot use php variables within a NEWDOC but you can within the HEREDOC if you enclose them in { } braces. Because of this we'll want to use a HEREDOC so we can use php variables in the output.
function addTableEntry($id, $name)
{
echo <<<HTML
<tr>
<td>'.$id.'</td>
<td>'.$name.'</td>
<td>Manage group
</tr>
HTML;
}
addTableEntry(1,"livingroom");
http://php.net/manual/en/language.types.string.php - scroll down to where it says HEREDOC
The advantage to doing this is that you don't have to escape the single quotes, which makes it way more readable IMO. The trick with HEREDOC, or NEWDOC, is the ending HTML; has to start a new line and can be the only thing on that line, no leading or trailing spaces, or it won't work properly..
For this case it is probably simple enough to get away with how you are doing it, but if you needed to use concatenation in javascript, the quotes would become a hassle. For example say you wanted to add a html image tag using javascript with a javascirpt variable for the image name, but use php to get the server host name( html and variables in javascript ).
echo '
var foo = "image.jpb";
$(body).html( \'<img src="'.$_SERVER['HTTP_HOST'].'\'+foo+\'" />\' );
';
This quickly becomes unmanageable because ( not even sure if I have that right, anyway ). Compare how much cleaner this is, because you are not wasting the quotes in php....
echo <<<HTML
var foo = "image.jpb";
$(body).html( '<img src="{$_SERVER['HTTP_HOST']}'+foo+'" />' );
HTML;
Please try with this code:-
function addTableEntry($id, $name)
{
echo("<tr>
<td>".$id."</td>
<td>".$name."</td>
<td>Manage group
</tr>");
}
addTableEntry(1,"livingroom");
Change
onClick="activateGroupSettingsOverlay('.$id.','.$name.')"
to
onClick="activateGroupSettingsOverlay('.$id.',"'.$name.'")"
#chandresh_cool was kind of right, you have to "force" the quotes
onClick="activateGroupSettingsOverlay('.$id.',\''.$name.'\')"

json_encode() gives special charactors like '\n'..how can i replace them in PHP?

I encoded an array using json_encode() function and it gave me a string like this..
"[{"details":"power - 2000w \nac-220-240v \/ 50-60hz\n369 degree cordless base\n","model_id":"MC-EK3428 \/ MC-EK3328"}]"
as you can see it contains special characters like "\n"..I want these special characters to be replaced with "" because in javascript I am using the JSON.parse(); function to convert this string to an object..
but it gives me an error
syntaxerror : missing ) after argument list
I think this is because of the special characters in the string..how can I escape these?
Edit
php :
$view->jsonencoded_array = json_encode($array);
javascript :
var products = JSON.parse('<?php echo $jsonencoded_array; ?>');//this line gives me the error
update :
found out that the error is given in this :
'<?php echo $jsonencoded_array; ?>'
The problem here is that \n (and various other combinations) have special meaning inside a JavaScript string, and you are dumping your JSON into a JavaScript string without doing any conversion of those characters.
Since JSON is heavily inspired by JavaScript literal syntax, you can use json_encode to convert a PHP string into a JavaScript string.
There are some gotchas, the main one being that </script> can appear in a JSON text without causing any problems, but having that in the middle of your JavaScript <script> element is going to cause the HTML parser to cut off your JavaScript in the middle of the string … but PHP's default encoding rules will generate <\/script> which solves that problem.
So:
<?php
$json_array = json_encode($array);
$javascript_string = $json_encode($json_array);
?>
var products = JSON.parse(<?php echo $javascript_string; ?>);
That said. A JSON array is also a JavaScript array, so you can skip that step entirely.
<?php
$json_array = json_encode($array);
?>
var products = <?php echo $json_array; ?>;
There must something that you are missing or there is some other reason for your issue while parsing in JavaScript; because json_encode handles \n and other special characters such " \ etc. very well and escape them properly without any explicit work.
I would suggest you to check the JSON produced and you are supplying to JavaScript and see if there is something missing in between.
Note: You can do a str_replace but it is not advised. Better stick to json_encodesince its s standard function and it works well.
Edit:
You should be echoing $view->jsonencoded_array not just $jsonencoded_array, no need to parse already JSON object.
php :
$view->jsonencoded_array = json_encode($array);
javascript :
var products = <?php echo $view->jsonencoded_array; ?>;
json_encode() twice helped me to solve this issue..
$view->jsonencoded = json_encode(json_encode($array));

Forward slash is changing to backward slash and forward slash

I have converted normal text into json with json_encode(data), but the problem is
normally written images/data.png is converted to images\/data.png i have to remove this extra backslash. How is it possible
In a JSON string, / and \/ are equivalent. You should not need to enforce the former syntax.
If you think you need to change them then you are either:
Designing too much for text editors instead of JSON parsers or
Being overly concerned with individual bytes
Escaping / provides a defence against premature script termination when you have code like this:
<?php
$data = Array( "</script>" );
?>
<script>
var data = <?php echo json_encode($data); ?>;
</script>
That said, if you really want to remove it, PHP provides an option for it:
json_encode($data, JSON_UNESCAPED_SLASHES);

jquery unterminated string literal when loading dynamic content

$str is loading dynamic content from admin panel (tinymce) in following format
$str = 'First Line
Second Line
Third Line';
Now when i try to access this variable then it gives me unterminated string literal
<script type="text/javascript">
$(document).ready(function() {
var a = '<?php echo $str;?>';
$('#abc').html(a);
});
</script>
<div id="abc"></div>
when i convert string to $str = 'First line Second line Third line'; then it does not give error but my string is in above way.
When dumping a PHP variable into JavaScript, ALWAYS use json_encode. Like this:
var a = <?php echo json_encode($str); ?>;
Note no quotes around the PHP code, this is important! PHP will add the quotes for you and escape everything correctly.
It's the line breaks, they're not valid inside a JavaScript string literal. If you want multiple lines in a JavaScript string, use a backslash (\):
var testString = 'This is \
a test';
Even then, multiple whitespace (including linebreaks) will be removed when it's set as the content of an HTML element.
That said, I don't see why you're using the JavaScript to do this at all, you could simply do:
<div id="jaspreet"><?php echo $str;?></div>

Categories

Resources