Feed aggregator

The Security Audit

The Daily WTF -

We do our best to anonymize submissions, but there’s always a chance that some dangerously identifying detail slips through. Every once in a while, a submitter contacts us to ask for a modification. More rarely, a submitter’s employer contacts us.

Our rule is to make edits more or less as requested, then move on without comment. There’s nothing about an article so sacrosanct that it’s worth going to war over.

However, we recently got a request that was itself too much of a WTF to pass up.

An old Errord—practically antique—contained a picture of a freaked-out Windows login screen, submitted by someone we’ll call Johnny. The post contained Johnny's name, username, and an Active Directory Domain. It did not identify the company Johnny worked for. But the company—we’ll call them “Lagomorphic Cogitations”—recently performed a security audit and sent us a message:

To: [email protected]
From: [email protected]
Subject: Request for Article Picture Removal (Information Disclosure)

I am reaching out to you about an article posted in 20XX, specifically, the last two screenshots by Johnny in http://thedailywtf.com/articles/someolderrordiwontname.

Gathering an employee’s first name and last name, coupled with the corporate email convention of [First Name].[Last Name]@LagomorphicCogitations.com may allow attackers to gather a list of possible targets for phishing attacks. If the article can be edited to remove the last section from Johnny it would be greatly appreciated as we are looking to limit our exposure of cooperate information. Thank you!

-Hunter Jacobs

We did some basic due diligence, confirming the email looked authentic and that someone with this name worked on Lagomorphic Cogitations' security team. I also happen to know Johnny, and confirmed with him that he'd left that job over five years ago, and yes, that particular submission came in during his tenure there. We removed the offending image. Frankly, we didn’t do much else. It’s a minor edit to an old Errord, and we’re not that concerned.

There’s a fair bit to unpack here, though. After all, our article made no mention of Lagmorphic Cogitations. To find it, they must have been searching employee names—not just current employees, but also ex-employees. (A quick check on LinkedIn shows me 45,000 people who work or have worked for Lagomorphic Cogitations.)

After that incredible slog, someone then had to click on the article, look at the image, recognize the Lagomorphic Cogitations domain, then contact us directly to request a removal. Even with modern technology, there’s only a small degree of automation that could've been involved in this process.

If nothing else, this gives us a sense of how much effort Lagomorphic Cogitations puts into these audits. Unfortunately, their attempt to prevent information disclosure has led to, well, more of it, hasn’t it? Before we received their email, we didn’t know Johnny had ever worked for them. We didn’t know that screenshot was their logon. Heck, we didn’t know their email address pattern, even if [First Name].[Last Name]@LagomorphicCogitations.com is pretty easy to guess.

Now we know all of those things.

Based on my own personal experience in these kinds of environments, I have a hunch about what happened. Lagomorphic Cogitations almost certainly didn’t perform this audit themselves; this was an outside contractor thing. They handed the contractor a check, and a few months later, the contractor came back with a spreadsheet listing “potential security risks.” The security company looks better the more they find, and they’re also not being paid to do more than provide a high-level triage, so this spreadsheet contains anything and everything they could possibly dig up.

From there, the executive who commissioned that study handed the spreadsheet to a pool of middle managers and said, “Deal with these.” The spreadsheet filtered down the hierarchy until it landed on the desk of poor Hunter, who just followed the policy he was given: Tell them to take it down because it’s an information disclosure. If they don’t, escalate.

After we took down the image, Hunter changed the background of the row in his spreadsheet to green. Then he moved on to asking a Facebook group to remove a picture of a cute bunny, because it happens to be owned by an old employee and its name might be part of their password.

At the end of the quarter, Hunter’s boss will brag to the executive board about how his team has resolved 3,421 security issues identified by the audit. The board will nod sagely and pat themselves on the back for writing that check.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!

CodeSOD: The Story of Things

The Daily WTF -

