What characters are unsafe in query strings?

Depending on what technology you're using, there is usually a built-in function that will handle this for you.

ASP.NET (VB) & Classic ASP

myUrl = Server.UrlEncode(myUrl)

ASP.NET (C#)

myUrl = Server.UrlEncode(myUrl);

PHP

$myUrl = urlencode($myurl);

If you simply would like to remove unsafe characters, you would need a regular expression. RFC 1738 defines what characters are unsafe for URLs:

Unsafe:

Characters can be unsafe for a number of reasons. The space
character is unsafe because significant spaces may disappear and
insignificant spaces may be introduced when URLs are transcribed or
typeset or subjected to the treatment of word-processing programs. The characters "<" and ">" are unsafe because they are used as the
delimiters around URLs in free text; the quote mark (""") is used to
delimit URLs in some systems. The character "#" is unsafe and should
always be encoded because it is used in World Wide Web and in other
systems to delimit a URL from a fragment/anchor identifier that might follow it. The character "%" is unsafe because it is used for
encodings of other characters. Other characters are unsafe because
gateways and other transport agents are known to sometimes modify such characters. These characters are "{", "}", "|", "\", "^", "~", "[", "]", and "`".


I need to prevent the characters that cause vulnerabilities

Well, of course you need to URL encode, as the answers have said. But does not URL encoding cause vulnerabilities? Well, normally not directly; mostly it just makes your application break when unexpected characters are input.

If we're talking about web ‘vulnerabilities’, the most common ones today are:

  1. Server-side code injection, compromising your server
  2. SQL injection, compromising your database
  3. HTML injection, allowing cross-site scripting (XSS) attacks against your users
  4. Unvalidated actions, allowing cross-site request forgery (XSRF) attacks against your users

These are in order of decreasing seriousness and increasing commonness. (Luckily few web site authors are stupid enough to be passing user input to system() these days, but XSS and XSRF vulnerabilities are rife.)

Each of these vulnerabilities requires you to understand the underlying problem and cope with it deliberately. There is no magic list of “strings you need to block” that will protect your application if it is playing naïve about security. There are some add-ons that do things like blocking the string ‘<script>’ when submitted, but all they give you is a false sense of security since they can only catch a few common cases, and are usually easy to code around.

They'll also stop those strings being submitted when you might genuinely want them. For example, some (stupid) PHP authors refuse all incoming apostrophes as an attempt to curb SQL-injection; result is you can't be called “O'Reilly”. D'oh. Don't block; encode properly.

For example, to protect against SQL injection make sure to SQL-escape any strings that you are making queries with (or use parameterised queries to do this automatically); to protect against HTML injection, HTML-encode all text strings you output onto the page (or use a templating/MVC scheme that will do this automatically).

My sample URL http://localhost/add.aspx?id=4;req=4

Is there supposed to be something wrong with that URL? It's valid to separate two query parameters with a ‘;’ instead of the more common ‘&’, but many common web frameworks lamentably still don't understand this syntax by default (including Java Servlet and ASP.NET). So you'd have to go with ‘id=4&req=4’ — or, if you really wanted that to be a single parameter with a literal semicolon in it, ‘id=4%3Breq%3D4’.


http://en.wikipedia.org/wiki/Query_string#URL_encoding

See also: http://tools.ietf.org/html/rfc3986#section-2.2