Follow-up: CodeBash Ascend Vegas 2018
This year, once again – it was time for the coolest coding competition of the year – Ascend CodeBash, sponsored by Microsoft.
Some might recall that last years theme was a bit on the creative side – coming up with a fun and innovative use of Microsoft Cognitive Services together with Episerver CMS.
This year had a bit more of a strict and realistic agenda: The participating teams (9 in total) of 1-5 participants was asked to ‘rescue’ a web site project for a small fictional fashion retailer, called ‘FashionKings’. They have had a nephew (‘John’) of the CEO built a site based on Episerver Commerce – and frankly, it had not gone all that well.
Several must-have functionalities was left out – and even worse – he had introduced a number of serious security vulnerabilities.
Each team was given access to a GitHub repository for their version of the site – which again was connected to an Azure AppService with continuous deployment. Their task: Fix the site and commit to the repo before time runs out. They were supposed to find and fix all security issues, implement ratings, reviews and activity feed using Episerver Social – and setup a real-time reporting call to an existing Azure Function connected to PowerBI with transaction data.
The security theme was obviously inspired by having the great Troy Hunt (https://www.troyhunt.com/) as a guest judge alongside Michael Collier from Microsoft and our own Jacob Khan. As the security vulnerabilities seemed to prove the most difficult to find and fix, I promised several participants that I would walk through them in this blog post.
#1 Insecure File Upload
The site contained a trendy new social feature called ‘Share what you wear’ – here, you could upload a photo of yourself wearing some clothes bought on the site. Great idea – but sadly the implementation was a bit rough. It didn’t check on file extension or mimetypes of the upload – and simply put the uploaded files in a ‘/upload/’ folder.
This means that it was quite easy to upload – say for instance an ASPX file that provided root access to the server and site, like this:
Sadly, no teams found (or at least fixed) this vulnerability.
#2 Insecure download
Just as an upload field can be insecure, so can a download functionality. In this case, the expert implementor, ‘John’, wanted to make a download functionality to allow visitors to download a shoe-sizing chart. Sadly, he made it a little bit too generic: /Download/Get/?path=/App_Data/ShoeSize.pdf can just as easily be /Download/Get/?path=/connectionstrings.conf.
Only 1 team caught this bad boy…
#3 The classic: SQL Injection
And time for a real classic – SQL Injection error. ‘John’ had prepared the site for a future newsletter. Since he recently learned SQL he had decided to add a specific SQL table to keep the list of all the people signing up for it. And why not concatenate a few strings to get the data in there:
Now, unfortunately my email address is a bit untraditional:
abc');update [dbo].[CatalogContentProperty] set longstring='SQL INJECTION!' where MetaFieldName='DisplayName';--
(Might remind you of the story of little Bobby Tables, https://xkcd.com/327/).
For some strange reason, after signing up for a newsletter all the products had a weird name:
But not to worry – turns out 3 out of 9 teams found this one and fixed it!
#4 Default Credentials
Now, what is one of the simplest things you should always remember to change when going into production?? Well, how about NOT USING THE DEFAULT CREDENTIALS ANY MORE!!!
Surprisingly, in 7 out of 9 teams we had no problem getting into the backend as admin@example.com with the password: ‘store’. Rings a bell?
#5 Not cleaning up confidential information
While coding, ‘John’ had a hard time remembering the default credentials he used. So – he made a little not of it, in a /passwords.txt file. But – ‘John’ wasn’t stupid. He knew it wouldn’t be good if it was easily found by an evil hacker – so he made sure to disallow it’s indexing in robots.txt…
User-agent: *
Disallow: /Passwords.txt
Disallow: /upload/
I’m happy to report that at least 4 teams found and removed this one.
#6 Another classic: Script Injection
‘John’ had heard the request for more social features on the site – and sure enough, in the ‘Fashion Club’ segment of the site, he build a nice little forum functionality where visitors can share their ideas with the company. Since he is kind of a genius at HTML, John has always preferred to make his own comments stand out – for instance using the <blink> tag. Now, in order to get this to work, he had to go through some hoops in the code – but he finally got it working.
Sadly, this also means that my comment works just as well:
Which results in this:
#7 Enforcing SSL
SSL is the sh*t these days – and if you are not doing it, you should be. Now, being hosted on Azure, the sites naturally supports SSL through a site certificate – but you can also access it directly on http – which you shouldn’t be able to.
There are several ways to fix this – the best is supposedly HSTS – and configure the proper rules in your web.config, like Scott Hanselman suggests here (http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspx):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>
</rules>
<outboundRules>
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security"
pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
And here, I think Troy Hunt’s talk earlier in the day paid off – only 3 out of the 9 teams didn’t get this one right!
#8 Custom Errors
Last but not least – never show detailed stack traces in production environments – it can give away information you don’t want to share.
This can both be a setting in a web.config file – but as in John’s case, it can also be something set within Episerver. In Admin mode, under “Permissions for Functions”.
Only 1 team managed to find this one – and they even made a nice, custom 404 page. And since they also successfully implemented Reviews and Ratings and a few other nice details that impressed the judges this ended up being the winning team – TEAM 3!
And for those curious as to what was on stake – this was the prize for every member on the winning team:
http://www.samsung.com/global/galaxy/gear-fit2-pro/
For fun- OWASP ZAP
Just for fun, I ran the open source OWASP ZAP (https://github.com/zaproxy/zaproxy) vulnerability scanner on the site after the competition, and this is what it found:
As you can see, of the severe errors, it only caught on to was the script injection vulnerability – and the fact that the application exposes custom errors.
The Remote OS Command Injection looks like a test error (I haven’t been able to reproduce) – but then again, you just never know with developers like ‘John’ around đ
We had a blast hosting the CodeBash competition – and I hope that you, who participated had fun – as well as learned a few new things along the way!
Thanks for sharing, It's a benchmark for a secure site!
Thanks Alan! It was very well organized and was so much fun. Sadly, we never even browsed to the file upload page.
Loving the new Samsung Gear Fit2 though :)
If you liked the competition and want to do more, I would recommend https://hackyourselffirst.troyhunt.com/ and the PluralSight course that goes with it: https://www.pluralsight.com/courses/hack-yourself-first