-3

In my application, an attacker can pass in the URI something like this:

http://domain/someapi?entryId=d2rf<script>alert("gotcha")</script>f334&param2=....

What are the steps that I need to take to prevent it. I can't seem to find a good answer for this, even in OWASP site. According to OWASP every character with ascii value of less than 256 is ok.

I also don't want some very generic solution such as sanitizing each param by striping it's <> signs.

Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
Alon1980
  • 1,225
  • 1
  • 16
  • 30
  • Is that an actual example of an attack that works? Are you blindly executing any javascript in the ID like that? They don't need to surround it with ` – Gray Aug 03 '15 at 17:46
  • Darn, stack overflow stripped it. There are script tags. – Alon1980 Aug 03 '15 at 18:15
  • Oh, duh. I should have checked the source. I edited it for you. – Gray Aug 03 '15 at 18:15
  • [ASCII](https://en.wikipedia.org/wiki/ASCII) actually has only characters with byte value between 0–127. – Gumbo Aug 03 '15 at 18:18
  • 1
    "According to OWASP every character with ascii value of less than 256 is ok" — You've misinterpreted what OWASP is saying. – Quentin Aug 03 '15 at 18:18
  • possible duplicate of [Protection against XSS exploits?](http://stackoverflow.com/questions/5414962/protection-against-xss-exploits) – Quentin Aug 03 '15 at 18:19
  • The steps you need to take to defend against XSS depend on (a) Where you are going to put the data and (b) If you are expecting text, a safe subset of HTML, or something else. There's no way to tell either of those from your question. – Quentin Aug 03 '15 at 18:22

2 Answers2

3

OK, let's use an example. You have a search page that takes a GET parameter for the search query.

http://example.com?search=test+search

On your search page, you do something like this.

<p>your search results for "{search}":</p>

This is vulnerable to reflected XSS. The following query:

http://example.com?search=<script>alert(1);</script>

would result in the following HTML:

<p>your search results for "<script>alert(1);</script>":</p>

Obviously, that's not good, as it will execute the script (well, the XSS Auditor will probably block it, but we don't depend on that). The first thing we can do to help prevent XSS is to escape this string since it is un-trusted and comes from the client.

<p>your search results for "{HTML.Escape(search)}":</p>

The syntax for this, of course, depends on your server-side language. In general, you are looking for HTMLEncode/Escape/etc. I'm sure someone can point you to a function or library for doing this in PHP.

Now that we escape the string, our output would look like this:

<p>your search results for "&lt;script&gt;alert(1)&lt;/script&gt;":</p>

That will show up as < in the browser, but the source will be encoded (&lt;).

This is the general overview of preventing most XSS. Manually escaping every input can be a little risky, cause you might forget one. So you want to use some kind of templating system. There are different things you do for HTML attributes/javascript strings/html entities, etc.

Google has a great introductory resource for this:

https://www.google.com/about/appsecurity/learning/xss/#PreventingXSS

Community
  • 1
  • 1
Gray
  • 7,050
  • 2
  • 29
  • 52
2

According to OWASP every character with ascii value of less than 256 is ok.

What? No. XSS prevention depends on context! I'm also very sure that OWASP doesn't regard every ASCII value less than 256 as okay, since ASCII is only defined for characters 0 - 127.

I also don't want some very generic solution such as sanitizing each param by striping it's <> signs

If an attacker supplies malicious Javascript code in a URL parameter, you cannot prevent them from doing that. What you can do is make sure your application doesn't blindly echo this value back to the user, or else you've opened the door to a reflective cross-site scripting vulnerability.

Do you need to accept and reflect (display) arbitrary HTML code?

  • Yes: Use HTML Purifier.
  • No: One of the following should be safe to use:
    • htmlentities($yourStringVariable, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    • For URLs only: http_build_query($yourArrayOfKeysAndValues); or urlencode($string);

Demo: http://3v4l.org/itUZX

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206
  • according to what you say and what @Gray mentioned it sounds like you will do the checking before rendering the html. to me it sounds weird. why not do it when the controller receives the request? in addition, if your server uses a string as id and the view will render it differently because it stripped some chars from it, the user will have the wrong id. – Alon1980 Aug 03 '15 at 20:12
  • "to me it sounds weird. why not do it when the controller receives the request?" This is a form of premature optimization. If you're going to store information in a database, store it verbatim (not escaped) so it can serve as the sole, unaltered source of truth and then escape it while rendering the page. (Use prepared statements.) – Scott Arciszewski Aug 03 '15 at 20:31
  • In a similar vein, if you're going to escape it in the controller, you deprive yourself of the ability to store it verbatim in the database. You lose your single source of truth, since it was altered before input. – Scott Arciszewski Aug 03 '15 at 23:45
  • but if the "truth" contains script tags, i guess i won't want it - i will prefer to have something more safe and clean. – Alon1980 Aug 04 '15 at 04:26