Showing posts with label .net framework. Show all posts
Showing posts with label .net framework. Show all posts

Monday, October 18, 2010

Creating DBHelper that can support various types of database...

Yes I know there's a framework (EF, NH and whatever name that I've never heard before) that can solve the problem. Unfortunately, EF only works on new technologies (at least with .NET framework 3.5). What if we're stucked with an old Microsoft technologies (NH is another option, but I still couldn't figure out on how and where to begin with - ~ I ain't a .NET superstar ~)? Is it possible to do it then? Yes!!! back to basic stuff!!!

I've try it on .NET framework 2.0. IDBConnection, IDBTransaction and IDBDataParameter are available in System.Data namespace since .NET framework 1.1 however, DBDataReader in System.Data.Common was available not until .NET framework 2.0 (DBDataReader was derived by SqlDataReader, OracleDataReader and OleDbDataReader). Those are the important interfaces and class needed.

Basically we need to create an abstract layer to our db helper. Let's just call it IDBHelper. Define all basic methods that can support various databases. It's important not to have a method that is specific to any data provider such as ExecuteXmlReader.
    ...
using System.Data;
using System.Data.Common;

public interface IDbHelper
{
IDbConnection CreateConnectionInstance(string connectionString);

...

DbDataReader ExecuteReader(IDbConnection connection, string query, CommandType cmdType, params IDbDataParameter[] commandParameters);

...

IDbDataParameter CreateParam(string paramName, object paramValue);
}
For concrete implementation. Create a class that implement IDBHelper interface. I named the class as SqlClientHelper.
    ...
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;

public class SqlClientHelper : IDbHelper
{
public IDbConnection CreateConnectionInstance(string connectionString)
{
return new SqlConnection(connectionString);
}

...

public DbDataReader ExecuteReader(IDbConnection connection, string query, CommandType cmdType, params IDbDataParameter[] commandParameters)
{
...
}

...

public IDbDataParameter CreateParam(string paramName, object paramValue)
{
SqlParameter param = new SqlParameter(paramName, paramValue);
...
}

...
}
Then, the code for OracleClientHelper.
    ...
using System;
using System.Data;
using System.Data.OracleClient;
using System.Data.Common;

public class OracleClientHelper : IDbHelper
{
public IDbConnection CreateConnectionInstance(string connectionString)
{
return new OracleConnection(connectionString);
}

...

public DbDataReader ExecuteReader(IDbConnection connection, string query, CommandType cmdType, params IDbDataParameter[] commandParameters)
{
...
}

...

public IDbDataParameter CreateParam(string paramName, object paramValue)
{
OracleParameter param = new OracleParameter(paramName, paramValue);
...
}

...
}
Noticed that the instantiation of connection and parameter object has been done in the class itself. Ideally, if we don't use any specific data provider namespaces in DAL layer, it should be flexible enough to use any database without the need to change the code logic. The concern is more on the abstract layer method signature.

Create an object factory that'll return the helper instance. This is the only place that we need to change if the project owner aka our client suddenly decided to use different data provider in future (reality is cruel).
    ...
public static class SomeObjectFactory
{
public static IDBHelper GetHelperInstance()
{
return new SqlClientHelper();

// uncomment the code below for oracle client
// return new OracleClientHelper();
}
}
The code at DAL
    ...
using (IDbConnection connection = SomeObjectFactory.GetHelperInstance().CreateConnectionInstance(connectionString))
{
connection.Open();

string query = "SELECT * FROM tblSomething WHERE Id = @Id";
IDbDataParameter param = MyObjectFactory.GetDBHelperInstance().CreateParam("@Id", id);

DBDataReader reader = SomeObjectFactory.GetHelperInstance().ExecuteReader(connection, query, CommandType.Text, param);

...
}
...
This way, adding System.Data and System.Data.Common namespace should be sufficient enough to our DAL.

Tuesday, September 21, 2010

