How to Create Multi-Page Forms in PHP, Revisited

A couple weeks ago, I wrote a short article about how to create a multi-page form.

The simple solution I suggested involved a foreach loop that cycled through the $_POST array and sent every value along in a hidden input element. After a bit of reflection (and some useful comments), I realized there’s a teeny tiny security hole in that approach – so I’ve slightly modified it to close the loophole.

The Multi-Page Form Snippet

The old snippet of code looked like this…

foreach ($_POST as $key => $val) {
  echo '<input type="hidden" name="' . $key . 
    '" value="' . $val . '" />' . "\r\n";
}
The Security Loophole

What’s the problem? If someone enters a quote into the form, it could break all of the hidden elements. Here’s an example.

Let’s say I type this into a text input.

" /><input type="text" name="newField" value="newValue

The next page would create this…

<input type="hidden" name="firstField" value="" />
<input type="text" name="newField" value="newValue" />

By adding a quote, you prematurely end the first hidden element and can add new html tags. You can combine this with javascript for some potentially nasty effects. I guess. I’m really not sure what you could do with this… but it’s better to be safe than sorry, eh?

How to Fix the Multi-Page Form Snippet

We can close this loophole once and for all with a simple function call – htmlentities. With the proper parameter, this will encode all html entity characters (including quotes), so that the user can’t input a quote or create new HTML tags.

foreach ($_POST as $key => $val) {
  echo '<input type="hidden" name="' . $key . '" value="' 
    . htmlentities($val, ENT_QUOTES) . '" />' . "\r\n";
}

No more problems.

It’s also important to note that this problem isn’t just a security loophole. By not validating the input before creating the hidden element, you could accidentally break the form for a legitimate user. If the user enters a ” inside a text field, it would break the hidden element on the next page.

Why Not Use Sessions or a Database?

Some people have suggested using sessions or a database to accomplish the same thing. That’s certainly possible, but I feel this is a better design choice.

I like to keep the php and html as separate as possible. This allows us to keep all of the input inside of the form until we’re ready to process it. Meanwhile, our processing script sees all of the input as coming from a single form – even if it came from different pages.

By contrast, you need to break up your processing script to use databases. You also need to mix and match $_POST and $_SESSION to use sessions to store the information. It’s functional, but doesn’t seem elegant to me.

With that in mind, this is something of a preference. It’s not better than the other methods – but I think it is semantically more logical. So use what you prefer.

Bookmark and Share:
  • Digg
  • Furl
  • del.icio.us
  • StumbleUpon
  • MisterWong
  • DZone
  • Technorati

Tags: , , , ,

3 Comments to “How to Create Multi-Page Forms in PHP, Revisited”

  1. How to Pass All Elements of a Form to the End in a Multi-Page Form | Web Cash said this on

    [...] that there’s a possible security hole in this method. No big deal. This article that revisits multi-page forms patches the hole up nice and snug. I’d suggest you take a look at it. Bookmark and Share: [...]

  2. ppc formula said this on

    Very nice! good info

  3. Gangster59 said this on

    Sometimes I leave post-its on the desks telling people to go there. ,

Leave a Reply