How can I deal with a quote in data that has to be there?
This javascript statement works fine until city name is "ST JOHN'S".
We are not able to change the change the city name in database -or- use a more reliable key.
$('#map_output').html('<p><img src="img/map/<?=$CITY_OUT?>_map.PNG" width="600"></p>')
Use htmlspecialchars().
EDIT: you use it (sorta) like json_encode:
<?=htmlspecialchars($CITY_OUT, ENT_QUOTES)?>
But htmlspecialchars is more semantic - json_encode is about generating JSON (internal, data representation), not about presentation.
Nick Craver is right though - it'll also work.
Edit: need ENT_QUOTES for rendering " ' " correctly...
You can use json_encode() to escape the quote, like this:
<?=json_encode($CITY_OUT)?>
There are three levels of encoding needed:
You're creating a URL, so you need to URL-encode it:
$url = rawurlencode('img/map/'.$CITY_OUT.'_map.PNG');
You're creating an HTML attribute, so you need to HTML-encode it:
$html = '<p><img src="'.htmlspecialchars($url).'" width="600"></p>';
That second step may not make a big difference, since you're not likely to have ', ", &, <, or > in your URL. But if you want to be strictly correct, you should encode all HTML attributes. It's a good habit to get into, so you can handle all special characters.
Finally, you're creating a JavaScript value, so you need to JSON-encode it:
$('#map_output').html(<?= json_encode($html) ?>)
(edited to add JSON-encoding)
In my quick tests, neither of the two answers worked:
<?php
$string = "ST JOHN'S";
$json = json_encode($string);
$html = htmlspecialchars($string);
$escape = str_replace("'", "\'", $string);
?>
<script type="text/javascript">
alert('<?php echo $escape?>');
alert('<?php echo $html?>');
alert('<?php echo $json?>');
</script>
The only test which did not produce a javascript error was my usage of str_replace to actually escape the single quote.
"rawurlencode" is what you need to ensure the characters in the URL are interpreted the same on the "img/map/..." request the same way they are in this PHP script.
Incidentally, "rawurlencode" safely escapes all of the characters you need to worry about in XSS injections.
<?php
$string = "ST JOHN'S";
$json = json_encode($string);
$html = htmlspecialchars($string, ENT_QUOTES);
$htmlent = htmlentities($string, ENT_QUOTES);
$escape = str_replace("'", "\'", $string);
$urlenc = rawurlencode($string);
?>
<script type="text/javascript">
alert('<?php echo $html; ?>');
alert('<?php echo $htmlent; ?>');
alert('<?php echo $urlenc; ?>');
</script>
You've said that none of the solutions given so far have worked for you, but I think actually they're fine (at least some of them). Let me demonstrate:
Here are the examples you listed:
$json:
<img src="img/map/"ST JOHN'S"_map.PNG"/ width="600">
$html:
<img src="img/map/ST JOHN'S_map.PNG"/ width="600">
$htmlent:
<img src="img/map/ST JOHN's_map.PNG"/ width="600">
$escape:
<img src="img/map/ST JOHN\'S_map.PNG"/ width="600">
$urlenc:
<img src="img/map/ST%20JOHN%27S_map.PNG"/ width="600">
I don't see any problem with any of these (except the JSON one, which I'll explain in a moment).
And I've just tried all these examples, trying to simulate your scenario as closely as possible (even down to using the same file name).... All of them loaded the graphic correctly, again except the JSON example.
The JSON example needs a minor tweak to get it working, but it also does escape the string in a workable way. To get it working you need to take into account that JSON produces a fully-quoted Javasscript string rather than just escaping it as the others do, so you'd modify the output to close the quotes and add the strings together, like so:
$('#map_output').html('<p><img src="img/map/"+<?=$json?>+"_map.PNG"/ width="600"></p>');
The other solutions don't need this. They all work as is. As I say, I tried them, and they all loaded the graphic into the page.
In the context, all three mechanisms (escaping \', entities ' and URL encoding %27) are valid:
Escaping works because you're in the context of Javascript, so the backslash gets dealt with by Javascript and the final generated HTML that gets inserted into the page won't contain it.
Entities work because HTML translates entities into the mapped character, so ' in a HTML page is the same as a single quote, even within an attribute value as in this case.
URL Encoding works because browsers translate them when they load a URL.
I would suggest URL encoding is the correct solution in this case, since this is being used for a URL. The reason for that is that while all the solutions work for the given example, if you have any examples that contain a question mark or an ampersand (&) or a few other reserved characters, then URL encoding will be the only solution that will work in these cases. On the other hand, if you're displaying the output in your HTML page in another context, then entities are the way to go. And if it is going to be used just within Javascript, then JSON is the answer.
But you say none of them did the trick. My question is: Did you actually try them? Did you run the code and the graphic failed to load? It did for me. On the other hand, if they did work, but still don't "do the trick", then what is it you actually want?
My guess is that what you actually mean is that you want to end up with a simple quote character there, but have it magically work. That can't happen; the quote has to be escaped somehow or other in order for it to work, but they user will never see the escaped version, so there's no need to worry about it.
In fact, you should be escaping or encoding all the strings you input or output, so that invalid characters do work. Otherwise Mr O'Brien is going to have trouble entering his name into your site, and if he manages it, you'll have trouble displaying it afterward.
Unfortunately none of the above solutions did the trick.
<?
$string = "ST JOHN'S";
$json = json_encode($string);
$html = htmlspecialchars($string, ENT_QUOTES);
$htmlent = htmlentities($string, ENT_QUOTES);
$escape = str_replace("'", "\'", $string);
$urlenc = rawurlencode($string);
?>
$json:
<img src="img/map/<?=$json?>_map.PNG"/ width="600">
$html:
<img src="img/map/<?=$html?>_map.PNG"/ width="600">
$htmlent:
<img src="img/map/<?=$htmlent?>_map.PNG"/ width="600">
$escape:
<img src="img/map/<?=$escape?>_map.PNG"/ width="600">
$urlenc:
<img src="img/map/<?=$urlenc?>_map.PNG"/ width="600">
output:
$json:
<img src="img/map/"ST JOHN'S"_map.PNG"/ width="600">
$html:
<img src="img/map/ST JOHN'S_map.PNG"/ width="600">
$htmlent:
<img src="img/map/ST JOHN's_map.PNG"/ width="600">
$escape:
<img src="img/map/ST JOHN\'S_map.PNG"/ width="600">
$urlenc:
<img src="img/map/ST%20JOHN%27S_map.PNG"/ width="600">
Related
I am quite new in php. I have to store a img tag in a var. I think this is ok:
$fotoTag1 = "<img src='42.png'
alt='text alt'>";
But the problem comes if there is a single quote in the name of the photo or in the alt?. For intance, don't
What I have tried:
$fotoTag1 = "<img src='don't.svg' alt='don't>'";
echo htmlspecialchars ($fotoTag1);
echo addslashes($fotoTag1);
$fotoTag2 = "<img src='don\'t.svg' alt='don\'t'>";
echo $fotoTag2;
(This is a simplified example but the url and alt comes from a sql database and of course, I cannot change the text manually. I need a general solution)
Use htmlspecialchars() to properly encode the text fragments you use to build the HTML fragment, not the HTML you built:
$fotoTag1 = '<img src="'.htmlspecialchars("don't.svg").'" alt="'.htmlspecialchars("don't").'">';
Or, to be more clear:
// Wrapped for clarity
$fotoTag1 = sprintf(
'<img src="%s" alt="%s">',
htmlspecialchars("don't.svg"),
htmlspecialchars("don't")
);
Read about sprintf() and the different ways to specify a string in PHP.
addslashes() doesn't help when you build HTML content. As a side note, it is an obsolete function that doesn't have many usages nowadays.
$fotoTag2 = "<img src=\"don't.svg\" alt=\"don't\">";
echo $fotoTag2;
$fotoTag1 = "<img src='don't.svg' alt='don't>'";
Your problem here has nothing to do with PHP.
You have an HTML attribute value delimited with apostrophe characters and you want to use an apostrophe inside that value.
When you want to represent a character with special meaning in HTML as that raw character, you can use a character reference.
This can be a named entity (') or one of the numeric references to the position of the character in unicode (');
<img src='don't.svg' alt='don't'>
Beware: ' was added to HTML relatively late. Old versions of IE do not support it.
Alternatively you could change your HTML so you use double quotes to delimit the data:
<img src="don't.svg" alt="don't">
This would introduce a PHP problem because you are using them to delimit the string literal.
In this case you would need to escape the data for PHP, which you do with a backslash character.
$fotoTag1 = "<img src=\"don't.svg\" alt=\"don't\">";
Alternatively, you could use some other form of string generation, such as HEREDOC.
$fotoTag1 = <<<END
<img src="don't.svg" alt="don't">
END;
As a rule of thumb, it is better to avoid storing HTML in variables in the first place.
When you want to output data, just switch to output mode:
?>
<img src="don't.svg" alt="don't">
<?php
You can always drop back into PHP mode if you need a variable.
$src = "don't.svg";
$alt = "don't";
?>
<img src="<?php echo htmlspecialchars($src); ?>" alt="<?php echo htmlspecialchars($alt); ?>">
<?php
(Note that for the characters involved, htmlspecialchars isn't needed in this example, but it does protect you when dealing with programmatically acquired data that you can't guarantee to be HTML safe).
You had the right idea using htmlspecialchars(), the issue with this specific example is that function does not escape ' by default. You need to add the flag ENT_QUOTES to escape single quotes with htmlspecialchars().
You should also be applying this function just to strings you wish to escape, not the entire html line. This could, and most likely will in most cases, cause unintended side effects of escaping characters you didn't want escaped.
Try this, it's working:
$fotoTag1 = '<img src="'.htmlspecialchars("don't.svg").'"
alt="'.htmlspecialchars("don't").'">';
echo $fotoTag1;
You should use the html ascii codes, so for your example:
$fotoTag2 = "<img src='don't.svg' alt='don't'>";
Since ' is the ascii code for single quote.
I am using PHP/mysqli to read in comments, but various comments in the table have either a single quote or a double quote.
I am storing the comments in a data-attribute. Using the Chrome console, I can see where the quote is throwing the whole code out of whack.
<?php
echo "<td><a href='' class='comment' data-toggle='modal' data-comment='".htmlentities($row[comment])."'>" . $row[partner_name] . "</a></td>";
?>
As you can see in the code above, I tried to use htmlentities. I also tried addslashes and a combination of the two.
Either way, I still can't get the comment to display properly because of the quote inside the mysql table.
Is there another PHP function that I can use to fix this?
Directly above is a screen shot from the Chrome console. Right after the words POTENTIAL 53 there is a single quote that is throwing my code off. All the other orange text is being read as HTML when it's supposed to be part of the comment.
There has to be a way to read the single quote as part of the string.
Pass the flag, ENT_QUOTES, to your htmlentities function. See http://php.net/htmlentities. This will replace quotes with entified quote and prevent it from breaking out of the data-comment attribute.
Well, there are two problems:
You have to encode stuff, especially quotes:
$text = htmlentities($value, ENT_QUOTES);
The title attribute does not work with newlines, so you will have to deal that. Something like this should do the job:
$text = preg_replace('/\r?\n/', '#xA;', $text);
Try escaping the quotes in your data. Something to this affect:
$pattern = "/\"|\'/";
$replace = '\\\"';
$subject = $row[comment];
$rowComment = preg_filter($pattern, $replace, $subject);
*Tip - You can also filter the data before storing it.
Description: echo $rowComment will produce a string with all quotes escaped;
You can visit this link for an example of my promlem : http://jflaugher.mystudentsite.net/cmweb241/cmweb241_lab2.html
Everything is working correctly, except that I am having problems utilizing the htmlspecialchars in my echo. I am wanting the entity to show up in the echo and not the html character. I have tried placing the htmlspecialchars within the echo, but then the paragraph tags shows up. How do I utilize the htmlspecialchar in the echo, and display the echo in a paragraph tag? I have been at this for some time and have gotten no where, as I am very new to PHP.
For example, when I enter a '&', I get that echoed back. Instead of the '&', I want the entity & to be echoed.
<?php
$username = htmlspecialchars(str_replace(array("'", "\""), "", $_POST['username']));
$password = htmlspecialchars(str_replace(array("'", "\""), "", $_POST['password']));
$comment = htmlspecialchars(str_replace(array("'", "\""), "", $_POST['comment']));
echo "<p> Your Username is: $username .</p> ";
echo " <p>Your Password is: $password . </p>";
echo " <p>Your Comment was: $comment . </p>";
?>
Say you enter &.
htmlspecialchars will turn this into &.
& is the HTML entity for &, so viewing the result in a browser displays &.
This is the normal purpose of htmlspecialchars, it preserves the visible character by escaping it for the medium (HTML) appropriately.
If you want & to turn into a visible &, the browser will need to receive &. Apply htmlspecialchars twice to do that:
htmlspecialchars(htmlspecialchars($_POST['username']))
Maybe The Great Escapism (Or: What You Need To Know To Work With Text Within Text) helps you to understand the topic better.
I'm not sure what this means:
I am wanting the entity to show up in the echo and not the html character.
Are you saying that you want the entity to be displayed in your web page? htmlspecialchars is converting the characters to entities, but a browser will display those entities as the characters they represent.
If you want to actually see the entities in your browser, you can double-escape the values:
$username = htmlspecialchars(htmlspecialchars(str_replace(array("'", "\""), "",
$_POST['username'])));
But I don't really think that's the purpose of the exercise you're doing.
If you want to display the entities, you could apply htmlspecialchars() twice and it will turn all the & in & to & and thus the entity itself will be displayed.
Another method is wrapping the output in <pre></pre> tags.
Try this approach:
<?php
$string = "<tag>&";
$string = htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
print $string;
It will print:
<tag>&
How to prevent XSS with HTML/PHP?
I was trying to get away from using PHP's htmlentities and here's where I stopped:
<?php
echo '<img ... onclick="MP.view(\''.$i->name.'\') />';
?>
But then I thought, instead of doing replaces and checks for special characters, I'll just JSON the entire object.
<?php
echo '<img ... onclick="MP.view('.json_encode($i).') />';
?>
And this provided a much undesired result putting in a ton of double quotation marks.
So how should I do this? Should I assign a numerical unique id to every image and just pass the id, and then look up the rest of the data from a JS array?
The correct approach in such cases would be:
htmlspecialchars(json_encode($var), ENT_QUOTES, "UTF-8")
htmlspecialchars turns any double quotes into the proper HTML escapes, making the resulting string suitable for most attributes. The ENT_QUOTES parameter also takes care of single quotes; but you probably don't need that in your example.
It would take a whole lot less escaping (and fewer bytes) to pass the data something like this:
echo '<script>var myObj = '.json_encode($i).'</script>';
Then, your code could look more like this:
echo '<img ... onclick="MP.view(myObj)" />';
This is my source code:
<html>
<body>
<?php
$query = $_REQUEST["search"];
Print "<iframe src="http://www.en.wikipedia.org/wiki/$query"></iframe>';
?>
</body>
</html>
I want to have it where, when the user types in a term, then it automatically brings them to the Wikipedia page of their query. I definitely know I'm doing something wrong here, but I can't figure out what. Thanks for helping!
Change your statement to:
print "<iframe src=\"http://www.en.wikipedia.org/wiki/$query\"></iframe>";
You needed to escape the quotation marks.
Same way you output any variable into HTML text content or attribute values, using htmlspecialchars(). If you don't do this every time you drop user data into HTML, you've got an HTML-injection vulnerability leading to cross-site-scripting (XSS) exploits.
In your case you are inserting a variable into a URL component, so before you HTML-encode, you need to URL-encode, using rawurlencode().
OK... so if you're doing URL-encoding, you can actually skip the HTML-encoding if you want, because all characters that are special to HTML are also turned into safe % sequences by URL-encoding.
PHP is a templating language. Use it, don't fight it. Any time you echo or print an interpolated string from inside a PHP block, you're probably making life unnecessarily hard for yourself.
Include literal content verbatim and don't worry about backslash-escaping quote characters in string literals:
<?php
$query= $_REQUEST['search'];
?>
<iframe src="http://en.wikipedia.org/wiki/<?php echo rawurlencode($query); ?>">
</iframe>
Try not to include huge html strings inside print / echo statements, it makes it easy to make quoting mistakes and tough to follow what's going on with your code.
Instead you can include variables as tokens inside the html like many templating languages, but using the shorthand echo functionality <?= $variable; ?>
<html>
<body>
<iframe src="http://www.en.wikipedia.org/wiki/<?= $_REQUEST["search"]; ?>"></iframe>
</body>
</html>