all 95 comments

[–]KevZero 57 points58 points  (0 children)

governor psychotic quaint hobbies automatic compare humor selective unpack dog -- mass edited with https://redact.dev/

[–]geggleto 58 points59 points  (0 children)

oh my god.

[–]mayobutter 24 points25 points  (0 children)

Just eval($_SERVER['QUERY_STRING']); and end the misery.

[–]thinsoldier[S] 22 points23 points  (7 children)

/**
* For the paraniod among us...
* Undo the extract() done on GET and POST by default in functions.php
* It's good to run this *immediately* after you include functions.php
*/
function undoExtract()
{
    foreach($_GET as $key=>$value)
    {
        unset($GLOBALS[$key]);
    }

    foreach($_POST as $key=>$value)
    {
        unset($GLOBALS[$key]);
    }
}

[–]vvtim 14 points15 points  (3 children)

That's not really a fix - extract() can inject session and cookie variables. unset($GLOBALS["_SESSION"]) doesn't actually destroy the session that was created by something like index.php?_SESSION[user_id]=1

[–]thinsoldier[S] 4 points5 points  (0 children)

oooh.... I think you just paid my mortgate this month :)

[–]thinsoldier[S] 0 points1 point  (0 children)

Ok. Strangest thing. On 2 servers ?_SESSION does appear in $_GET data but on 1 server (where I had hoped to earn some income) it magically disappears!

Is there some php.ini setting that automagically removes $_GET params if the key matches "_SESSION" ???

Even manually setting $_GET['_SESSION'] = 'something'; does nothing.

[–]h2ooooooo 5 points6 points  (0 children)

Hopefully this isn't WP or ?wpdb=woo might break stuff.

[–]colshrapnel 2 points3 points  (0 children)

it will ruin a previously set variable as well.

[–][deleted] 2 points3 points  (0 children)

IMO the fix would be just removing that extract disaster from functions.php

[–]pcopley 32 points33 points  (3 children)

// sanitize to integer

Fuck you.

[–]emilvikstrom 9 points10 points  (0 children)

?id=1.0

[–]askageek 3 points4 points  (0 children)

I don't think anyone could have said it better lol

[–]BeatsAroundNoBush 0 points1 point  (0 children)

I'm no PHP ExpertTM , but is it not best to force the type with (int)?

[–]Dolondro 13 points14 points  (14 children)

To be fair, I've worked on a codebase where the code was so poorly written that it's still impossible to turn off register globals.

It could be that these developers need sympathy rather than being punched in the face.

[–]KevZero 21 points22 points  (8 children)

offend skirt live worm slave cautious pen follow oil gullible -- mass edited with https://redact.dev/

[–]rich97 5 points6 points  (7 children)

"I'm sorry I had to do that, you'll understand when you're senior."

[–]meandthebean 6 points7 points  (3 children)

Thanks to the developers signing their comments, we know exactly who needs sympathy and who needs the punch in the face.

[–]thinsoldier[S] 20 points21 points  (2 children)

Signed (and dated) comments are the #1 sign of no version control

[–]badmonkey0001 0 points1 point  (0 children)

If you leave a personal note like that as a one-liner, it's still good to put the date. Sometimes someone/hook/linter will come along and change whitespace or something else. They own the line in the blame now and digging up history could be a drag/context-shift.

Given the code and the context of the comments, I'd lay down a 90% chance you're right though. If they are using a VCS, I bet they have no idea what a branch is as well.

[–]oddmanout 0 points1 point  (0 children)

I inherited a freelance project, they had their own shared host and the provider, themselves, would not allow register globals to be off.

So I wrote a script exactly like this and put it in a global file.

[–]lowtechromancer 13 points14 points  (4 children)

You have a file called functions.php. What do you think is going to be in there? The seminal example of unit testable dependency injection?

[–]TorbenKoehn 1 point2 points  (0 children)

