Secure Coding

How To Find Vulnerabilities in ASP.NET Source Code

Sharing is caring!

icon-aspnet
This section describes methods of handling user-supplied input, ways of interacting with the user’s session, potentially dangerous APIs in the ASP.NET platform.

Identifying User-Supplied Data

ASP.NET applications acquire user-submitted input via the System.Web .HttpRequest class. This class contains various properties and methods that web applications can use to access user-supplied data.

There are various API can be used to obtain data from user request.
e.g. Params, QueryString, QueryString, Headers,UrlReferrer,Cookies, HttpMethod, InputStream etc.

Session Interaction

ASP.NET applications can interact with the user’s session to store and retrieve information in various ways. The Session property provides a simple way to store and retrieve information within the current session. It is accessed in the same way as any other indexed collection:

Session[“MyName”] = txtMyName.Text; // store user’s name
testWelcome.Text = “Welcome “+Session[“MyName”]; // retrieve user’s name

ASP.NET profiles work much like the Session property does, except that they are tied to the user’s profile and therefore actually persist across different sessions belonging to the same user. Users are re identified across sessions either through authentication or via a unique persistent cookie.

Data is stored and retrieved in the user profile as follows:

Profile.MyName = txtMyName.Text; // store user’s name
testWelcome.Text = “Welcome “ + Profile.MyName; // retrieve user’s name

The System.Web.SessionState.HttpSessionState class provides another way to store and retrieve information within the session. It stores information as a mapping from string names to object values, which can be accessed using the APIs e.g. Add, Keys.

Potentially Dangerous APIs

This section describes some common ASP.NET APIs that can introduce security vulnerabilities if used in an unsafe manner.

File Access

System.IO.File is the main class used to access files in ASP.NET. All of its relevant methods are static, and it has no public constructor.

The 37 methods of this class all take a filename as a parameter. Path traversal vulnerabilities may exist in every instance where user-controllable data is passed in without checking for dot-dot-slash sequences.

For example, the following code opens a file in the root of the C:\ drive on Windows:

string userinput = “..\\boot.ini”;
FileStream fs = File.Open(“C:\\temp\\” + userinput,
FileMode.OpenOrCreate);

The following classes are most commonly used to read and write file contents:

System.IO.FileStream
System.IO.StreamReader
System.IO.StreamWriter

They have various constructors that take a file path as a parameter. These may introduce path traversal vulnerabilities if user-controllable data is passed.

For example:

string userinput = “..\\foo.txt”;
FileStream fs = new FileStream(“F:\\tmp\\” + userinput, FileMode.OpenOrCreate);

Database Access

Numerous APIs can be used for database access within ASP.NET. The following are the main classes that can be used to create and execute a SQL statement:

-System.Data.SqlClient.SqlCommand
-System.Data.SqlClient.SqlDataAdapter
– System.Data.Oledb.OleDbCommand
– System.Data.Odbc.OdbcCommand
– System.Data.SqlServerCe.SqlCeCommand

Each of these classes has a constructor that takes a string containing a SQL statement. Also, each has a CommandText property that can be used to get and set the current value of the SQL statement. When a command object has been suitably configured, it is executed via a call to one of the various Execute methods.

If user-controllable input is part of the string being executed as a query, the application is probably vulnerable to SQL injection. For example:

string username = “admin’ or 1=1–”;
string password = “foo”;
OdbcCommand c = new OdbcCommand(“SELECT * FROM users WHERE username = ‘”+ username + “’ AND password = “’ + password + “’”, connection);
c.ExecuteNonQuery();

executes this unintended query:

SELECT * FROM users WHERE username = ‘admin’ or 1=1–’AND password = ‘foo’

Each of the classes listed supports prepared statements via their Parameters property, which allows an application to create a SQL statement containing parameter placeholders and set their values in a secure and type-safe way. If used as intended, this mechanism is not vulnerable to SQL injection. For example:

string username = “admin’ or 1=1–”;
string password = “foo”;
OdbcCommand c = new OdbcCommand(“SELECT * FROM users WHERE username [email protected] AND password = @password”, connection);
c.Parameters.Add(new OdbcParameter(“@username”, OdbcType.Text).Value =username);
c.Parameters.Add(new OdbcParameter(“@password”, OdbcType.Text).Value =password);
c.ExecuteNonQuery();

results in a query that is equivalent to the following:

SELECT * FROM users WHERE username = ‘admin’’ or 1=1–’
AND password = ‘foo’

OS Command Execution

The following APIs can be used in various ways to launch an external process from within an ASP.NET application:

System.Diagnostics.Start.Process
System.Diagnostics.Start.ProcessStartInfo

A filename string can be passed to the static Process.Start method, or the StartInfo property of a Process object can be configured with a filename before calling Start on the object. If the user can fully control the filename string, the application is almost certainly vulnerable to arbitrary command execution.

For example, the following causes the Windows calc program to run:

string userinput = “calc”;
Process.Start(userinput);

If the user controls only part of the string passed to Start, the application may still be vulnerable. For example:

string userinput = “..\\..\\..\\Windows\\System32\\calc”;
Process.Start(“C:\\Program Files\\MyApp\\bin\\” + userinput);

The API does not interpret shell metacharacters such as & and |, nor does it accept command-line arguments within the filename parameter. Therefore, this kind of attack is the only one likely to succeed when the user controls only a part of the filename parameter.

Command-line arguments to the launched process can be set using the Arguments property of the ProcessStartInfo class. If only the Arguments parameter is user-controllable, the application may still be vulnerable to something other than code execution. For example, if an application executes the program wget with a user-controllable parameter as the target URL, an attacker may be able to pass dangerous command-line parameters to the wget process. For example, the process might download a document and save it to an arbitrary location on the filesystem.

URL Redirection

The following APIs can be used to issue an HTTP redirect in ASP.NET:

-System.Web.HttpResponse.Redirect
– System.Web.HttpResponse.Status
-System.Web.HttpResponse.StatusCode
-System.Web.HttpResponse.AddHeader
– System.Web.HttpResponse.AppendHeader
-Server.Transfer

The usual means of causing a redirect response is via the HttpResponse. Redirect method, which takes a string containing a relative or absolute URL.If the value of this string is user-controllable, the application is probably vulnerable to a phishing vector.

You should also be sure to review any uses of the Status/StatusCode properties and the AddHeader/AppendHeader methods. Given that a redirect simply involves a 3xx response containing an HTTP Location header, an application may implement redirects using these APIs.

The Server.Transfer method is also sometimes used to perform redirection. However, this does not in fact cause an HTTP redirect. Instead, it simply changes the page being processed on the server in response to the current request. Accordingly, it cannot be subverted to cause redirection to an off-site URL, so it is usually less useful to an attacker.

Dynamic Code Execution

The VBScript function Eval takes a string argument containing a VBScript expression. The function evaluates this expression and returns the result.

If user controllable data is incorporated into the expression to be evaluated, it might be possible to execute arbitrary commands or modify the application’s logic.

The functions Execute and ExecuteGlobal take a string containing ASP code, which they execute just as if the code appeared directly within the script itself.

The colon delimiter can be used to batch multiple statements. If user-controllable data is passed into the Execute function, the application is probably vulnerable to arbitrary command execution.

Join The Discussion