Sunday 28 September 2014

ASP.Net using location path attribute to secure URL access

One of the easiest security access mechanism that we can maintain is secure URL access. One way of doing this using authorization attribute in controller action method if you are using MVC. You can use this attribute to secure entire controller as well. Just place the Authorize attribute in the contoller class definition.
[Authorize(Roles="Admin")]
public ActionResult Edit(int id = 0)
{
Studentstudent = db.Students.Find(id);
………………………………….
……………………………
}
But this is more or less hard coding the role in to the code and this is action level authorization. But in page level ,we can use location path attribute in web config to perform more configurable access rule.
Following is an example in web.config
<location path="Students/Edit">
<system.web>
<deny users="?"/>
<allow roles="Admin"/>
</system.web>
</location>
Keep in mind that this would not work properly if you are mapping the URL into a different name in the RouteConfigs.cs
Eg :
routes.MapRoute("Student", "NewStudentUrl", new { Controller = "Student", action = "Edit" });
In a situation like this, it is better to use the aforementioned authorize attribute in cs code
 

Thursday 25 September 2014

Symmetric encryption without using a key in the C# code

Either symmetric or Asymmetric encryptions, managing keys are a bigger problem than doing the encryption decryption itself. There is a way that we encrypt the data using key in the scope of the machine or user.

Following is the code

// To Encrypt
var textToSecure = "This is the text that we need to secure with encryption";
var textBytes = Encoding.Unicode.GetBytes(textToSecure);
var encryptedText = ProtectedData.Protect(textBytes, null, DataProtectionScope.CurrentUser);
// To Decrypt
var decryptedBytes= ProtectedData.Unprotect(encryptedText, null, DataProtectionScope.CurrentUser);
var decryptedText = Encoding.Unicode.GetString(decryptedBytes);

Note that as the 2nd Param we can pass in an additional byte array as an additional entropy.
 
Eg : static byte[] s_aditionalEntropy = { 9, 8, 7, 6, 5 };

DataProtectionScope can be either user or Machine. If we select the machine level scope anyone who has the access to the machine can decrypt the encrypted data.
 
 

Hashing passwords … How much security we can guarantee ??


There are many ways where we can store application passwords securely. We can use existing frameworks like membership provider in .Net and there are other 3rd party providers as well. We can use either encryption or hashing in this regard but the most famous way of securing passwords is hashing.

First if all we need to understand that Hashing and Encryption are totally different methods in cryptography. Bit confused eh ? ;) let me explain..

In Encryption what we are doing is we are using one or several keys to do the encryption. So this is called symmetric encryption and normally it is a reversible process.

But Hashing is a one-way process, ie : there is nothing called un-hashing. Hashing using deterministic algorithms. We use our hashing algorithm to create the hash with a the value we need to hash ( password ) and store them. So when we need to do check the value again ( during login process as an example ) the hashing algorithm generates the hash again with given password and check against the saved value.

Normally hashing algorithms are not cracked. Instead, what attackers do is , they are using existing password list and generate hashes and compared vis brute force. We can use tools such as hash cat for this process. Attackers using consumer hardware such as high end GPUs to perform these kind of brute force cracks. If we take an example , the VS2010 membership provider ( default using the SHA1 ) can be cracked up to 60% within 15 mins.

Rainbow tables

Rainbow tables are pre compute hashes where we can use to compare rapidly with breached accounts. Rainbow crack provides pre-configured rainbow tables to download. But these files are huge. As an example , md5_ascii collection for password length 1 to 8 is around 576GB.

 How to secure hashing

Technically we cant secure hashing 100% . What we can do is, we can slow down the cracking process hence it is taking much longer time to do the brute force attack on it.


Using Salt 

Salt is a sequence of random bytes which got appended with the value ( password ) we need to store securely. So the salt is also saved along with the hashed password. This would eliminate the use of Rainbow tables up to some limit. But if we have a salt rainbow table, still we can use the brute force but would take much longer time to do the cracking.
 

Using hash algorithms which takes much longer time to compute

VS2012 using the PBKDF2( Password base key derivation function)  with HMAC-SHA. This hashing process iterates 1000 times in the crypto.cs class which comes with the VS2010. To compare this with VS2010 method, this takes 10 days( with 1 GPU ) to crack with brute force attack compared to 14 mins in VS2010. But still, it is a matter of time !

Use much stronger hashing algorithms

Instead of using standard hashing algos , we can switch to much stronger hashing algorithms such as BCrypt or Ztetic. Ztetic can be replaced .Net membership provider with some configuration changes. Ztetic using 5000 computations of PBKDF2.

 

 

 

 

 

 

Wednesday 24 September 2014

Securing ASP.Net configurations from being hacked



ASP.Net configurations are pretty easy to use and highly manageable feature. But this can lead up to many misconfigurations which would lead into high security vulnerabilities.  

ELMAH is a handy 3rd party configuration tool that developers can use to log errors and other information. But bad configuration can be lead up to many loopholes in the security perspective of the application. In following sections I’m explaining how to avoid those misconfigurations.

Handling Errors and redirect properly


First and foremost, we need to enable the customErrors in the web.config file. This is mainly to prevent the yellow screen of death in the browser.

<customErrors mode ="On" defaultRedirect ="Error.aspx"/>

This would solve the YSD issue but it would reveal the error page path in the url section in the browser. To eliminate that, we need to use the redirect mode attribute as below.

<customErrors mode ="On" defaultRedirect ="Error.aspx" redirectMode="ResponseRedirect"/>

This would keep the existing url in the browser’s url section while it is getting redirected to the appropriate error page.

Disable Tracing

Tracing is a handy tool that developers are using to get a log of requests been made and to get information about trace log information.

When you go to the View Details section, you can view various details such as detailed request details, origin .Net framework info etc.. But most dangerously, there can be trace logs that developers have logged and forgot to remove in production code. To remove all these make sure that the following attribute is set to false.  
<trace enabled="false"/>
 

Encrypt config sections



We used to keep sensitive data such as connection string passwords in the web.config file. But leaving these sensitive data in plain text in anywhere is a high security vulnerability. There are many tools and methods where we can encrypt these sections and I’m going to discuss one of the easiest ways we can achieve it using regiis tool.

  1. Run the command prompt in Admin mode

  2. Browse to the .Net framework’s path > eg : C:\Windows\Microsoft.NET\Framework\v4.0.30319

  3. Run the following command
    Aspnet_regiis –site “MySecureSite ” –app “/” –pe “ConnectionStrings”
Note : -app is the application folder relative to root of the IIS. In my case I hosted mySecureSite in the root.  –pe is the section we need to encrypt
After this you can see the given section is hashed.
Use the –pd attribute in same manner to decrypt the given section.
This may not the most appropriate way to encrypt the config sections but it is fairly easy.

Use config transforms


We can use the Web.Release.Config’s config transform to make sure we are not leaking out any dev related config entries to the production code. Following are two examples of how we can use it.
Following sections would make sure that error mode is remoteonly, the 500 error would redirected to a production error page and the trace attribute is removed.
Keep in mind that in order to take this into the action, we need to publish the web project.
 <customErrors mode="RemoteOnly" xdt:Transform="Replace">

      <error statusCode="500" redirect="InternalServeError.html"/>

    </customErrors>

    <trace xdt:Transform="Remove"/>

In the production environment, it is advisable to enable the retail mode in machine.config file.
<deployment retail="true"/>