4

Using classic ASP, is this the right way to do to protect against XSS?

var1=untrusteduserinput

Showing a text in the body

<%=server.htmlencode(var1)%>

Showing a link in the body

<a href="http://www.example.com/page.asp?var1=<%=server.urlencode(var1)%>"><%=server.htmlencode(var1)%></a>

Showing an image

<img src="http://www.example.com/images/<%=server.urlencode(var1)%>" alt="<%=server.htmlencode(var1)%>">

Showing an iframe

<iframe src="http://www.example.com/page.asp?var1=<%=server.urlencode(var1)%>"></iframe>

In meta tags

<meta name="description" content="<%=server.htmlencode(var1)%>">

In forms

<input type="text" name="var1" value="<%=server.htmlencode(var1)%>">

EDIT: In e-mail

<a href="mailto:<%=server.urlencode(var1)%>">Email</a>

EDIT 2: Why does http:// become %3A%2F%2F when using urlencode on a link like this? Then the link doesn't work.

<a href=”<%=server.urlencode(var1)%>”><%=server.htmlencode(var1)%></a>

EDIT 3:

Thank you so much for your replies! However, I am not sure if I understand this right. XSS is dangerous on output, on what is printed on the website so that others can see it, right? So I thought that is was the fact that the link appears as a clickable link that made it more dangerous? That someone inject malicious code that´s executed when someone clicks on the link? And that it was because of that I had to use urlencode instead of htmlencode.

If I have a link that someone else entered in a form, how can it be safe with only HTMLencode? I do not know if it´s a link within my own website or if it´s to an external website. In theory, it can look exactly like the link in my first example where I used urlencode of a variable that was only a part of the link.

I read in this forum https://stackoverflow.com/questions/205923/best-way-to-handle-security-and-avoid-xss-with-user-entered-urls about someone who has similar issue and from that post I thought it's very dangerous and nearly impossible to protect agains XSS displaying an external url?

I also spent hours Googling for a classic asp regexp that is able to verify that it is an external link without dangerous content but could not find anything.

3
<a href=”http://www.mypage.com/page.asp?var1=<%=server.urlencode(var1)%>”>

Here you are here injecting content into a URL component, inside HTML. So in principle the correct thing to do would be to URL-encode the variable, and then HTML-encode the output of that:

<a href="http://www.mypage.com/page.asp?var1=<%= Server.HTMLEncode(Server.URLEncode(var1)) %>">

However, in reality the shorter form with just URLEncode is still safe because it just so happens that the output of URLEncode never produces any character that is special in HTML. So that's fine.

<img src=”http://www.mypage.com/images/<%=server.urlencode(var1)%>”

There is a minor problem in this one, but not one that causes XSS: the Classic ASP URLEncode method treats the space character specially, encoding it as +. This is a short-form that only works in query strings; for path parts a space has to be written as %20; a plus just means a plus, so if you have a filename with a space in, this won't link to it properly.

Some platforms always encode to %20 and some have options or different methods to produce URL-encoded components for use in a path (eg in PHP, rawurlencode). Unfortunately Classic ASP doesn't do either of those things, so if you need to get this right you have to define your own function that does URLEncode then replaces + with %20 manually.

(Aside: you have smart quotes throughout your code. This is probably just an artefact of copy-pasting through a word processor, but if you actually used them in your source lots of things would break.)

  • Thank you so much for your detailed explanation! Yes, the quotes are from copy-pasting through word. The images don´t contain any space character so it would not be a problem. Instead I have a problem with urlencode an external link, If you have time please see my edit in my first question. – ASP XXS Dec 13 '14 at 15:27
  • urlencode doesn't encode a URL. It encodes data to go inside a component of a URL. If you already have a URL, you don't need to URL-encode it (unless you want to put a URL inside a query in another URL!). When you insert content into a new string context, it is the context being inserted into that decides how you must escape it. In your last example, you are injecting a URL into some HTML, so you have to HTML-encode it. – bobince Dec 15 '14 at 0:41
  • “I thought it's very dangerous and nearly impossible to protect agains XSS displaying an external url?”—not really, you just have to verify that the URL you are including is of a scheme you want to support (usually, that it begins with http:// or https://) and not a dodgy one like javascript:. That's a separate issue to how you escape it when you put it on the page. – bobince Dec 15 '14 at 11:08
  • Ok, but what if I want to allow url that starts with www. too, is it ok just to check if the url starts with http://, https:// or www. or do I need to add http:// to these www. links first? – ASP XXS Dec 15 '14 at 11:31
  • You would need to add http://—www.example.com is not a URL and wouldn't work in an href. – bobince Dec 15 '14 at 17:05
1

Correct although technically you should URL encode then HTML encode for output to a HTML page. However, the ASP URL encode function URL encodes the required characters to prevent output escaping from the HTML attribute context and also does not output any characters that should be HTML encoded.

When showing an image I would also validate var1 to ensure it is a valid image path that exists on your server. For the validation, whitelist which characters you are allowing, for example alphanumerics only for the filename before the extension, and that it ends in an allowed extension (e.g. .jpg). This will prevent a user from making your page call something it shouldn't (e.g. ../Logout.asp) when the image is requested by other users. If left unvalidated this would not pose an XSS vulnerability as script cannot be embedded, however it could enable a request forgery vulnerability to be executed using your own site. Validation can take place at point of entry if you trust that it cannot be altered by any user or process once stored. If you do not trust the source where you store the image URL, then you should validate here instead.

In response to edits:

<a href="mailto:<%=server.urlencode(var1)%>">Email</a>

Yes, this is correct.

Why does http:// become %3A%2F%2F when using urlencode on a link like this? Then the link doesn't work.

<a href=”<%=server.urlencode(var1)%>”><%=server.htmlencode(var1)%></a>

If var1 is already a well formed URL then you just need to htmlencode here. The URL should be validated to check that it conforms to RFC 3986, and you should check that the protocol is HTTP or HTTPS to prevent javascript: links being inserted.

  • Thank you so much! Is it the same with e-mail addresses as with links, one should use urlencode? – ASP XXS Dec 8 '14 at 6:18
  • @ASPXXS: Not sure what you mean. Please update your question with an example then let me know. – SilverlightFox Dec 8 '14 at 11:10
  • Path components are supposed to be URL-encoded. You can only (sometimes) get away without it because browsers tend to autocorrect your mistakes. Although it doesn't cause XSS, this fails for characters like ?, # and in many cases for non-ASCII characters. – bobince Dec 8 '14 at 14:57
  • If I validated the image (e.g. the extension) when it was uploaded and var1 contains the filename stored in a database, do I still have to validate it when shown on the website? – ASP XXS Dec 13 '14 at 13:22
  • @ASPXXS: No, if all code paths that can write to the database table pass through this validation process. – SilverlightFox Dec 13 '14 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.