PHP with HTML Forms
This page introduces having a HTML Form on the client
and a program on the server.
We will use PHP for the program.
We will imagine something like a search engine.
The user types in a term on the client and presses a button.
The term is sent to the server-side PHP program for processing.
The client side is implemented as a
HTML Form
using the
<form>
tag.
Embed something like the following
in your page.
<FORM METHOD="GET" ACTION="prog.php">
Enter argument:
<INPUT size=40 name=q id=q >
<INPUT TYPE="submit" VALUE="Submit">
</FORM>
- Change "prog.php" to point to your PHP program to process the form.
We will see how to write such a program below.
-
The input field above is called "q".
You can change it to a different name, but the PHP must know what name to expect.
The form makes a call to the PHP program like:
http://host/prog.php?q=value
This is
HTTP GET.
The data appears in the URL.
Like Google search:
search?q=biscuits
PHP to process the form
The input comes in as the environment variable QUERY_STRING,
which is the part of the URL after the question mark.
With one input, QUERY_STRING looks like:
x=value
With multiple inputs, QUERY_STRING looks like:
x=value&y=value&...&a=value
Either way, PHP can parse the QUERY_STRING
into an array of inputs
using
parse_str
$qs = $_SERVER["QUERY_STRING"];
parse_str ( $qs, $a );
// get the q= input:
$q = $a["q"];
print " q is $q ";
- See also $_GET
- Use
isset
to see if the incoming variable exists.
Try it out
More on parsing the input
You do not have to parse the URL in the body of the HTML.
You can parse the URL
early
so can use the variables in the head section of the page (e.g. in the title):
<html>
<?php
$qs = $_SERVER["QUERY_STRING"];
parse_str ( $qs, $a );
$q = $a["q"];
?>
<head>
<?php
print "<title> Page for q = $q </title> ";
?>
</head>
Hacking attack: Overwrite PHP vars
parse_str can be done in a single line:
$qs = $_SERVER["QUERY_STRING"];
parse_str ( $qs );
// $q is now defined as whatever the value was in the URL section: q=value
print " q is $q ";
But this is not safe.
This
overwrites any existing variables.
A hacker might construct a URL to overwrite some other PHP variables.
Q. Construct an example.
So do not use this.
Use the "parse into an array" method.
The above PHP program, even with "parse into an array",
is still not safe.
Any program put on the web will be a target for hackers - either in person or using bots to find forms.
So what is the problem?
Construct your own PHP page as above.
(My version already has the security, so you need to make your own copy to see.)
Now consider the following attacks:
Hacking attack: Inject HTML, CSS, JS
- HTML injection:
-
Enter HTML in the form like <h1>. It will appear on the output page.
-
Enter <img src=(some image at a remote site)>. You have now made that image appear on the page at DCU.
-
You can inject any HTML into the page at DCU.
This can grossly mislead people.
- CSS injection:
- Enter CSS that changes the body to have display:none
- If the form is to enter comments, and comments are displayed on the site's webpages, you can now blank the entire website!
- JS injection:
- Enter: <script> alert("hello"); </script>
- The browser may or may not block this.
But that is irrelevant because the hacker can use a client that does not block this.
- The site firewall may block this. Or it may not.
- Hackers might be able to make
Cross-site scripting
attacks.
These can be very serious attacks on your web app.
Click to run World:
Websocket chat at
Ancient Brain.
This chat program at Ancient Brain
deliberately has no protection against HTML or CSS injection.
So you can inject HTML or CSS or JS into the other user's page.
Try it!
Solution to HTML/CSS/JS injection
We need to sanitise all user supplied data, including user supplied URL.
See
htmlspecialchars.
$qs = $_SERVER["QUERY_STRING"];
parse_str ( $qs, $a );
$q = $a["q"];
// convert all HTML chars to &nnn;
// including both types of quote
$q = htmlspecialchars ( $q, ENT_QUOTES );
print " q is $q ";
Try it out
Output other than HTML
The PHP does not have to output HTML tags.
It can use the
Content-Type: HTTP header
and a
MIME type.
Here is a PHP file that outputs a JPEG, with no HTML.
This is the entire PHP file:
<?php
// tell browser what content type to expect
header ( "Content-Type: image/jpeg" );
// pick image at random from
// https://commons.wikimedia.org/wiki/File:Leonardo_da_Vinci_-_Plan_of_Imola_-_Google_Art_Project.jpg
// https://commons.wikimedia.org/wiki/File:Da_Vinci_Vitruve_Luc_Viatour.jpg
if ( rand(0,1) ) // returns 0 or 1 randomly
readfile ( "Images/da.vinci.1.jpg" ); // read file and dump to stdout
else
readfile ( "Images/da.vinci.2.jpg" );
?>
See Working example.
Reload
for other image randomly.
You can also send arbitrary-length data (contents of large forms, uploaded files, etc.) to PHP.
You send this with
HTTP POST.
The data does not appear in the URL.