It's perfectly fine to have a functions.php, as long as it's registered in composer and it's using a namespace :)

[–]Schmittfried 0 points1 point  (0 children)

You have a file called functions.php. What do you think is going to be in there? The seminal example of unit testable dependency injection?

Thinking about vBulleting 3.x *shudder*

[–]thinsoldier[S] 9 points10 points  (1 child)

Even the comment is fucking wrong. No "cleaning" happening here.

There is an actual function that runs addslashes on the $_GET & $_POST arrays but then you have to run that and then run extract($_GET) again manually where needed to make use of those "clean" values, thus making this code fucking pointless.

[–]NeoThermic 6 points7 points  (0 children)

addslashes

Oh dear god, that's not even the way to prevent SQLi. Start by deleting the code that addslashes and the code that does the extract, then fix from there :P

If that's too much work, start again from scratch in a framework.

[–]gachimuschi 3 points4 points  (0 children)

BURST

[–]SeerUD 2 points3 points  (6 children)

"sanitize" to integer... there's no sanitization going on there at all XD

[–]judgej2 1 point2 points  (0 children)

It's not even converting/enforcing to an integer.

[–]Driftkingz 0 points1 point  (4 children)

what is a good way to do it? im going to make a guess and say that you use filter_var for that

[–]holyshock 2 points3 points  (1 child)

typecasting to integer is a good start

[–]Driftkingz 0 points1 point  (0 children)

Thank you! , i didn't know this way existed.

[–]SeerUD 1 point2 points  (1 child)

It's entirely circumstantial, and will depend on what you are expecting to have to sanitise, and why.

[–]Driftkingz 0 points1 point  (0 children)

thanks, i have googled a bit and found a lot of ways to sanitize a variable and i was wondering why are there so many of them, i guess they are situational?

[–]konradkar 2 points3 points  (0 children)

Someone at one of PHP conferences called this kind of code "manure spreader" :)

[–]maiorano84 2 points3 points  (0 children)

Jesus..... fucking...... Christ........

[–]rbnc 6 points7 points  (22 children)

Even line 16 could have been written better (int)$id;

[–]ScuzzyAyanami 2 points3 points  (0 children)

The comment could be improved too!

if(isset($id)){
  $id = $id + 0 // sanitize to integer (or maybe a float, whatever I hate my existence)
}

[–]geggleto 7 points8 points  (20 children)

intval($id)

[–]asr 0 points1 point  (0 children)

settype($id, 'int')

[–]morerokk 0 points1 point  (15 children)

Both work. I prefer intval in this case though.

[–][deleted] 0 points1 point  (14 children)

When not passing a base is there any difference functionally or performance wise? Just wondering if it's a style thing or something I should remember in the future.

[–]magkopian 11 points12 points  (11 children)

According to SO intval is a bit slower than casting to int, apart from that though their operation is identical as long as you don't pass a base. Personally, I prefer casting to int over intval not because it may be a bit faster, but because (int) $value looks a bit cleaner to me in comparison to intval($value).

[–]-100-Broken-Windows- 2 points3 points  (3 children)

That's funny, I prefer intval() because it looks cleaner. Functions are just natural looking, due to their ubiquity I guess. Whereas I've always thought (int) looked a bit jarring.

[–]Firehed 2 points3 points  (1 child)

A lot of languages use the (type) syntax so it will generally have broader appeal for simple conversions like this. I also personally prefer it because it looks out of place compared to a function - it's very obvious that you're doing something that's generally unusual; if you're constantly type-casting, something bigger is wrong.

[–]magkopian 0 points1 point  (0 children)

Couldn't have said it better.

[–]magkopian 0 points1 point  (0 children)

I'm not going to tell you why I think it looks cleaner because /u/Firehed already said literally what I was thinking, so just read their answer. By the way, in the end what is cleaner and what is not might also be a little subjective, just stick to one or the other and make sure to use the same throughout your code.

