How to prepare PHP variable for Javascript array() use? - php

Let's say that we have input field or textarea where user can put anything. This means that user can put there:
text
white spaces
multilines
HTML tags
single and double quotes
slashes
and whatnot...
My current code does this: <?php $data = addslashes($content_of_input); ?>
and soon after that...
<?php
$php_generate_javascriptArray .='
javascriptArray[0] ="'.$data.'";
';
?>
<script>
javascriptArray = [];
<?php echo $php_generate_javascriptArray; ?>
</script>
Adding slashes unfortunately isn't enough - Javascript breaks when user puts for instance multiple lines or HTML links into that. Is there any way to prevent that and still ALLOW Javascript array to contain LINK, MULTIPLE LINES, HTML TAGS? I'm looking for some universal filters.

json_encode will convert a PHP data structure (or string, or number) to the appropriate JavaScript data structure while making it safe for injecting into a script element in an HTML document (by escaping slashes).
<script>
var data = <?php echo json_encode($data); ?> ;
</script>

Use PHP function urlencode(...)
or base64_encode(...) of need of more advanced protection.
I normal use urlencode and on Javascript side use unescape for decode the URL format data.

Related

Should I be using htmlspecialchars?

I seem to have trouble understanding when to use htmlspecialchars().
Let's say I do the following when I am inserting data:
$_POST = filter_input_array(INPUT_POST, [
'name' => FILTER_SANITIZE_STRING,
'homepage' => FILTER_DEFAULT // do nothing
]);
$course = new Course();
$course->name = trim($_POST['name']);
$course->homepage = $_POST['homepage']; // may contain unsafe HTML
$courseDAO = DAOFactory::getCourseDAO();
$courseDAO->addCourse($course); // simple insert statement
When I ouput, I do the following:
$courseDAO = DAOFactory::getCourseDAO();
$course = $courseDAO->getCourseById($_GET['id']);
?>
<?php ob_start() ?>
<h1><?= $course->name ?></h1>
<div class="homepage"><?= $course->homepage ?></div>
<?php $content = ob_get_clean() ?>
<?php include 'layout.php' ?>
I would like that $course->homepage be treated and rendered as HTML by the browser.
I've been reading answers on this question. Should I be using htmlspecialchars() anywhere here?
There are (from a security POV) three types of data that you might output into HTML:
Text
Trusted HTML
Untrusted HTML
(Note that HTML attributes and certain elements are special cases, e.g. onclick attributes expect HTML encoded JavaScript so your data needs to be HTML safe and JS safe).
If it is text, then use htmlspecialchars to convert it to HTML.
If it is trusted HTML, then just output it.
If it is untrusted HTML then you need to sanitise it to make it safe. That generally means parsing it with a DOM parser, and then removing all elements and attributes that do not appear on a whitelist as safe (some attributes may be special cased to be filtered rather than stripped), and then converting the DOM back to HTML. Tools like HTML Purifier exist to do this.
$course->homepage = $_POST['homepage']; // may contain unsafe HTML
I would like that $course->homepage be treated and rendered as HTML by the browser.
Then you have the third case and need to filter the HTML.
It looks like you're storing raw html in the database and then rendering it to the page later.
I wouldn't filter the data before you store it into the db, you risk corrupting the users input and there would be no way to retrieve the original if it were never stored.
If you want the outputted data to be treated as html by the browser then no, htmlspecialchars is not the solution.
However it is worth thinking about using striptags to remove script tags in order to combat XSS. With striptags you have to whitelist the allowable tags which is obviously tedious but pretty safe.
It might also be worth you taking a look at tinyMCE and see how they deal with such things
output plain HTML if you are sure about the contents. use htmlspecialchars on every other resources, especially for user inputs to prevent security issues.

Passing PHP-generated JSON via semantic markup

