I have a set of items stored in a database, each with their own unique name.
On one of my HTML pages, I create a list of buttons that display the name of each item, and when they are clicked, I call a function that passes the name of the item as a parameter.
The issue is, these item names are user-generated, so they can be whatever a person wants. This means they have the potential to have single quotes in them, for example: name'with'quotes. I have found that my HTML construction runs into an error when it tries to construct the buttons for any items with quotes in the name. They end up looking something like this:
As soon as it hits the first single quotes in the name, it seems to turn them into a space and double-quotes ( ") and then everything else after that becomes a garbled mess. Any double quotes seem to get converted to ".
What should I do so that I can allow single quotes in an item name, and then use that name in an HTML attribute later? I already am using encodeuricomponent() when taking the names in and out of the database, but that function doesn’t affect single quotes.
Maybe use the escape character ( / ) to prevent JavaScript from interpreting a quote as the end of the string, or the same in PHP somewhere in your syntax. Sorry that is the best I can do.
Unfortunately, seems like that doesn’t work. Here’s when I use decodedName.replace(/'/g, "\\'"); to add escape characters before all of the quotes and log the string being inserted into the HTML:
If and only if the database is PHP driven then there are numerous PHP functions available to convert the source before storing. On retrieval the data should render without any problems.
Hi @John_Betong! Yes, the database is completely PHP driven. Apologies for not making that explicit.
Nothing happening during the storage is an issue. I am encoding the user-given strings as well as using filter_var in my PHP code to sanitize the input. I decode everything when it comes out of the database and end up with the exact same string that the user inputted. The problem is that when I try to take names that involve single quotes (') out of the database and put them into the HTML, the HTML seems to break. It doesn’t appear to have anything to do with the storage/retrieval aspect of getting the names.
Sure. Are you implying the solution is to just bar users from inputting the single quote symbol?
@m3g4p0p I sanitize the user input when I take it in and out of the database (see above in this response) to avoid a Little Bobby Tables situation. When it comes to inserting the user input into the HTML attribute, though, what is the best practice for ensuring safety and preventing injection? I have been doing some simple sanitizing like converting spaces to hyphens, but what is the ideal way to keep it clean? Using encodeURIComponent? (though even if I use encodeURIComponent, it will not encode single quotes, so my original problem will still remain.)
Enhance this PHP function to suit your requirements
//======================================
function fnClean(string $tmp)
:string
{
// good and bad can be an array of items
$bad = "'";
$good = '"'"';
$tmp = str_replace( $bad, $good, $tmp);
return $tmp;
}
Don’t generate your JS dynamically at all, especially if user content is involved; and even if not, this gets hard to read and maintain pretty quickly. I assume you’re currently doing something like this?
This way you can be sure that the the value of $item won’t get evaluated but always treated as a string by your JS. And while at it, you might also consider using addEventListener() instead to keep your PHP and JS logic separate:
What you do it stop using HTML inline event handlers.
There are much better ways to deal with things when using addEventListener instead.
With the params, you can store that in a data attribute, and use dataset to retrieve it.
Oh, that’s a great idea! Encoding the single quotes as HTML entities before putting them on the page, I should have thought of that! It works like a charm, thank you @John_Betong!
Oh, nifty, I did not know about data attributes before! Besides just looking cleaner, does the extra security come from data attributes ensuring that the user-input is parsed as a String and not as runn-able code?
Great, alright. I was never given formal training on JavaScript/HTML structuring practices (I was self-taught in that area), so I didn’t know that it is better practice to keep all function calls in external Event Listeners instead of inline ones. Are there any other small best-practice formatting/structuring conventions I should be aware of?
I’ve officially refactored to move all my listeners into external functions and put all of the information they need into data attributes. Thanks for the help everyone, this was very valuable to me!