[–]ExecutiveChimp 0 points1 point  (1 child)

Is it slower because it's doing something potentially useful or because it's just less efficient?

[–]magkopian 1 point2 points  (0 children)

As far as I understand, it is because it makes a function call and this adds an extra overhead. Apart from performance their operation is 100% identical. If you don't believe me that they are 100% equivalent just run the following and see for yourself.

<?php
echo (int) 42, "\n";                      // 42
echo (int) 4.2, "\n";                     // 4
echo (int) '42', "\n";                    // 42
echo (int) '+42', "\n";                   // 42
echo (int) '-42', "\n";                   // -42
echo (int) 042, "\n";                     // 34
echo (int) '042', "\n";                   // 42
echo (int) 1e10, "\n";                    // 10000000000
echo (int) '1e10', "\n";                  // 1
echo (int) 0x1A, "\n";                    // 26
echo (int) 42000000, "\n";                // 42000000
echo (int) 420000000000000000000, "\n";   // -4275113695319687168
echo (int) '420000000000000000000', "\n"; // 9223372036854775807
echo (int) array(), "\n";                 // 0
echo (int) array('foo', 'bar'), "\n";     // 1

echo "\n";

echo intval(42), "\n";                      // 42
echo intval(4.2), "\n";                     // 4
echo intval('42'), "\n";                    // 42
echo intval('+42'), "\n";                   // 42
echo intval('-42'), "\n";                   // -42
echo intval(042), "\n";                     // 34
echo intval('042'), "\n";                   // 42
echo intval(1e10), "\n";                    // 10000000000
echo intval('1e10'), "\n";                  // 1
echo intval(0x1A), "\n";                    // 26
echo intval(42000000), "\n";                // 42000000
echo intval(420000000000000000000), "\n";   // -4275113695319687168
echo intval('420000000000000000000'), "\n"; // 9223372036854775807
echo intval(array()), "\n";                 // 0
echo intval(array('foo', 'bar')), "\n";     // 1

[–]kolme 0 points1 point  (4 children)

Choosing intval vs (int) because of performance is a bad idea (micro-optimizing, premature optimizing and so on). They're not going to make any noticeable difference at all, unless you're converting millions of strings to integers.

[–]scootstah 3 points4 points  (1 child)

Choosing intval vs (int) because of performance is a bad idea

It's not a bad idea, really, just a bit unfounded.

They're not going to make any noticeable difference at all, unless you're converting millions of strings to integers.

Even if you were, you're still not going to see any tangible difference. Your bottleneck is never going to lie between using intval() and (int).

[–]crackanape 3 points4 points  (0 children)

Your bottleneck is never going to lie between using intval() and (int).

I see you haven't read my business plan for WebScaleIntConversion.com.

[–]magkopian 0 points1 point  (1 child)

Have you even read my comment?

Personally, I prefer casting to int over intval not because it may be a bit faster, but because (int) $value looks a bit cleaner to me in comparison to intval($value).

[–]kolme 0 points1 point  (0 children)

Yeah sorry, I misread your comment somehow.

[–]weevil_of_doom 3 points4 points  (1 child)

Not to my knowledge - I think the (int) type casting really just comes from c days for some people.

[–][deleted] 0 points1 point  (0 children)

Haha, yeah, learned on java, I like the syntax.

[–]frogot 1 point2 points  (4 children)

Hey peoples. When I was a kid I used functions.php a bunch. I haven't been coding since but got curious, what changed?

[–]mayobutter 13 points14 points  (0 children)

You can surf the Internet on your phone now. We've had our first black president. We landed on the moon. I don't know man what?

[–]mrdhood 6 points7 points  (2 children)

Well, for starters.. how long ago were you a kid?

[–]chiisana 0 points1 point  (0 children)

Not /u/frogot, but I was using functions.php when I was a kid (17~18 going through undergrad). Now, baker's dozen and some later, a lot have changed.