Vulnerability in the ASP.NET encryption...

The Impact of the Vulnerability
ASP.NET uses encryption to hide sensitive data and protect it from tampering by the client. However, a vulnerability in the ASP.NET encryption implementation can allow an attacker to decrypt and tamper with this data.

But what can the attacker do with this capability? Part of the answer depends on the ASP.NET application being attacked. For example, if the ASP.NET application stores sensitive information, such as passwords or database connection strings, in the ViewState object this data could be compromised. The ViewState object is encrypted and sent to the client in a hidden form variable, so it is a possible target of this attack.

If the ASP.NET application is using ASP.NET 3.5 SP1 or above, the attacker could use this encryption vulnerability to request the contents of an arbitrary file within the ASP.NET application. The public disclosure demonstrated using this technique to retrieve the contents of web.config. Any file in the ASP.NET application which the worker process has access to will be returned to the attacker.

How the Vulnerability Works
To understand how this vulnerability works, you need to know about cryptographic oracles. An oracle in the context of cryptography is a system which provides hints as you ask it questions. In this case, there is a vulnerability in ASP.NET which acts as a padding oracle. This allows an attacker to send chosen cipher text to the server and learn if it was decrypted properly by examining which error code was returned by the server.

By making many requests the attacker can learn enough to successfully decrypt the rest of the cipher text. The attacker can then alter the plain text and re-encrypt it as well.

The Workaround - Silencing the Oracle
The workaround for this vulnerability is to use the customErrors feature of ASP.NET to configure applications to return the same error page regardless of the error encountered on the server.

By following the steps in the advisory to map all error messages to a single error page, you make it difficult for the attacker to distinguish between the different types of errors, effectively limiting access to the oracle.

How to Detect Vulnerable ASP.Net Applications
Script can be obtain from the original article.

Note:
Text copied from blogs.technet.com.

The vulnerability affects all versions of .NET Framework. Click here for detail.

Sunday, September 5, 2010

Evolution of data query in C#...

One of the most common operation in programming is data query. In C# 1.2, normally I would use a custom collection class that derived from System.Collections. But for sake of example here, I'll show it with an ArrayList instead.

Here's a class that'll become an element of the collection (yes, I know Auto-Implemented Properties).
    public class Student
{
private int _id;
private string _name;
private string _gender;

public Student()
{
}

public int Id
{
get { return _id; }
set { _id = value; }
}

public string Name
{
get { return _name; }
set { _name = value; }
}

public string Gender
{
get { return _gender; }
set { _gender = value; }
}
}
This is how I normally code in C# 1.2 (.NET Framework 1.1) with an ArrayList.
    private ArrayList SomeFilterMethod(ArrayList myList)
{
ArrayList result = new ArrayList();

for (int x = 0; x < myList.Count; x++)
{
if (((Student)myList[x]).Gender == "Male")
{
result.Add(myList[x]);
}
}

return result;
}
Generic list with action and predicate was introduced in C# 2.0 (.NET Framework 2.0). This is how my code will look like.
    private List<Student> SomeFilterMethod(List<Student> myList)
{
return mylist.FindAll(GetMaleStudents);
}

private bool GetMaleStudents(Student item)
{
return item.Gender == "Male";
}
Not to forget an anonymous methods.
    private List<Student> SomeFilterMethod(List<Student> myList)
{
return mylist.FindAll( delegate(Student item) { return item.Gender == "Male"; } );
}
In C# 3.0 (.NET Framework 3.5), there's LINQ with 2 flavours.
1) Lambda Expression
    private List<Student> SomeFilterMethod(List<Student> myList)
{
return mylist.FindAll( item => item.Gender == "Male" );
}
2) Query Expression
    private List<Student> SomeFilterMethod(List<Student> myList)
{
return (from student in mylist
where student.Gender == "Male"
select student).ToList<Student>();
}
Between the two, personally I prefer the former.