views:

67

answers:

4

I'm creating a wizard-based series of forms for taking user inputs. One of the requirements for that wizard is that the script (PHP) cannot save the inputs into the database (MySQL) until the user clicks the 'Save' button, so I have to device a mechanism to transport user inputs in one form to another when the user clicks 'Previous' or 'Next' buttons. I looked into using various methods including cookies, sessions, temporary files etc, but I settled for embedding base64_encoded serialize data in a hidden field that exists in all the forms in the series. The value in this field will be decoded on form submissions and re-encoded for putting in the next form after other values from the current form are inserted.

Here is a sample of how the hidden field looks:

<input type="hidden" name="wizard:presave" value="YTo2OntzOjU6InRpdGxlIjtzOjEwOiJRdWVzdGlvbiAyIjtzOjQ6InRleHQiO3M6MTk6IlllcyBpdCdzIGEgcXVlc3Rpb24iO3M6NDoidHlwZSI7czo2OiJjaG9pY2UiO3M6NzoiY2hvaWNlcyI7YTowOnt9czo1OiJwb2ludCI7aToxO3M6Mjoib3AiO3M6MTM6ImVkaXRfZXhlcmNpc2UiO30=" />

So the questions are:

  1. Is it considered a good/bad practice?

  2. Is there any length limit of hidden fields in HTMLform?

  3. What are the possible security issues?

  4. And are there better alternatives? (with explanations, preferably without using javascript)

Thanks in advance!

A: 

Well, you can store into the session either by serializing or just simply store it the way it is for each step. When the user clicks Save, you grab and validate the data from all the steps in the session.

thephpdeveloper
A: 

tsk tsk :)

  1. Is it considered a good/bad practice? subjectively - bad practice..you're using the wrong hammer for the job.

  2. Is there any length limit of hidden fields in HTMLform? - Not sure if there is a limit.

  3. What are the possible security issues? - Possibly, quite a few, but you can sanitize the data received for every request. Besides, the data is pretty easy to decode and can be easily modified on the client side (I can see that its some sort of json that you are using :) )

  4. And are there better alternatives? (with explanations, preferably without using javascript) - Use the right tool .. sessions perhaps?

And yes... You are most likely going to face performance and scalability issues (should you have a substantial user load) with all that sanitizing, parsing, formatting and security code running for every request.

Ryan Fernandes
+1  A: 
  1. I've never seen this particular method of parameter passing in my career, so I can't say whether it's good or bad. It's certainly not "standard". Standard methods would either be passing the submitted method along (unencoded/normally) using hidden inputs, or storing in session. I think you might be making work for yourself, so in that sense it would lean towards "not ideal".

  2. As long as you are using POST for your forms, there is no defined limit for data sizes that I'm aware of in the HTTP specifications. Older servers may have practical limits, but unless you're doing something extreme such as media file uploads, they shouldn't be a worry.

  3. Possible security issues are the normal web security flaws. Anything you take from a user and re-output to a page could contain cross-site scripting vulnerabilities and would have to be properly sanitized (this is somewhat moot if you're encoding everything). Users can craft their own data and submit it if they like. Basically, assume all the data you handle is unsafe and tainted.

  4. Sessions would work much better here. The data the user submits wouldn't have to go through a lengthy encoding process. As well, you'd only have to validate it once. After it's been submitted and validated, you can simply store it on the server in $_SESSION and leave it alone until the final button is clicked. Otherwise, you have to worry about re-outputting it, re-receiving it, and re-validating it at each step. A malicious user could submit one set of data, have it checked and re-output as encoded data, but then craft the next form submission by unencoding, changing data, and re-encoding.

I would highly recommend that you reconsider sessions, as it simplifies all your data operations into a "do-once" scenario.

zombat
i reconsidered using session and it works, although I still have to device a randomized 'instance id' to pass between submissions so that the user can have the multiple wizard instances running on the same sessions without interfering each other. but will it introduce other security issues like the user messes up with the instance id etc?
Lukman
I don't think so. As long as you store your randomized value properly inside the session, then the only parameter available for manipulation is the session token itself.
zombat
implemented and it's working great. all answers here are good but this one gives the best explanation. thanks.
Lukman
+1  A: 

Is it considered a good/bad practice?

Depends on the purpose. As far I've only seen such constructs as a client side URL hash to remember the state of the selections in large ajax-based applications (so that they are bookmarkable) and then often also Gzipped to make it shorter. In your speficic case I'd say: make use of the HTTP session and only pass a request based identifier (also called token) in the hidden field so that you can get the associated information from the session.

Is there any length limit of hidden fields in HTMLform?

In GET the complete query string (all parameter names and values and separators together) is usually limited to 2048 characters, but you can better adhere an officious limit of 256 chars. In POST it is dependent on server configuration. Often this defaults around 2GB.

What are the possible security issues?

Well, it is obviously decode-able.

And are there better alternatives? (with explanations, preferably without using javascript)

You could Gzip it to make it shorter and less obvious. Or, as already said, make use of the session in combination with a request based identifier.

BalusC
tried gzip after base64_encode but it breaks the html structure. gzip before base64_encode gives almost the same length of string. +1 anyway ;)
Lukman