CodeSOD: Administrative Transfer

When the pandemic started, a lot of companies needed to cut back, and Initech was no exception. In the Before Times™, Initech had an offshore development team that maintained an application inherited from an acquisition. Now that everyone was tightening their belts, though, that had to go. The offshore team was released and the application they supported ended up in the hands of Lovelace.

Lovelace dug in, and they quickly discovered a few things. From 2010-2017, the application's idea of source control was a folder on an FTP server and a lot of files named some_module.php.old and some_module.php.donotuse. In 2017, someone put the project into Git, but the commits were just point-in-time snapshots of the FTP folder. Deployment? Just work right on that FTP folder, it's fine. And if you forget to commit those changes back to source control? No biggie- consider the FTP folder the source of truth.

Then again, when Lovelace saw the "truth" that was there, they weren't exactly excited to be supporting this PHP application.

if (!isset($_SESSION['ADMIN_ID']) or empty($_SESSION['ADMIN_ID']) or $_SESSION['ADMIN_ID'] == NULL) { $isAdmin = false; } else { $isAdmin = true; }

Now, this isn't going to be anybody's favorite code, but it's not a WTF. If the session variable ADMIN_ID doesn't have a meaningful value, then we're not in admin mode, otherwise we are. It's ugly, and I think redundant: while isset and empty are actually different, isset includes a NULL check.

As Lovelace writes:

While ugly, this really isn't so bad. It's not like you can set session variables from the client.

Of course you can't. Right? Right?

if (isset($_COOKIE["SESSION"])) { foreach ($_COOKIE['SESSION'] as $name => $value) { $_SESSION[$name]= $value; } }

This block is copy-pasted into the top of every page, because what's an "include file"? This looks for all the sub-cookies under SESSION and just loads them directly into $_SESSION. So a cookie named SESSION[ADMIN_ID] would get stored in $_SESSION['ADMIN_ID'].

So now, anyone who could open up the dev tools could easily make themselves an admin. And there were many admin pages, and as you can imagine, the admin validation was also copy-pasted into every admin page, right under the cookie/session loader. And an exploiter wouldn't need to guess the correct value- any non-false, non-null value is going to grant them admin access.

Or set/alter any session variable. Who knows what else might be in there?

Lovelace raised this up to their management. "Oh, it's no big deal," management said, "because we're going to stop selling this software sometime really soon. I mean, we did just sign a three year contract with a large customer, but like, really soon, nobody will be using this anymore."

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

This post originally appeared on The Daily WTF.

Leave a Reply

Your email address will not be published.