In another question, it was pointed out that using semantic markup can be a really clean way to pass data to an onclick function, along the lines of the code below.
I have a second question relating to passing JSON and having the receiving function recognize it as such. I have a PHP generated JSON value of [{"authed":"2012-03-04 17:24:24"},{"authed":"2012-03-04 11:44:38"}] that I need to pass to a function. echoing that straight into the <a> tag won't work, so I am using urlencode() to get:
click
Unfortunately, when I alert this out from popup(), I via the following code:
function popup(t) {
var auth = t.getAttribute('data-auth');
alert(decodeURI(auth));
}
I get
[{"authed"%3A"2012-03-04+17%3A24%3A24"}%2C{"authed"%3A"2012-03-04+11%3A44%3A38%22"}]
which JSON.parse() is unable to handle. Any suggestions on decoding/passing JSON using this pattern?
You need to use htmlspecialchars() to escape for html--like you should be doing for everything you echo out in html. (You are doing that right? To prevent generating invalid html?) Don't use urlencode(), which is for encoding parts of a url path or query parameter.
<?php
$data = array(array('authed'=>'2012-03-04 17:24:24'), array('authed'=>'2012-03-04 11:44:38'));
$jsondata = json_encode($data);
?>
<a data-auth="<?php echo htmlspecialchars($jsondata, ENT_COMPAT, 'UTF-8')?>" onclick="popup(this)">click</a>

Store JSON in a hidden input element?

I need to be able to generate an effectively unlimited number of datasets, so what I want to do is something like this;
<input type="hidden" name="items[]" value="{id:1,name:'some-name'}" />
I tried JSON.stringify to convert my array in javascript and store it in the current hidden input element, but it wraps all the keys and values in double quotes, which obviously conflicts with HTML wrapping the entire value in double quotes. Somehow I need to escape the quotes, but I need this to work two ways...basically these elements are generated with PHP and placed in the page in order, then I can add or delete items on the user end and submit the page, which should have PHP iterating through these hidden elements and updating the records.
Anyone have any suggestions on an escaping method of some sort?
You can use escaping function presented here: http://phpjs.org/functions/htmlspecialchars:426
It should escape chars in json and make your string safe to use as value of html attribute.
If you want to do the escaping on PHP then you should use function htmlspecialchars() that is built in PHP.
What you want to do is grasp some of html5 data-* attrubites so you can dod
<div id="post-container" data-meta="{id:22,name:'Robert Pitt'}">
..
</div>
Then you can use htmlentites() to make the string safe and use javascript, you can get the data with javascript like so:
function ElementJson(id,attrib)
{
var post_c = document.getElementById(id);
for( var x = 0; x < post_c.attributes.length; x++)
{
if( post_c.attributes[x].nodeName.toLowerCase() == 'data-' + attrib.toLowerCase())
{
return post_c.attributes[x].nodeValue;
}
}
return false;
}
json = ElementJson('post-container','meta');
Via jQuery for instance you can do
json = $('#post-container[data-meta]').attr('data-meta');
A lot of large sites use it especially Facebook
base64_encode the data or run it through htmlentities() to turn the quotes in to entities :)
To be honest, if you are setting the value in javascript in the page then I am a little surprised that you ran into problems but here are a couple of suggestions: -
Of course the proper thing to do is HTML encode the data in the html attributes - but this requires calling htmlentities or similar so instead, why not URL encode the data using the "built in" javascript encode and decode and methods. URL encoding should escape double quotes to '%22'.
Or if you are already using jQuery, use the val() method to set (and get?) the value - I am sure that would deal with these issues for you (although I have not gone and actually checked this).

Javascript Object Not Digging My PHP Var's Value (Has HTML in It)

