You can't do it. Vue uses the DOM to set the href attrib, so it's not hard-coded from the server in a way that could fool the HTML parser. It's simply impossible to set an attrib with the DOM in a way that "breaks out" of the attrib, or starts a new attrib as though you had raw HTML source; all invalid characters will be logically escaped, even if the raw values in the dev tools make it look like the attack should work.
If you did any of the templating on the server (perhaps in an attempt to pre-render) then it's a problem, but as-is, you're safe.
note that data:
and javascript:
urls could still be an issue, but you've probably already got protection from that setup, given your apparent level of expertise.
EDIT: responding to comment
consider a simple page that uses the DOM to inject content:
<html>
<a id=a href="#">xss</a>
<script>a.href='"><script>alert(123)<\/script>';</script>
</html>
If you look at the developer tools inspect view, you might see something scary like this:
<a id="a" href=""><script>alert(123)</script>">xss</a>
It appears there's a <script>
tag inside the <a>
tag, and indeed, if you copy that into a blank page and view it, it WILL alert. However, it's not actually a problem because the developer tools are playing a visual trick. The actual contents of the element when serialized are more like this:
<a id="a" href=""><script>alert(123)</script>">xss</a>
That's what I meant by the DOM auto-escaping any arbitrary content; as long as you use the DOM to set an attrib, there's no way to "bust out" of the attrib with any content. That doesn't mean that an attrib with side effect, like onmouseover
can't do you wrong, just that you can't set onmouseover
by adjusting an href
.
That data:
and javascript:
url protocol is well-discussed elsewhere, but be aware it a way to link to arbitrary content documents (data:
) and JS code (jacascript:
).
For example, both of these alert "666" (mark of the beast) when clicked:
Javascript: <a href=javascript:alert(666)>xss</a>
Data: <a href=data:text/html,%3Cscript%3Ealert%28666%29%3C/script%3E>xss</a>
Both can be used in place of an http(s) url, so make sure to guard against that, especially javascript:
because it doesn't need a slash to make code executable.
foo
end up in the href attribute? The attribute is set using JS, likelink.setAttribute("href", foo.bar)
?