Every line of code tells a story. It never just… appears. Someone made and crafted that code. There’s a story, and an explanation for how that code could be. The world, even the bad, awful corners of it, makes sense and can be understood.

For example, Luke sends us this block.

/** * Format a string as a phone number mm/dd/yyyy */ public static String formatPhone(String phone) { String s = ""; if (phone != null) { s = phone.trim(); } return s; }

I imagine, the thinking went like this: “I need to write a function to format a phone number, so I’ll copy the code for the function to format dates, and I’ll replace every instance of date with phone. Oh, wait, the comment is unclear. I’ll make that phone number”

Similarly, this Anonymous PHP code tells its own story:

if(!$this->auth_model->in_group('Manager')) { $data->userLevel = 1; } else { $data->userLevel = 3; } if($data->userLevel == 3) { redirect('index', 'refresh'); //In CodeIgniter, this triggers a 301 redirect to another page. }

The story, I imagine here, was a case of conflicting terminology. Once upon a time, someone came up with the idea of “User Levels”. Someone else thought that was needlessly cryptic, and wanted to give them names. Then this developer got confused, and decided to translate everything back into user levels. This particular if block appeared dozens of times in the code, and it was the only place that userLevel was eveer used. Our anoymous submitter ripped them out.

Finally, a different Anonymous contributor found this block:

def formatDate(date): date = time.strptime(str(date), '%Y-%m-%d') date = str(date.tm_year)+'-'+str(date.tm_mon)+'-'+str(date.tm_mday)

Now, the developer responsible for this knew that they needed a date in a Year-Month-Day(%Y-%m-%d) format. So they started out by taking a date object, and converting it to a string, using str(date). This converts it into a %Y-%m-%d format. They then parse that into a date object- specifically a struct_time, using time.strptime. Once they had that, they could then use the various properties of the struct_time to build a %Y-%m-%d format.

I take back what I said. The world is a chaotic, disordered place, effects may proceed without cause. Sense is nonsense, and paradoxes are the only form of truth. There’s no explanation for this code, or for… anything, is there?

hljs.initHighlightingOnLoad(); [Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!

Time To Transfer

The Daily WTF -

When people think about government, they usually think about a President or Prime Minister, Senators, MPs, or what have you. But government isn't just a handful of people at the top of the food chain: there's government all the way down to the city level, quietly making the country run. Driver's licenses have to be issued, as do pet licenses. Buildings have to be inspected and certified. All those elevator certificates get printed up somewhere. Increasingly, these small functions are being computerized—in bits and pieces, in incompatible systems—and hooked up to the Internet.

Lisa was the lead engineer for one of these public websites. At its core, it took in personally identifying details and spat out some sort of official document. This meant they had to deal with the PII issues that come with taking people's information: encrypting and salting the data, securing the database backend, et cetera.

One of the pieces in this chain was a separation of data: until the user had paid for the document, proving their identity (or at least their possession of the credit card for the person they claimed to be), their data sat in a frontend database accessible to the Internet. After payment was taken, the data was sent to a more secure database in the backend and removed from the potentially hackable frontend. The frontend ran in a VM that could only make an outgoing connection to the database. It could receive incoming connections and respond, but not initiate them. Basic security for this type of system.

There was one issue, however, that Lisa struggled to track down. It seemed that a small percentage of users, fewer than 1%, were getting an error page immediately after payment. Their application was fine; payment was received, and their document was sent to them along with a confirmation. But they saw an error page suggesting they hadn't completed their transaction.

When Lisa managed to catch the issue in the act, she was able to reconstruct the sequence from the logs:

  • The user entered their card info
  • The payment processor accepted the payment
  • The application marked the record as paid
  • The application responded with the redirection back to the confirmation page
  • The transfer service kicked in and moved the data
  • The user landed on the confirmation page—and the record was no longer there to display.

In other words, a timing issue. So far, this was just a run-of-the-mill everyday problem. Race conditions happen all the time, after all. The problem was, Lisa had already fixed this race condition: the logic indicated that the system would wait at least 5 minutes before moving the data from the frontend to the backend, to allow for the confirmation page to be generated.

So, what gives? Lisa wondered.

The logic was still in place. In fact, the logs showed that the data hadn't been moved until 5 minutes after it was marked to be moved. But the confirmation page had generated in mere seconds. How could this possibly have occurred?

"It just doesn't make sense," she complained to her coworker.

"What time is it on the server right now?" he asked with a frown.

And that was it: the transfer service was 6 minutes off from the frontend box. As soon as it was marked eligible for transfer, the backend box would move the data. If the periodic service ran right when the row was generated, the user would get an error.

With a groan, Lisa put in a ticket to have both boxes sync to a time server.

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!

Chapter Three: How to Prevent Duplicate Terms During a Drupal 8 Migration

Drupal Planet -

In this post I will show a custom process plugin that I created to migrate taxonomy terms. The plugin handles the creation of new terms and prevents duplicates.

Below is a portion of the migration template. In the example, I am migrating new terms into keywords vocabulary via field_keywords field.

field_keywords: - plugin: existing_term # Destination (Drupal) vocabulary name vocabulary: keywords # Source query should return term name source: term_name - plugin: skip_on_empty method: row

This is the source code for the process plugin.

CodeSOD: An Emailed Condition

The Daily WTF -

For a change of pace, the code in this CodeSOD isn’t the real WTF. Our Anonymous submitter works for a company that handles meeting scheduling for corporate customers. This entails shipping off loads of HTML-emails, and that means using a relatively terrible WYSIWYG editor that generates code like this:

<p class="MsoNormal"><strong style="color: #003877;">Meals</strong></p> <p class="MsoNoSpacing"> <span style="font-size:9.0pt;font-family:" verdana",sans-serif;="" mso-fareast-language:en-gb"=""> All breakfasts and lunches will be served in Food Capital on the ground floor of the hotel. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span></p> <p class="MsoNoSpacing"><span style="font-size:9.0pt;font-family:" verdana",sans-serif;="" mso-fareast-language:en-gb"=""> We look forward to hosting you for the following dinners: <o:p></o:p></span></p>

Yes, awful, but no worse than any other WYSIWYG email editor, right? Well, take a look at this particular sample:

<p class="MsoNoSpacing"> <span style="font-size:9.0pt;font-family:" verdana",sans-serif;="" mso-fareast-language:en-gb"="">Dietary Requirements: </span> <!--[if supportFields]> <span style='font-size:9.0pt;font-family:"Verdana",sans-serif;mso-fareast-font-family:"Times New Roman";mso-bidi-font-family:Arial;mso-fareast-language:EN-GB; mso-bidi-font-weight:bold'> <span style='mso-element:field-begin'></span> <span style='mso-spacerun:yes'>&#160;</span> MERGEFIELD Dietary_Requirements <span style='mso-element:field-separator'></span> </span><![endif]--> <span style="font-size:9.0pt;font-family:" verdana",sans-serif;="" mso-fareast-font-family:="" "="" times="" new="" roman";mso-bidi-font-family:arial;mso-fareast-language:en-gb;="" mso-bidi-font-weight:bold"=""> */field1/*</span></p>

This particular block came to our submitter’s attention when they received a report that it was crashing computers. This was surprising, in part because after rigorous and thorough testing, our submitter couldn’t replicate the error.

That is, until they followed up and asked the important question: “What email client are you using?”

“Outlook,” came the reply.

Obviously, they’d already tried to replicate the error in Outlook. “Which version?”

“2007. Why, does that matter?”

As it turns out, the decade old email client really doesn’t like conditional comments- things like the <!--[if supportFields]-->. In fact, it hates them so much, it was crashing the users’ computers.

hljs.initHighlightingOnLoad(); [Advertisement] Infrastructure as Code built from the start with first-class Windows functionality and an intuitive, visual user interface. Download Otter today!


Subscribe to Heydon Consulting aggregator