While I agree with the vulnerabilities raised in @Alfonso's answer, the situation is actually worse: All of your untrusted variables are vulnerable to an XSS attack here.
For example,
say untrustedURL
contained the following text
"><img src="http://example.com" onerror=alert(/xss/) data-x="
this would cause the following to be rendered:
<a class="url" href=""><img src="http://example.com" onerror="alert(/xss/)" data-x="">
which will cause the JavaScript alert to show instantly:

As your code is all in a JavaScript context already, you need to follow Rule #1 of the OWASP XSS cheat sheet and HTML encode the data. A simple conversion of the following characters is sufficient:
& --> &
< --> <
> --> >
" --> "
' --> ' ' not recommended because its not in the HTML spec (See: section 24.4.1) ' is in the XML and XHTML specs.
/ --> / forward slash is included as it helps end an HTML entity
Note that OWASP recommend Rule #2 for HTML attribute values, however if you are quoting all attributes then the above will be enough. Rule #2 works everywhere, including unquoted, so if you have a mixture Rule #2 will be simpler.
I've read your comment regarding that you say you should encode Javascript after escaping HTML entities
.
Yes, this applies to where the value is initially from (say from the server side), but you should do this encoding in the language that your server side code uses, not JavaScript. Also, do the JavaScript escaping first to get the server side variable into JavaScript, then later use HTML escaping in JavaScript ready for insertion into the DOM.
e.g. JavaScript escaping in ASP.NET C#:
<script>
var untrustedURL = "<%=HttpUtility.JavaScriptEncodeString(usersUrl)%>";
</script>
See my answer here for greater detail on this.
Then you need to HTML encode using a function:
function escapeHTML (unsafe_str) {
return unsafe_str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\"/g, '"')
.replace(/\'/g, ''')
.replace(/\//g, '/')
}
So your code could just be
<script>
var untrustedURL = escapeHTML("<%=HttpUtility.JavaScriptEncodeString(usersUrl)%>");
</script>
untrustedURL
and untrustedSource
Note that these are special cases where validation should take place as well. You should do this on the server side and make sure that they either start with http://
, https://
or //
(protocol relative URL). A whitelisting approach ensures that the user cannot enter a javascript:
scheme URL and will also protect against different schemes from being entered that may be unique to the user's browser, operating system, device, configuration, etc. Only allowing HTTP is much safer.