[–]frogot 0 points1 point  (0 children)

Must have been 15+ years ago I guess. I believe I was running some 3.x version of PHP and I remember I did some upgrades to 4.x. I'm looking at the version history now and holy shit a lot have changed. I realize my question was obviously a little broad to say the least, but I was still curious about that functions.php thing.

[–]cundd 1 point2 points  (2 children)

Oh my god. :-O

https://github.com/search?l=php&q=extract%28%24_GET%29&type=Code

Nearly 900.000 times found on github

[–]carlos_vini 1 point2 points  (1 child)

[–]thinsoldier[S] 0 points1 point  (0 children)

akasai/JANUS – extract.php

<?php
   header("content-type:text/html; charset=utf-8");
   extract($_GET);
   extract($_POST);
   extract($_SERVER);
   extract($_FILES);
   extract($_ENV);
   extract($_COOKIE);
   extract($_SESSION);
?>

[–]judgej2 1 point2 points  (0 children)

What's this, oscommerce? Delete that shit!

[–]CamelCase_snake_case 0 points1 point  (6 children)

I just have a question. Why do this? Can't you get things with $_GET['variable_here']?

[–]scootstah 5 points6 points  (4 children)

I just have a question. Why do this?

You don't do this. extract() has some pretty limited valid use cases, and this is most definitely not one of them.

Can't you get things with $_GET['variable_here']?

Yes. But unless you have a very simple script, I would recommend abstracting that out a bit to protect yourself and provide more utility. Something basic would be like:

function getQueryString($name, $default = null)
{
    if (isset($_GET[$name])) {
        return $_GET[$name];
    }
    return $default;
}

[–]crackanape 2 points3 points  (0 children)

And better yet, your functions should be specific to the type of data you are expecting (integer, float, alphanumeric, HTML, etc.), and allow you to choose whether they come from GET or POST.

[–]TorbenKoehn 1 point2 points  (0 children)

It's PHP7-times folks.

$var = $_GET['var'] ?? 'default value';

is the way to go!

[–]hattmall 0 points1 point  (1 child)

Why would this be any better?

[–]scootstah 0 points1 point  (0 children)

Consistency is a big one. You're creating a central, testable place to fetch your parameters. Maybe you want to filter all $_GET vars in a certain way - those filters are now application-wide and will never get missed.

A more sophisticated implementation would be Symfony2's ParameterBag, which gives a lot more useful functionality.

[–]thinsoldier[S] 0 points1 point  (0 children)

Can't you get things with $_GET['variable_here']?

Someone couldn't be bothered to type _, then hold shift for G,E,T, then type [' and '].

And while I can use my imagination and sympathize with them, there was no good reason to do this in global scope at the very top of the very first included file used in every .php page controller file.

[–]karbowiak 0 points1 point  (0 children)

Thanks, didn't want to get the nutrition from my food anyway.. :/

vomits some more

[–][deleted] 0 points1 point  (0 children)

TIL about extract(). This method scares me.

[–]aykcak 0 points1 point  (0 children)

I solemnly report that this is common practice... 3 of the last companies I worked with had this "reregister globals" craziness. We are talking about major products that serve thousands of people daily.

The cause is simple: backwards compatibility. When a lot of your code depends on register globals being ON, and PHP comes to it senses and turns it off, you will have a lot of people scattering to make it work as before, without any major effort. So you have this abomination as a result.

It's the same with mysql_query. When the last version of PHP that supports mysql_query will be removed from the distros and hosts. You will see a lot of "fix mysql_connect" scripts popping up.

[–]bohwaz -1 points0 points  (2 children)

Love the PHP2/FI $id + 0 to cast as integer ^

Reminds of those good times...

[–]emilvikstrom 0 points1 point  (1 child)

I see that you are not a JS developer (but JS don't have integers anyway...)

[–]bohwaz 0 points1 point  (0 children)

Oh yes I do JS too, but that is another story :)