So I have a set of strings with some "custom markdown" that I created. My intention is to render these strings to HTML on the front end. Let's say I have this string:
This is a string <color>that I need</color> tonrender <caution>safely in the browser</caution>. This is some trailing text
I was hoping for something like:
This is a string <span class="primaryColor">that I need</span> to<br>render <div class="caution">safely in the browser</div>. This is some trailing text
What I do now is to use some basic regular expressions:
toHtml = text .replace(/<color>(.*)</color>/gim, "<span class='primaryColor'></span>") .replace(/\n/g, "<br>") .replace(/<caution>(.*)</caution>/gims, "<div class='caution'></div>")
This works fine and returns the correct string. Then to print, in the template I just:
<div id="container" v-html="result"></div>
My problem is that at some point I want the user to be able to enter these strings themselves and have this be displayed to other users as well. So for sure I'm vulnerable to XSS attacks.
Are there any alternatives to avoid this? I've been looking at https://github.com/Vannsl/vue-3-sanitize and this looks to be allowing the div
, span
and br# I'm using Good approach for ## tags and setting the properties of all tags to allow only
class. Is this safe enough? Is there anything else I should do?
, the web browser cannot execute the malicious code, right?
My problem is that at some point I want the user to be able to enter these strings themselves
So, do we have a form input for the user to enter the string you mentioned in your post? If yes, my suggestion is that you can sanitize the user input first before passing it to the backend. Therefore the backend itself should not store malicious code.
So, by using the
string.replace()
method. You can replace ex's malicious tag first. Extract,
, etc. from the input string and store it in the database.
Steps you can follow:
blacklist
variable containing a regular expression of disallowed characters/strings.This way you don't have to worry about the string coming from the backend and can bind it via
v-html
without causing any harm.