During the amazing Umbraco Code Garden 2015 I presented a session titled 'Securing your Umbraco'. The session covered common web security risks and how with Umbraco we can mitigate those risks.
The talk covered:
HTTPS
Umbraco Setup
Cookies
Input and Outputs
Self Testing
Pen Testing
Watch the talk back on the Umbraco stream http://stream.umbraco.org/video/11666249/securing-your-umbraco
5. – K E V I N M I T N I C K
“Companies spend millions of dollars on firewalls,
encryption and secure access devices, and it’s
money wasted, because none of these measures
address the weakest link in the security chain.”
6.
7. H T T P S : / / W W W . O W A S P . O R G
T H I S P R E S E N T A T I O N
I S P O W E R E D B Y
O W A S P
A N D M Y
E X P E R I E N C E S
8. B E F O R E Y O U S T A R T ,
T H I N K S E C U R I T Y
11. # 1
C A S E S T U D Y
Umbraco 4.7 running on an un patched Windows
2008 Server
This vulnerability was reported by Umbraco HQ
and patches made available immediately.
12.
13. # 1
U P G R A D E U P G R A D E U P G R A D E
• Upgrade Umbraco
• Upgrade servers operating system
• Upgrade the .NET framework
• Upgrade your packages (Umbraco and Nuget)
• Upgrade your front end frameworks
19. # 2
B A C K O F F I C E - W E B . C O N F I G
Make sure that all of the requests in the back
office are called over HTTPS instead of HTTP
20. # 2
O P T I O N 2
S E C U R E P A R T S O F Y O U R S I T E
O V E R H T T P S : / /
21. # 2
F R O N T E N D
Switch a URL from HTTP to HTTPS based on the
document-type (alias), node id or template alias
with help from @leekelleher
G I T H U B . C O M / L E E K E L L E H E R / U M B R A C O - H T T P S - R E D I R E C T
22. # 2
O P T I O N 3
S E C U R E Y O U R S I T E O V E R
H T T P S : / / W I T H
I N F R A S T R U C T U R E
23. # 2
S E C U R E B Y N - T I E R
I N F R A S T R U C T U R E
1 - 4. Request ARR
5. ARR ‘Offloads’ SSL
6. HTTP request to application server
7 - 9. Application server responding
to ARR on HTTP
10. ARR encrypts response and
sends to client
26. # 3
H A N D L I N G Y O U R E R R O R S - 4 0 4
1. Update UmbracoSettings.config with the content node you wish to serve as
your error page
2. IIS7+You may find IIS handles the error. Add the following key to your
web.config just before the closing tag of the system.webServer section.
27. # 3
H A N D L I N G Y O U R E R R O R S - 5 0 0
1. Tell IIS to pass the error to Umbraco (same setting for
the 404)
2. Set the CustomErrors section of the web.config
28. # 4
R E S T R I C T A C C E S S T O T H E
B A C K O F F I C E
29. # 4
R E S T R I C T A C C E S S
Restrict access to ‘/umbraco' by IP using IIS Rewrite.
<rewrite>
<rules>
<rule name="Restrict URL" enabled="true" stopProcessing="true" >
<match url="^umbraco($|/)" />
<conditions logicalGrouping="MatchAll">
<!-- Use REMOTE_ADDR if your server is NOT behind load balancer -->
<add input="{REMOTE_ADDR}" pattern="^10.11.12.13$" negate="true" />
</conditions>
<action type="Redirect" url=“/page-not-found/“ />
</rule>
</rules>
</rewrite>
33. # 6
I I S / . N E T H T T P H E A D E R S
Server: The web server software being run by the
site. Typically for Umbraco: “Microsoft-IIS/7.5”
X-Powered-By: The collection (there can be
multiple) of application frameworks being run by
the site. Typically: “ASP.NET”
X-AspNet-Version: ASP.NET only header, typical
examples include “2.0.50727” and “4.0.30319”
X-AspNetMvc-Version: ASP.NET stack and
typical examples include “3.0”, “2.0” and “1.0”
34. – I E T F ( I N T E R N E T E N G I N E E R I N G T A S K F O R C E )
“Revealing the specific software version of the
server may allow the server machine to become
more vulnerable to attacks against software that is
known to contain security holes.”
35. # 6
H T T P H E A D E R S
‘Server’ header reads:
‘; DROP TABLE
servertyes; —
The web server on
reddit.com.
36. # 6
H T T P H E A D E R S
Removing the headers manually
isn't as straight forward as you may
initially expect.
37. # 6
H T T P H E A D E R S
StripHeaders IIS Module
G I T H U B . C O M / D I O N A C H / S T R I P H E A D E R S /
38. # 6
H T T P H E A D E R S
Umbraco used to serve a version header
‘X-Umbraco-Version’
This was removed from V4.8
39. # 6
H T T P H E A D E R S T O T H I N K
A B O U T A D D I N G
40. # 6
H T T P H E A D E R S
Header:
Strict-Transport-Security
Example:
ansport-Security: max-age=16070400; includeS
41. # 6
H T T P H E A D E R S
Header:
X-XSS-Protection
Example:
X-XSS-Protection: 1; mode=block
42. # 6
H T T P H E A D E R S
Header:
X-Frame-Options, Frame-Options
Example:
X-Frame-Options: SAMEORIGIN
43. # 6
H T T P H E A D E R S
Header:
curity-Policy, X-Content-Security-Policy, X-
Example:
Content-Security-Policy: default-src 'self'
45. # 7
C O O K I E S
Mark your cookies ‘HttpOnly’
46. # 7
C O O K I E S
Mark your cookies ‘Secure’ when
working over HTTPS
47. # 8
S A N I T I S I N G I N P U T S A N D
O U T P U T S
48. # 8
S A N I T I S I N G I N P U T S
X S S - V A L I D A T E R E Q U E S T
49. D O N ' T R E L Y O N
R E Q U E S T
V A L I D A T I O N F O R
X S S P R O T E C T I O N
50. # 8
F O R M S - S A N I T I S I N G I N P U T S
• Validate form fields both client and server side
• Where there are option types (dropdown, checkboxes etc) ensure the
value matches an available option
• Required fields
• Correct data type and length
• Data falls within an acceptable range
• Whitelist allowable values. The regex namespace is particularly useful
for checking to make sure an email address or URL is as expected.
51. # 8
M V C F O R M S - S A N I T I S I N G
I N P U T S
Use the Synchroniser token pattern
ValidateAntiForgeryToken
52. # 8
S Q L I N J E C T I O N - S A N I T I S I N G
I N P U T S
• Use Parameterised SQL commands for all data access, without exception.
• Do not use SqlCommand with a string parameter made up of a concatenated SQL String.
• Whitelist allowable values coming from the user. Use enums, TryParse or lookup values to
assure that the data coming from the user is as expected.
• Enums are still vulnerable to unexpected values because .NET only validates a successful cast
to the underlying data type, integer by default. Enum.IsDefined can validate whether the input
value is valid within the list of defined constants.
• Apply the principle of least privilege when setting up the Database User in your database of
choice. The database user should only be able to access items that make sense for the use
case.
• Use of the Entity Framework is a very effective SQL injection prevention mechanism. Remember
that building your own ad hoc queries in EF is just as susceptible to SQLi as a plain SQL query.
• When using SQL Server, prefer integrated authentication over SQL authentication.
53. # 8
F O R M S - S A N I T I S I N G O U T P U T S
Encode your outputs - if the nasties are in
then don't let them out.
RAZOR
@Model.Title
is encoded
WEBFORMS
From .NET 4+ use <%: text %>
55. – C O D E S P A C E S , J U N E 2 0 1 4
“In summary, most of our data, backups, machine
configurations and offsite backups were either
partially or completely deleted. ”
56. # 1 0
T E S T Y O U R O W N S I T E
A S A F A W E B . C O M
57. # 1 1
H I R E A P E N E T R A T I O N T E S T E R
( P E N - T E S T I N G )
58. W W W . O W A S P . O R G
G I T H U B . C O M / L E E K E L L E H E R / U M B R A C O - H T T P S - R E D I R E C T
G I T H U B . C O M / D I O N A C H / S T R I P H E A D E R S /
W W W . R A P I D 7 . C O M
S T A H E R I . C O M
W W W . T R O Y H U N T . C O M
A S A F A W E B . C O M
Also thanks to
@ C G A S K E L L
Hinweis der Redaktion
Good afternoon everyone, My talk today is on ‘Securing your Umbraco’
My name’s Chris Gaskell and I’m a freelance ASP.NET developer based in Manchester, England.
I started coding using classic ASP back in 2000
No more gross slides I promise.
Here’s my disclaimer slide - I’m no hacker or security expert. I have an interest in the security space and have implemented changes through codebases to fix issues found through penetration testing - it’s these experiences I want to share.
The security I'm going to talk about is application security, securing you application against hacking type attacks - I’m not talking about security in the CMS itself.
The important thing is that you need to consider all the security aspects when it comes to websites, only implementing 50% isn't going to help
This quote from Kevin Mitnick sums up the point I'm trying to get across.
We’re in a place where security through infrastructure (thats firewalls etc) is pretty good and as solution providers we need to do our part - we cant simply rely on firewalls.
Looks like we’ve all probably had our details leaked.
Personally I try and use a different password for each internet account. I use a password tool. The one I use is called 1password.
Much of the detail of what I'm going to talk about today has been taken from OWASP guidance.
Open Web Application Security Project
“Worldwide not-for-profit charitable organisation focused on improving the security of software”
Specific .NET guidance from Bill Sempf, Troy Hunt and Jeremy Long
Think security from the start.
It can be difficult to add security retrospectively to an application that didn't really consider it from the start.
How will you ensure that your solution design, hosting and data will embrace security?
This presentation will cover some key points which you should consider on your next project.
Point number 1 is…
.. is Upgrade
Upgrading can be a pain! One of the most difficult to schedule, find time, find money, bug free?, ‘if its not broke don't fix it’
Upgrading will help solve any security issues brought buy the underlying operating system or framework.
Before I show a screen cast that a good mate of mine has put together showing how a vulnerability can be exploited I wanted to thank him.
I asked him if he could s end me a pic, as he’s not here and you could put a face to the name but in typical Gav style…
So thanks to Gav. Needless to say, I didn't include the pic!
The screencast shows Umbraco 4.7 running on an unmatched windows 2008 server.
The exploit is known as "Umbraco CMS Remote Command Execution"
The exploit is called "Umbraco CMS Remote Command Execution"
The framework used to deliver the exploit is called Metasploit. Its favoured with script kiddies as it is incredibly easy to setup. The steps used to carry out one exploit can be done in four steps (choose exploit, set target, choose payload, run exploit).
About the exploit: The exploit exists in umbraco versions less than 4.7.1. By crafting a SOAP request to codeEditorSave.asmx, which permits unauthorised file upload via the SaveDLRScript operation on the webservice side of things. The upload allows code to be placed into the /umbraco/ directory. The upload would be an aspx shell, from there further exploits and in this case a shell on the remote host can be uploaded.
The initial shell gives the attacker a very limited access due to the IIS default Network Service user restricting the attacker from browsing to sensitiveness parts of the server. So important to also segregate the user running IIS and not to use SYSTEM or a user with high privileged user (Admin).
An unpatched or up-to-date host operating system allows for far too many ways to escalate privileges. The screen-cast uses the exploit called Chimchurri which impersonates a service in use running as a higher service account. Once privileges are escalated (usually to SYSTEM), you can do anything nasty - delete the website, steal sensitive information from databases, <insert the risk typically posed to an umbraco web site>
I’m not just talking about upgrading umbraco
…
Thats a lot of upgrading :)
Option 1
If you have forms, especially those capturing personal info or of course authentication - best practice would be to secure your entire site.
Allows cookies to be marked secure
Easier to ensure *everything* is over HTTPS rather than only certain parts of the site
- Servers are now more than powerful enough to handle the encryption / decryption of HTTPS and it’s easier to setup than you may think.
- More complex infrastructures can be setup to ‘offload’ the HTTPS a step before the application
So of course if you're going to use HTTPS you need to install a certificate. With IIS this isn't as daunting as you may think.
Could redirect certain pages or whole site - why not just do whole site?
Install the Url Rewrite module and put this in the web config.Will throw exceptions on machines without the url rewrite module installed
Serve over https:
- JS files can be linked to as //[url]
Ensure forms post to HTTPS
AJAX endpoints over HTTPS
[TODO: Issues with preview?]
Sometimes there are reasons out of your control why the entire site cant be secured but thats the best idea. Otherwise ensure all forms and areas that collect data asre secured. Also if you have a login - once a user is authenticated they must stay on HTTPS
Lee’s package will help you redirect on Umbraco document-type (alias), node id or template alias
Option 3 - the IT pro approach
Sometimes you wont be able to update the application - maybe it’s been inherited…. So you could use infrastructure to help out.
Tier your infrastructure to allow the site to run on HTTPS
SSL IS offloaded by a reverse proxy - in this case the IIS ARR. This could also be modern firewalls, HA Proxy etc
In this setup the application serves only on HTTP - but the application is only available through the ARR reverse proxy. Allows usage of extra tiers such as VARNISH :)
(EXPLAIN DIAGRAM)
The ARR has many other advantages such as serving parts of your site form different locations, working with URL Rewrite to allow routing control, rewriting the body of the response (img urls to can etc) server farm monitoring, load balancing, ability to add / remove servers from the farm gracefully.
Hackers would only see the ARR, not your application server
Firewalls still required
Now, error handling
Showing a full error stack to the net can easily reveal the inner workings of your application. This stack trace shows that the application is trying to cast the ID query string value to a guid. Immediately a hacker knows that the ID parameter must be a GUID, I can also see that the site is using a SQL server.
YSODs are very helpful to developers but should not be visible out on the web.
Im sure everyone here sets their Umbraco installs with a 404 page, but it can be forgotten. It’s really easy to setup and puts the 404 page right in the CMS for your content authors to change as they please. You can also set a 404 page for each language if you like.
The 500 status code signifies there has been an unhanded exception thrown by the application for this request.
Handling the 500 status code is in the web.config and you can cater for sub codes if you wish.
Catering for these errors should not render a CMS node as the error could be a database connection, the error page should be static HTML on the servers harddrive.
Using the IIS Rewrite module you can intercept requests to your application. The module is free and produced by Microsoft - its easiest installed via the web platform installer.
The example above only allows access to /umbraco from the ip 10.11.12.13. This can be added to the webconfig in the <system.webServer> section and shipped with the app. Note if you do this the URL rewrite module will need installing on every sever the app runs on
If behind a load balancer you’d want to match the Original IP usually passed from a load balancer via {HTTP_X_FORWARDED_FOR}
Hides start point for potential hackers checking /umbraco
Taking your comments out of the clients markup will help keep those reminders hidden, it’ll reduce the payload to the client to.
This is a request to a default MVC 3 and .NET 4 using IIS 7.5. Microsoft servers are chatty with their out of the box headers.
These headers are so companies can track whats in use on the web and by what percentage
Why hide headers?
Say one day a researcher pops up at a security conference and shows how a new attack can be used to exploit IIS. What’s more, the vulnerability is specifically with IIS 7.5. And only when it’s running ASP.NET 3. It has happened and probably will do again.
Also - at extremes you will save bandwidth. Those headers go down with each response - both for HTML, assets etc
To remove the four headers some are in code, some in .config and the ‘Server’ header is typically removed in code through a HTTP module. Use of the "PreSendRequestHeaders" event is no longer recommended by Microsoft.
Code alterations (in global.asax - requires inheriting Umbraco global and updating global.asax)
All these different approaches can be difficult to maintain and could introduce bugs.
Old approach included UrlScan
I use the ‘StripHeaders’ IIS Module by Dio-nach for IIS 7.0 - 8.5.
Installs across the whole server and adds configuration in the applicationHost.config file and can be edited directly or from the Configuration Manager module in the site settings in IIS Manager.
The StripHeaders native code module uses a very simple syntax to add additional headers to remove.
This configuration could be altered in the web.config
The default configuration is shown here - I also add "X-AspNetMvc-Version"
As we saw in the hacking screen cast, finding that the application is Umbraco and then finding it’s version is very helpful to potential hackers.
You can add headers to enable extra security functionality in browsers. There’s a full list over on the OWasp website but here are a few to think about.
The headers could be easily added using the URL Rewrite module and configured in IIS
If you're running over HTTPS
HTTP Strict-Transport-Security (HSTS) enforces secure (HTTP over SSL/TLS) connections to the server.
This defends against Man-in-the-middle attacks.
HSTS also disables the ability for user's to ignore SSL negotiation warnings.
This header enables the Cross-site scripting (XSS) filter built into most recent web browsers.
It's usually enabled by default anyway, so the role of this header is to re-enable the filter for this particular website if it was disabled by the user.
This header is supported in IE 8+, and in Chrome. The anti-XSS filter was added in Chrome 4.
Provides Clickjacking protection.
Values:
deny - no rendering within a frame,
same origin - no rendering if origin mismatch,
allow-from: DOMAIN - allow rendering if framed by frame loaded from DOMAIN
Content Security Policy requires careful tuning and precise definition of the policy.
If you enable CSP has significant impact on the way browser renders pages (e.g., inline JavaScript disabled by default).
CSP prevents a wide range of attacks, including Cross-site scripting and other cross-site injections.
HTTP has no state therefore authentication systems usually rely on cookies. It’s usually cookies that are sniffed to allow hackers to hijack users sessions.
Larger applications may also store further user info in the cookie, such as website preferences.
According to Michael Howard, Senior Security Program Manager at Microsoft, the majority of XSS attacks target the theft of session cookies.
By setting the HTTPOnly flag on a cookie makes the cookie invisible to Javascript and Applets.
[EMAIL EXAMPLE - sign to to site, create authentication cookie. Click in email to compromised page on the site and JS can read the cookie and transmit its content elsewhere - this is known as session hijacking]
If you need cookies to support javascript functionality then consider running multiple cookies simultaneously.
The secure flag is an option that can be set on the server when sending a new cookie to the user within an HTTPS Response.
Secure cookies will only be sent by the browser over a secure connection. Bear in mind that if you application sets a cookie secure then redirects the user to a non secure url the cookie will disappear.
[COFFEE SHOP. You sign to website on https - create an authentication cookie. A potential attacker may then email you a link to a page on the site over HTTP - this will transmit your authentication cookie in plain text. A potential hacker could then sniff that value and take your session]
At position 1 and 3 within the oWasp top 10 are guidelines to sanitise your inputs.
Cross site scripting, cross site request forgery, session hijacking and sql injection are all types of attack that manipulate the input or output of a server to perform in a way the developer hadn't intended.
If you've implemented all the other bits before this then the ground work is done.
Im sure some of you have bumped into this error…
Request validation is a feature in ASP.NET that examines HTTP requests and determines whether they contain potentially dangerous content.
This check adds protection in the query string, cookies, or posted form values.
Do not disable ASP.NETs validateRequest in the web.config etc The XSS protection in ASP.NET should be left intact as it provides partial prevention of Cross Site Scripting.
Note this will only prevent nasties going in - if they’re already there - say in data migrated from an old site this wont help.
This can be disabled if there is a genuine reason to pass strings with tags to the server. This can be done with the [ValidateInput(false)] attribute on actions.
Request validation is generally desirable and should be left enabled for ‘defense in depth’
It should NOT be used as your sole method of XSS protection, and does not guarantee to catch every type of invalid input
There are known, documented bypasses (such as JSON requests) that will not be addressed in future releases, and the request validation feature is not in ASP.NET vNext
Validation - both in javascript and on the server. MVC validation attributes are great for this.
For option types ensure the value sent matches an available option
Enforce required fields, especially if there is interfiled dependencies
Check the type sent matches the type required, handle castings within tryparse where possible
For numeric or datetime fields check the value is within a specified range
Check all other fields for validity - use a whitelist where possible
Antiforgerytoken - Generates a hidden form field (anti-forgery token) that is validated when the form is submitted.
This helps prevent Cross-Site Request Forgery (CSRF) - favourite example here is change of user password (in the case where the password field doesnt require old password). If I could get you to submit that password change form through a bit of social engineering - then I have got you to set your own password to my value. The anti forgery token prevents that as each time the form renders the token is different.
Works by setting a hidden form field and a cookie value. When values are passed to the server, typically through a POST the server checks the cookie and hidden field values match.
Needs to be included in the form markup along with an attribute on the MVC Action
SQL injection is quite an old topic, but still ranks number one on the oWasp top 10.
SQL injection is used to attack applications which dynamically construct SQL statements without sufficient input validation.
The slide shows a number of recommended techniques to prevent SQL injection - the main points are Parameterise sql queries, consider an ORM such as entity framework and review user security.
Even points on here are still eluding to sanitising your inputs
Not relevant for Umbraco directly as it handles data access but you may be running custom databases alongside to support your application.
Razor by default will encode all strings, the prevent this encoding you can use Html.Raw()
ASP.NET 4 introduced a new code syntax <%: %>. Essentially, <%: foo %> translates to <%= HttpUtility.HtmlEncode(foo) %>. The idea is to to get developers to use <%: %> instead of <%= %> wherever possible to prevent XSS.
You may want to look at the Microsoft AntiXssEncoder Starting with ASP.NET 4.5 you can specify that the AntiXssEncoder to be used as the default encoder for you entire application
Backup everything, everything you configure, your code, your databases, snapshot your servers and move those backups away from your production environment. Think what may happen if you lost *everything* right now, how would you get back running?
In June 2014 what started as a DDOS attack became some communications with a hacker via a hotmail address. The hacker had taken control of their Amazon control panel. When CodeSapces attempted to re-gain control the hacker noticed and began to delete artefacts from the panel.
The company reported that all of its svn repositories—backups and snapshots—were deleted. All EBS volumes containing database files were also deleted. A few old svn nodes and one git node were left untouched.
The company subsequently shutdown as it had lost everything.
Using https://asafaweb.com/ why not test your own site.
ASafaWeb.com is a free Automated Security Analyser for ASP.NET Websites
Lets take a look at codegarden15.com site
The only way you can be 100% confident that what you’ve got live is secure, would be to have someone test it from the outside. it’ll give you some nice paperwork to say you have done.
It could be costly but there is a growing number of freelance pentesters.
Be ready for a big report though and if you've not tested before there could be a lot of work - better finding out now!
Thanks for listening and I hope those pointers will be of some help.
I’ll make these slides available after Code Garden
Any Questions?