Occam’s Razor as it applies to DevOps

A client emailed me today about an unusual problem. The “Create an Account” link on their website was not pointing to a page of their site, but instead to an IP address. An IP address that, when I ran a whois on it, turned out to be owned by China Telecom.

That was disconcerting. I’m not passing any judgment on anyone in particular in any country in particular, but the fact is, a hugely disproportionate number of online attacks against U.S. sites come from a small number of foreign countries, China being one of them. So, I was alarmed.

My first guess, since I’ve seen WordPress sites get hacked… a few times (much less often since I started using Wordfence as standard practice on every site I build), was that hackers had somehow hijacked this link and were trying to route my client’s users over to their systems in some kind of spoofing/phishing/whatever attack.

Only, the link didn’t actually do anything. There’s no web server listening on that IP address. Hmm.

Next up I looked at the HTML source, since I wasn’t quite sure if the code in question was being generated by their theme (which I built) or by a plugin like WooCommerce, so I wanted to see the CSS classes on the wrapper. Sure enough, it was in code I had built.

When in doubt, always blame your own code first.

But the fact that it was my code wasn’t what really caught my attention. It was the fact that the URL in the HTML wasn’t the IP address at all. It was just a string of 8 digits.

Suddenly it was clear to me that this was not a hack attempt, and China Telecom (or anyone using its services) had precisely zero to do with whatever was going on. This was a peculiar code problem, and it was at least indirectly my fault.

That 8-digit number… it looked very familiar. I knew that, due to some of the peculiarities of this client’s site, the ID values in their wp_posts table are on that order of magnitude. Bingo. This wasn’t a URL at all. It was a WordPress post ID, being incorrectly inserted here because Advanced Custom Fields was outputting the raw ID value instead of using it to look up the corresponding post URL.

Why was that happening? Well, that was ultimately my fault too, having to do with some logic that was designed to tell ACF where to load my custom field groups. When the site was built, I had that code running (technically) too early, then ACF released an update that started throwing up admin notices if you did that, so I rewrote it to run later… only I didn’t realize that my change was causing my code to get applied to a hook after it had already run, so… it wasn’t working. It was a very isolated set of circumstances, so it went unnoticed for months. As far as I know, the only user-facing issue it created was this weird integer URL on the “Create an Account” link on a page few people ever visit.

The simplest explanation is the most likely.

Even if the details are anything but simple. Was someone in China trying to hack my client’s site to phish for their customers’ data, or did I just write some flawed code? Hmm.

ST:TNG Treadmill Review #34: The Most Toys

The Most Toys
Season 3 Episode 22
Original airdate: May 5, 1990

Netflix Synopsis

After the crew transports a dangerous material to the Enterprise, a collector carries out an intricate plan to kidnap Data.

My Brief Review

Once again I’ve skipped an episode… specifically, the one that introduces pathologically shy, Holodeck-obsessed Lt. Barclay (“Broccoli”). Barclay plays a fairly significant role later in Voyager but I really do not care for him and I know that episode annoyed the crap out of me even when I was 16, so… no thanks.

This episode, on the other hand, is another great feature for Data. Trader and collector (also thief) Kivas Fajo, played excellently by the great character actor Saul Rubinek, tricks Enterprise into believing Data has been destroyed in a shuttlecraft explosion. In fact, Fajo has kidnapped Data for his collection, which includes, among other things, Dali’s Persistence of Memory, a one-of-a-kind Roger Maris baseball card, and the sole surviving member of an alien species that looks like a cross between a cobra and a cat, with giant compound eyes like a housefly. It’s quite a pet. And Data is the ultimate prize of his collection.

Meanwhile back on Enterprise, Geordi thinks something is up, and won’t give up trying to make sense of what happened to Data, while Worf awkwardly accepts another promotion in the wake of the death of a crew mate.

Data plays dumb for a friend Fajo is trying to impress, then plots an escape with one of Fajo’s lieutenants after she realizes Fajo is willing to kill her just to make Data sit in the chair.

The escape is foiled, Fajo uses his illegal disruptor — well, one of the four he owns — on her, and Data is — gasp! — just beginning to fire the same deadly weapon on Fajo when Enterprise returns and beams him aboard.

Memorable Moment

One scene in the collection room begins with us looking at Data, who is looking up curiously, attempting a strange half smile… then we see what he’s looking at: the original Mona Lisa, another prize of Fajo’s collection.

Crew Rando

Well, that would have to be the ensign who anonymously assumes Worf’s security post after Worf is promoted to ops. How does it feel to Worf to know that it was a big effin’ deal for Picard to decide to promote him to Data’s post, yet he hastily filled Worf’s own post with some nobody?

Distance Rating: 3K

IMDb score: 7.7/10

Participate in Wednesday’s SOPA strike

Looking for an easy way to participate in tomorrow’s SOPA (and PIPA) strike? The SOPA Strike website has some code you can use to automatically load this page.

I’ve set up my own customized version, which you’re welcome to use. This does not completely black out your site. Instead, the page loads with a black screen. Then after a few seconds, the words "STOP SOPA" with a "Learn more…" link appear in white. The black box then fades to slightly transparent and animates to the upper left corner of the screen. It then stays fixed in the corner as the user scrolls around. The site is still usable, but the “STOP SOPA” message is ever-present. (Be forewarned: as I did not take the time to set up cookies, the entire process also repeats on each new page load.)

If you’d like to see how it works, I set up an awesome fake site to demonstrate the blackout animation in action.

If your site is already using jQuery, simply copy the code below into your page, ideally just after the <body> tag:

<script type="text/javascript" src="http://atomic.room34.com/sopa_blackout.js"></script>

If you’re not already using jQuery on your site, you just need to include it from Google Code first, like this:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://atomic.room34.com/sopa_blackout.js"></script>

If you’re using PHP, you can even use this code to automatically make it appear at 8 AM EST and disappear at 8 PM EST. (Update the times as needed to represent your time zone, and remove the Google Code line if you’re already using jQuery.)

<?php
if (time() > mktime(8,0,0,1,18,2012) && time() < mktime(20,0,0,1,18,2012)) {
?>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://atomic.room34.com/sopa_blackout.js"></script>
<?php
}
?>

Note: As indicated above, I built this quickly, and have not done a lot of cross-browser testing. It’s pretty basic, but it may not display correctly in some older browsers, especially earlier versions of Internet Explorer. Use at your own risk… just like the Internet itself!