php.w3clubs.com

PHP tutorials and articles

 

Accepting user input through GET

Your smart PHP application should be able to accept user input and serve different pages, depending on the user request. This is really powerful, let's see how you can achieve it.

There are different ways for a web page to accept input from the user, the most common being through GET and POST requests.

What's in a request

When a user clicks on a link or types in the address bar, he/she requests a page (a file, a resource) from a remote server. This is done through the use of the HTTP protocol, so we say that the user makes an HTTP request. The resources out there are identifiable by their URL.

Let's take a URL:
http://www.w3clubs.com/w3clubs-examples/ragtime2/index.php

What we have here:

  • The whole thing is a URL
  • http identifies the protocol
  • www.w3clubs.com is the host name
  • /w3clubs-examples/ragtime2/index.php identifies where the resource is located

Just for information, here's how an HTTP request may look like:

GET /w3clubs-examples/ragtime2/index.php HTTP/1.1
Host: www.w3clubs.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.w3clubs.com/w3clubs-examples/ragtime2/
Cache-Control: max-age=0

To see the HTTP headers being exchanged when you request and receive pages, I'd recommend using the Firefox extensions LiveHTTPHeaders or the Net panel of Firebug. For IE and other browsers on Windows you can also use Fiddler.

GET

Notice the word GET in the request above? It specifies the request method.

Now let's check this URL:
http://www.w3clubs.com/w3clubs-examples/ragtime2/index.php?key=value

The part after the question mark is called a query string, it allows you to pass parameters when making a request. You can have several query parameters, divided by an &

http://www.w3clubs.com/w3clubs-examples/ragtime2/index.php?key=value&something=else

The cool thing is that in your PHP script you have access to those parameters and can do different things, for example branch the page execution, based on different values being passed in the query string.

You can access the query string parameters (let's call them GET parameters) through the array $_GET which PHP defines for you. Let's see an example.

Example

Create the script C:\mywebstuff\htdocs\php-tutorial\get.php (how to setup here) with the following contents:

<pre>
<?php
print_r($_GET);
?>
</pre>

Now load this script in the browser, like http://localhost/php-tutorial/get.php

The result might be slightly disappointing, but it does illustrate something important - that the $_GET array is always defined. The result is:

Array
(
)

Now let's change the URL of the request to:
http://localhost/php-tutorial/get.php?key=value

The result:

Array
(
    [key] => value
)

And how about http://localhost/php-tutorial/get.php?key=value&something=else

Array
(
    [key] => value
    [something] => else
)

Never trust user input

You just learned how to get user input and now I'm telling you not to trust it. What gives?

Not trusting user input is an important lesson (that many have learned the hard way) and cannot be over-emphasized.

Let's say you have the following script:

<?php
echo 'Hello ', $_GET['user'], '!';
?>

When you request is like http://localhost/php-tutorial/user.php?user=stoyan, this is a friendly little page that greats me:

Hello stoyan!

But as a malicious user I can try adding HTML tags in my username and nothing in the script will stop me:
http://localhost/php-tutorial/user.php?user=<b>stoyan</b>

This will result in:

Hello stoyan!

So what? So far, not so bad. But why stop here? I can also pass javascript as a parameter.
http://localhost/php-tutorial/user.php?user=<script>location='http://www.phpied.com'</script>

What will happen? As soon as you load the page, you're redirected to my blog at http://www.phpied.com, because the script printed whatever was passed as 'user' parameter, so the HTML looks like:

Hello <script>location='http://phpied.com'</script!>

Redirecting to a page is bad enough, but could be worse. With javascript you have access to the browser cookies, so a malicious user can not only redirect to a new page, but also send your cookies to this page and this way steal your session. Imagine PayPal doing such a mistake. A hacker can get your session ID and put it in his browser cookies, this way logging in as you and making some payments. Scary stuff.

The take-home message here is:
When you accept user input, expect the unexpected. If you ask for example for a phone number from the user, don't assume you'll only be receiving numbers, be also prepared to deal with all kinds of characters, HTML and JavaScript strings.

What's the fix to the vulnerability above? Surprisingly simple, just use function htmlspecialchars(), it will make all > and < into &gt; and &lt; and the script will never be executed.

<?php
if (!empty($_GET['user'])) {
    echo 'Hello ', htmlspecialchars($_GET['user']), '!';
}
?>

The result displayed in the browser will be:

Hello <script>location='http://phpied.com'</script>!

because the HTML code generated will be:

Hello &lt;script&gt;location='http://phpied.com'&lt;/script&gt;!

« to the PHP tutorial table of contents

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by WordPress, theme by ♣w3clubs.com, based on Kubrik and Sancta Simplicitas