I'm building a CMS for a client (Building on top of wordpress). I'm having an issue with some data I am returning from my database.
Basically I am building Javascript Objects from PHP data so that I can update certain areas of my site upon mouse click.
example (this would work fine):
<script language = "Javascript>
var myObject = new Object();
function updateDiv(id)
{
myObject.name = '<?php echo $valueName ?>'; // $varHeadline = "Bob"
myObject.headline = '<?php echo $value_headline ?>'; // $varHeadline = "My Story"
var div = document.getElementById(id).innerHTML = myObject.name +
'<br>' + myObject.headline';
}
</script>
The problem comes up when the data I bring back from my database already has some html, or line breaks in it.
Example:
echo $varHeadline;
// returns <h1>This is my headline</h1>
// This is part of the value too.
So if I create a Javascript Object with that data:
function updateDiv(id)
{
myObject.headline = '<?php echo $varHeadline; ?>';
var div = document.getElementById(id).innerHTML = myObject.headline;
}
I get errors in my Javascript.
I would like to continue populating my divs with Javascript Object data, but am unable to on account of some of the data containing HTML (or even single or double quotes for that matter).
I DO want to retain my HTML formatting (the <h1> tags and so forth) so using htmlspecialchars or strip_tags is out of the question. Is there any die hard way of storing returned HTML without killing Javascript?
Thanks in advance.
-J
json_encode() the string and take away the quotes:
myObject.headline = <?php echo json_encode($varHeadline;) ?>;
Of course, you could rewrite this as:
<script language = "Javascript>
var myObject = <?php echo json_encode(array('name'=>$valueName,'headline'=>$value_headline)); ?>;
function updateDiv(id)
{
var div = document.getElementById(id).innerHTML = myObject.name +
'<br>' + myObject.headline';
}
</script>
edit: as noted in the comments below, always make sure you can trust the HTML you're placing on the page. If $valueName or $value_headline is coming from user input, this is a bad idea if you don't validate the HTML in some other fashion, you're open to XSS attacks and the like: http://en.wikipedia.org/wiki/Cross-site_scripting
When you "quote" server-side values being dropped into a page, the quoting has to be different when the context is Javascript code and not HTML. For HTML, of course, you do things like turn ampersands into "&" and less-than symbols into "<", and so on. Well inside Javascript strings, less-than and ampersand aren't a problem - they might be later if you're going to stuff the string into HTML, but right there at the time the Javascript parser is reading the string, there's no problem. What is a problem are quotes and characters outside the good ol' 7-bit ASCII range. (That's a generalization, but you see what I mean.)
I don't know PHP but it seems like there has to be some way to tell it NOT to perform the quoting appropriate for HTML/XML, and to instead do something to protect the characters that are special inside Javascript string constants.

htmlspecialchars and json encode problem

I am trying to format some bad html to output into a pop window. The html is stored in a field in a mysql database.
I have been performing json_encode and htmlspecialchars on the row in the php like so:
$html = htmlentities(json_encode($row2['ARTICLE_DESC']));
and calling my makewindows function, which simply takes the html as a paramter and uses it withdocument.write like so:
<p>Click for full description </p>
This works ok, as in some html code is produced, such as the following:
http://www.nomorepasting.com/getpaste.php?pasteid=22823&seen=true&wrap=on&langoverride=html4strict
pasted there because I do not know how to wrap lines in SO
The problem is that htmlspecialchars does not seem to be stripping bad html data, as no popup window is created. The error I receive with firebug is
missing ) after argument list
However the html is outside of my control.
From what I have read, I am taking the correct steps. If I am missing something out, what is it?
My full make windows function:
function makewindows(html){
child1 = window.open ("about:blank");
child1.document.write(html);
child1.document.close();
}
You shouldn't have the single quotes in the function call. It should look like this:
<p>Click for full description </p>
Then the output will look like
<p>Click for full description </p>
which is correct.
Try it the following way:
$html = htmlentities(json_encode($row2['ARTICLE_DESC']),ENT_QUOTES);
I think the single quotation marks are not escaped by default.
Nevertheless I recommend you saving the html in a JavaScript variable before opening the window.

Categories