views:

50

answers:

6

I'm probably being a little thick, but I can't seem to find an answer to this one. I'm moving from a server with register globals ON to one with it being off. It's a good thing, but unfortunately I have been used to years and years working with register globals being ON which has resulted in me writing sloppy code. I am now trying to fix that.

I'm trying to rewrite some old code which has variable variables within $_POST.

I know this is a silly example, but it illustrates the problem I am trying to solve. The following would work with register globals ON:

<?php $variable = "fullname";?>
<form action="/test/" method="post">
<label for="fullname">Full Name:</label> <input name="fullname" type="text" value="<?php echo $$variable;?>" size="20" maxlength="150" />
<input name="submit" type="submit" value="Go!" />
</form>

How do I make this work with register globals off? The following obviously doesn't work:

<?php $variable = "fullname";?>
<form action="/test/" method="post">
<label for="fullname">Full Name:</label> <input name="fullname" type="text" value="<?php echo $_POST[$$variable];?>" size="20" maxlength="150" />
<input name="submit" type="submit" value="Go!" />
</form>

Please go easy on me- I know I am probably being stupid, but I can't seem to get my head round this.

+2  A: 

I have some form interactions similar to yours but I can;t understand why you are using $_POST within a form. What you should have is this:

<?php $variable = $_POST["fullname"];?>
<form action="/test/" method="post">
<label for="fullname">Full Name:</label> <input name="fullname" type="text" value="<?php echo $variable; ?>" size="20" maxlength="150" /> 
<input name="submit" type="submit" value="Go!" />
</form>
Daniel Hanly
Daniel, technically the way he is doing it is no different then the way you are doing it. Except for the fact you are now creating another variable. While this isn't intensive at all on the modern day webserver it is nice to note that you are basically just playing a cup and ball game with the variable.
Nick Shepherd
As I said, the above code was a silly example and is not the actual code I am using.
baritoneuk
The difference is that I'm picking the $_POST up in the PHP above the form and not in the form itself. It's more organised that way and less likely to break
Daniel Hanly
+5  A: 

Simple, just $_POST[$variable]. (Or $_GET or maybe $_REQUEST, as appropriate.)

However note that when you output text to HTML, you must encode it, or you will be vulnerable to cross-site-scripting attacks:

<input type="text"
    name="<?php echo htmlspecialchars($variable);?>"
    value="<?php echo htmlspecialchars($_POST[$variable]);?>" 
    size="20" maxlength="150"
/>

(I typically define a function called h that does echo htmlspecialchars, to cut down on this excessive amount of typing.)

bobince
I do feel silly now- so simple! I hope I am not the only one who suffers from the occasional brain freeze!
baritoneuk
By the way, I'm running lots of security checks on the variable anyway to detect any cross scripting stuff, but I think the example you have of htmlspecialchars is a good, quick and simple one.
baritoneuk
I would be worried about “detecting XSS” on the input. At a basic level, that's not how string escaping problems work. Every input-based attempt to counter XSS is doomed to failure: it will block perfectly valid input (like eg. here where I'm typing `<script>` into SO's comment box) whilst failing to prevent every possible attack. HTML-escaping is entirely an output-stage issue and should be tackled exclusively at the point HTML is being generated. That's not to say all input validation is worthless, just that you can't solve escaping issues through blanket application of input filtering.
bobince
+1  A: 

$_POST is an array, won't it just be.

$_POST[$variable]
Viper_Sb
+1  A: 

You sure you meant $_POST[$$variable] as opposed to $_POST[$variable]

SubSevn
+1  A: 

you can get rid of the whole $$ craziness and simply do $_POST[$variable].

Nick Shepherd
A: 

Using variable variables directly from $_SUPER globals is a BAD idea and a security risk, especially if any of your code is open source. One could modify the input to poke around and find out the value of any variable you let through. For example, they could pass in '$_ENV' which would get them a dump of your environment variables. In fact, register globals is a bad idea anyways.

This is referred to in @bobince's answer.

And, with regard to your question, that is why your example doesn't work with PHP's register globals turned off. PHP is stricter (for good reason) with register global's off, afaik, it's harder to do the variable variable trick.

nessence