Security Tips for Copy/Paste of Code From the Internet

February 6, 2017 by · Comments Off on Security Tips for Copy/Paste of Code From the Internet
Filed under: Development, Security 

Developing applications has long involved using code snippets found through textbooks or on the Internet. Rather than re-invent the wheel, it makes sense to identify existing code that helps solve a problem. It may also help speed up the development time.

Years ago, maybe 12, I remember a co-worker that had a SQL Injection vulnerability in his application. The culprit, code copied from someone else. At the time, I explained that once you copy code into your application it is now your responsibility.

Here, 12 years later, I still see this type of occurrence. Using code snippets directly from the web in the application. In many of these cases there may be some form of security weakness. How often do we, as developers, really analyze and understand all the details of the code that we copy?

Here are a few tips when working with external code brought into your application.

Understand what it does

If you were looking for code snippets, you should have a good idea of what the code will do. Better yet, you probably have an understanding of what you think that code will do. How vigorously do you inspect it to make sure that is all it does. Maybe the code performs the specific task you were set out to complete, but what happens if there are other functions you weren’t even looking for. This may not be as much a concern with very small snippets. However, with larger sections of code, it could coverup other functionality. This doesn’t mean that the functionality is intentionally malicious. But undocumented, unintended functionality may open up risk to the application.

Change any passwords or secrets

Depending on the code that you are searching, there may be secrets within it. For example, encryption routines are common for being grabbed off the Internet. To be complete, they contain hard-coded IVs and keys. These should be changed when imported into your projects to something unique. This could also be the case for code that has passwords or other hard-coded values that may provide access to the system.

As I was writing this, I noticed a post about the RadAsyncUpload control regarding the defaults within it. While this is not code copy/pasted from the Internet, it highlights the need to understand the default configurations and that some values should be changed to help provide better protections.

Look for potential vulnerabilities

In addition to the above concerns, the code may have vulnerabilities in it. Imagine a snippet of code used to select data from a SQL database. What if that code passed your tests of accurately pulling the queries, but uses inline SQL and is vulnerable to SQL Injection. The same could happen for code vulnerable to Cross-Site Scripting or not checking proper authorization.

We have to do a better job of performing code reviews on these external snippets, just as we should be doing it on our custom written internal code. Finding snippets of code that perform our needed functionality can be a huge benefit, but we can’t just assume it is production ready. If you are using this type of code, take the time to understand it and review it for potential issues. Don’t stop at just verifying the functionality. Take steps to vet the code just as you would any other code within your application.

SQL Injection: Calling Stored Procedures Dynamically

October 26, 2016 by · Comments Off on SQL Injection: Calling Stored Procedures Dynamically
Filed under: Development, Security, Testing 

It is not news that SQL Injection is possible within a stored procedure. There have been plenty of articles discussing this issues. However, there is a unique way that some developers execute their stored procedures that make them vulnerable to SQL Injection, even when the stored procedure itself is actually safe.

Look at the example below. The code is using a stored procedure, but it is calling the stored procedure using a dynamic statement.

	conn.Open();
        var cmdText = "exec spGetData '" + txtSearch.Text + "'";
        SqlDataAdapter adapter = new SqlDataAdapter(cmdText, conn);
        DataSet ds = new DataSet();
        adapter.Fill(ds);
        conn.Close();
        grdResults.DataSource = ds.Tables[0];
        grdResults.DataBind();

It doesn’t really matter what is in the stored procedure for this particular example. This is because the stored procedure is not where the injection is going to occur. Instead, the injection occurs when the EXEC statement is concatenated together. The email parameter is being dynamically added in, which we know is bad.

This can be quickly tested by just inserting a single quote (‘) into the search field and viewing the error message returned. It would look something like this:

System.Data.SqlClient.SqlException (0x80131904): Unclosed quotation mark after the character string ”’. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at

With a little more probing, it is possible to get more information leading us to understand how this SQL is constructed. For example, by placing ‘,’ into the search field, we see a different error message:

System.Data.SqlClient.SqlException (0x80131904): Procedure or function spGetData has too many arguments specified. at System.Data.SqlClient.SqlConnection.

The mention of the stored procedure having too many arguments helps identify this technique for calling stored procedures.

With SQL we have the ability to execute more than one query in a given transaction. In this case, we just need to break out of the current exec statement and add our own statement. Remember, this doesn’t effect the execution of the spGetData stored procedure. We are looking at the ability to add new statements to the request.

Lets assume we search for this:

james@test.com’;SELECT * FROM tblUsers–

this would change our cmdText to look like:

exec spGetData’james@test.com’;SELECT * FROM tblUsers–‘

The above query will execute the spGetData stored procedure and then execute the following SELECT statement, ultimately returning 2 result sets. In many cases, this is not that useful for an attacker because the second table would not be returned to the user. However, this doesn’t mean that this makes an attack impossible. Instead, this turns our attacks more towards what we can Do, not what can we receive.

At this point, we are able to execute any commands against the SQL Server that the user has permission too. This could mean executing other stored procedures, dropping or modifying tables, adding records to a table, or even more advanced attacks such as manipulating the underlying operating system. An example might be to do something like this:

james@test.com’;DROP TABLE tblUsers–

If the user has permissions, the server would drop tblUsers, causing a lot of problems.

When calling stored procedures, it should be done using command parameters, rather than dynamically. The following is an example of using proper parameters:

    conn.Open();
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = "spGetData";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Connection = conn;
    cmd.Parameters.AddWithValue("@someData", txtSearch.Text);
    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    DataSet ds = new DataSet();
    adapter.Fill(ds);
    conn.Close();
    grdResults.DataSource = ds.Tables[0];
    grdResults.DataBind();

The code above adds parameters to the command object, removing the ability to inject into the dynamic code.

It is easy to think that because it is a stored procedure, and the stored procedure may be safe, that we are secure. Unfortunately, simple mistakes like this can lead to a vulnerability. Make sure that you are properly making database calls using parameterized queries. Don’t use dynamic SQL, even if it is to call a stored procedure.

Does the End of an Iteration Change Your View of Risk?

February 16, 2016 by · Comments Off on Does the End of an Iteration Change Your View of Risk?
Filed under: Development, Security, Testing 

You have been working hard for the past few weeks or months on the latest round of features for your flagship product. You are excited. The team is excited. Then a security test identifies a vulnerability. Balloons deflate and everyone starts to scramble.

Take a breath.

Not all vulnerabilities are created equal and the risk that each presents is vastly different. The organization should already have a process for triaging security findings. That process should be assessing the risk of the finding to determine its impact on the application, organization, and your customers. Some of these flaws will need immediate attention. Some may require holding up the release. Some may pose a lower risk and can wait.

Take the time to analyze the situation.

If an item is severe and poses great risk, by all means, stop what you are doing and fix it. But, what happens when the risk is fairly low. When I say risk, I include in that the ability for it to be exploited. The difficulty to exploit can be a critical factor in what decision you make.

When does the risk of remediation override the risk of waiting until the next iteration?

There are some instances where the risk to remediate so late in the iteration may actually be higher than waiting until the next iteration to resolve the actual issue. But all security vulnerabilities need to be fixed, you say? This is not an attempt to get out of doing work or not resolve issues. However, I believe there are situations where the risk of the exploit is less than the risk of trying to fix it in a chaotic, last minute manner.

I can’t count the number of times I have seen issues arise that appeared to be simple fixes. The bug was not very serious and could only be exploited in a very limited way. For example, the bug required the user’s machine to be compromised to enable exploitation. The fix, however, ended up taking more than a week due to some complications. When the bug appeared 2 days before code freeze there were many discussions on performing a fix, and potentially holding up the release, and moving the remediation to the next iteration.

When we take the time to analyze the risk and exposure of the finding, it is possible to make an educated decision as to which risk is better for the organization and the customers. In this situation, the assumption is that the user’s system would need to be compromised for the exploit to happen. If that is true, the application is already vulnerable to password sniffing or other attacks that would make this specific exploit a waste of time.

Forcing a fix at this point in the game increases the chances of introducing another vulnerability, possibly more severe than the one that we are trying to fix. Was that risk worth it?

Timing can have an affect on our judgement when it comes to resolving security issues. It should not be used as an escape goat or reason not to fix things. When analyzing the risk of an item, make sure you are also considering how that may affect the environment as a whole. This risk may not be directly with the flaw, but indirectly due to how it is fixed. There is no hard and fast rule, exactly the reason why we use a risk based approach.

Engage your information security office or enterprise risk teams to help with the analysis. They may be able to provide a different point of view or insight you may have overlooked.

ViewStateUserKey: ViewStateMac Relationship

November 26, 2013 by · Comments Off on ViewStateUserKey: ViewStateMac Relationship
Filed under: Development, Security, Testing 

I apologize for the delay as I recently spoke about this at the SANS Pen Test Summit in Washington D.C. but haven’t had a chance to put it into a blog. While I was doing some research for my presentation on hacking ASP.Net applications I came across something very interesting that sort of blew my mind. One of my topics was ViewStateUserKey, which is a feature of .Net to help protect forms from Cross-Site Request Forgery. I have always assumed that by setting this value (it is off by default) that it put a unique key into the view state for the specific user. Viewstate is a client-side storage mechanism that the form uses to help maintain state.

I have a previous post about ViewStateUserKey and how to set it here: http://www.jardinesoftware.net/2013/01/07/asp-net-and-csrf/

While I was doing some testing, I found that my ViewState wasn’t different between users even though I had set the ViewStateUserKey value. Of course it was late at night.. well ok, early morning so I thought maybe I wasn’t setting it right. But I triple checked and it was right. Upon closer inspections, my view state was identical between my two users. I was really confused because as I mentioned, I thought it put a unique value into the view state to make the view state unique.

My Problem… ViewStateMAC was disabled. But wait.. what does ViewStateMAC have to do with ViewStateUserKey? That is what I said. So I started digging in with Reflector to see what was going on. What did I find? The ViewStateUserKey is actually used to modify the ViewStateMac modifier. It doesn’t store a special value in the ViewState.. rather it modifies how the MAC is generated to protect thew ViewState from Parameter Tampering.

So this does work*. If the MAC is different between users, then the ViewState is ultimately different and the attacker’s value is different from the victim’s. When the ViewState is submitted, the MAC’s won’t match which is what we want.

Unfortunately, this means we are relying again on ViewStateMAC being enabled. Don’t get me wrong, I think it should be enabled and this is yet another reason why. Without it, it doesn’t appear that the ViewStateUserKey doesn’t anything. We have been saying for the longest time that to protect against CSRF set the ViewStateUserKey. No one has said it relies on ViewStateMAC though.

To Recap.. Things that rely on ViewStateMAC:

  • ViewState
  • Event Validation
  • ViewStateUserKey

It is important that we understand the framework features as disabling one item could cause a domino effect of other items. Be secure.

2012 in Review

December 31, 2012 by · Comments Off on 2012 in Review
Filed under: Development, Security, Testing 

Well here it is, 2012 is coming to an end and I thought I would wish everyone happy holidays, as well as mention some of the topics covered this year on my blog.

The year started out with a few issues in the ASP.Net framework. We saw a Forms Authentication Bypass that was patched at the very end of 2011 and an ASP.Net Insecure Redirect issue. Both of these issues show exactly why it is important to keep your frameworks patched.

Next, I did a lot of discussions about ViewStateMAC and EventValidation. This was some new stuff mixed in with some old. We learned that ViewStateMAC also protects the EventValidation field from being tampered with. I couldn’t find any MSDN documentation that states this fact. In addition, I showed how it is possible to manipulate the EventValidation field (when ViewStateMAC is not enabled) to tamper with the application. Here are some links to those posts:

I also created the ASP.Net Webforms CSRF Workflow, which is a small diagram to determine possible CSRF vulnerabilities with an ASP.Net web form application.

The release of .Net 4.5 was fairly big and some of the enhancements are really great. One of those, was the change in how Request Validation works. Adding the ability for lazy validation increases the ability to limit what doesn’t get validated. In addition, ModSecurity was released for IIS.

The release of the Web.Config Security Analyzer happened early on in the year. It is a simple tool that can be used to scan a web.config file for common security misconfigurations.

Some other topics covered included .Net Validators (lets not forget the check for Page.IsValid), Forms Authentication Remember Me functionality, how the Request Method can matter, and a Request Validation Bypass technique.

I discussed how XSS can be performed by tampering with the ViewState and the circumstances needed for it to be possible. This is commonly overlooked by both developers and testers.

In addition, I have created a YouTube channel for creating videos of some of these demonstrations. There are currently two videos available, but look forward to more coming in 2013.

There is a lot to look forward to in 2013 and I can’t wait to get started. Look for more changes and content coming out of Jardine Software and its resources.

I hope everyone had a great year in 2012 and that 2013 brings better things to come.

ViewState XSS: What’s the Deal?

September 17, 2012 by · Comments Off on ViewState XSS: What’s the Deal?
Filed under: Development, Security, Testing 

Many of my posts have discussed some of the protections that ASP.Net provides by default.  For example, Event Validation, ViewStateMac, and ViewStateUserKey.  So what happens when we are not using these protections?  Each of these have a different effect on what is possible from an attacker’s stand point so it is important to understand what these features do for us.  Many of these are covered in prior posts.  I often get asked the question “What can happen if the ViewState is not properly protected?”  This can be a difficult question because it depends on how it is not protected, and also how it is used.  One thing that can possibly be exploited is Cross-site Scripting (XSS).  This post will not dive into what XSS is, as there are many other resources that do that.  Instead, I will show how an attacker could take advantage of reflective XSS by using unprotected ViewState.

For this example, I am going to use the most basic of login forms.  The form doesn’t even actually work, but it is functional enough to demonstrate how this vulnerability could be exploited.  The form contains a user name and password textboxes, a login button, and an asp.net label control that displays copyright information.  Although probably not very obvious, our attack vector here is going to be the copyright label.

Why the Label?

You may be wondering why we are going after the label here.  The biggest reason is that the developers have probably overlooked output encoding on what would normally be pretty static text.  Copyrights do not change that often, and they are usually loaded in the initial page load.  All post-backs will then just re-populate the data from the ViewState.  That is our entry. Here is a quick look at what the page code looks like:

 1: <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
 2:     <span>UserName:</span><asp:TextBox ID="txtUserName" runat="server" />
 3:     <br />
 4:     <span>Password:</span><asp:TextBox ID="txtPassword" runat="server" TextMode="Password" />
 5:     <br />
 6:     <asp:Button ID="cmdSubmit" runat="server" Text="Login" /><br />
 7:     <asp:Label ID="lblCopy" runat="server" />
 8: </asp:Content>

We can see on line 7 that we have the label control for the copyright data.   Here is the code behind for the page:

 1: protected void Page_Load(object sender, EventArgs e)
 2: {
 3:     if (!Page.IsPostBack)
 4:     {
 5:         lblCopy.Text = "Copy 2012 Test Company";
 6:     }
 7: }

Here you can see that only on initial page load, we set the copy text.  On Postback, this value is set from the ViewState.

The Attack

Now that we have an idea of what the code looks like, lets take a look at how we can take advantage of this.  Keep in mind there are many factors that go into this working so it will not work on all systems.

I am going to use Fiddler to do the attack for this example.  In most of my posts, I usually use Burp Suite, but there is a cool ViewState Decoder that is available for Fiddler that I want to use here.  The following screen shows the login form on the initial load:

I will set up Fiddler to break before requests so I can intercept the traffic.  When I click the login button, fiddler will intercept the request and wait for me to fiddle with the traffic.  The next screen shows the traffic intercepted.  Note that I have underlined the copy text in the view state decoder.  This is where we are going to make our change.

The attack will load in a simple alert box to demonstrate the presence of XSS.  To load this in the ViewState Decoder’s XML format, I am going to encode the attack using HTML Entities.  I used the encoder at http://ha.ckers.org/xss.html to perform the encoding.  The following screen shows the data encoded in the encoder:

I need to copy this text from the encoder and paste it into the copy right field in the ViewState decoder window.  The following image shows this being done:

Now I need to click the “Encode” button for the ViewState.  This will automatically update the ViewState field for this request.   Once I do that, I can “Resume” my request and let it complete.   When the request completes, I will see the login page reload, but this time it will pop up an alert box as shown in the next screen:

This shows that I was able to perform an XSS attack by manipulating a ViewState parameter.  And as I mentioned earlier, this is reflected since it is being reflected from the ViewState.  Win for the Attacker.

So What, I Can Attack Myself

Often times, when I talk about this technique, the first response is that the attacker could only run XSS against themselves since this is in the ViewState.  How can we get that to our victim.  The good news for the attacker…. .Net is going to help us attack our victims here.  Without going into the details, the premise is that .Net will read the ViewState value from the GET or POST depending on the request method.  So if we send a GET it will read it from the querystring.   So if we make the following request to the page, it will pull the ViewState values from the QueryString and execute the XSS just like the first time we ran it:

http://localhost:51301/Default.aspx?__VIEWSTATE=%2fwEPDwU
KLTE0NzExNjI2OA9kFgJmD2QWAgIDD2QWAgIFD2QWAgIHDw8WAh4
EVGV4dAUlQ29weTxzY3JpcHQ%2bYWxlcnQoOSk7PC9zY3JpcHQ%2b
Q29tcGFueWRkZA%3d%3d&ctl00%24MainContent%24txtUserName=
&ctl00%24MainContent%24txtPassword=
&ctl00%24MainContent%24cmdSubmit=Login

Since we can put this into a GET request, it is easier to send this out in phishing emails or other payloads to get a victim to execute the code.  Yes, as a POST, we can get a victim to run this as well, but we are open to so much more when it is a GET request since we don’t have to try and submit a form for this to work.

How to Fix It

Developers can fix this issue quite easily.  They need to encode the output for starters.  For the encoding to work, however, you should set the value yourself on postback too.  So instead of just setting that hard-coded value on initial page load, think about setting it every time.  Otherwise the encoding will not solve the problem.  Additionally, enable the built in functions like ViewStateMac, which will help prevent an attacker from tampering with the ViewState, or consider encrypting the ViewState.

Final Thoughts

This is a commonly overlooked area of security for .Net developers because there are many assumptions and mis-understandings about how ViewState works in this scenario.  The complexity of configuration doesn’t help either.  Many times developers think that  since it is a hard-coded value.. it can’t be manipulated.   We just saw that under the right circumstances, it very well can be manipulated.

As testers, we need to look for this type of vulnerability and understand it so we can help the developers understand the capabilities of it and how to resolve it.  As developers, we need to understand our development language and its features so we don’t overlook these issues.  We are all in this together to help decrease the vulnerabilities available in the applications we use.

Updated [11/12/2012]: Uploaded a video demonstrating this concept.

ASP.Net Webforms CSRF Workflow

February 7, 2012 by · Comments Off on ASP.Net Webforms CSRF Workflow
Filed under: Security, Testing 

An important aspect of application security is the ability to verify whether or not vulnerabilities exist in the target application.  This task is usually outsourced to a company that specializes in penetration testing or vulnerability assessments.  Even if the task is performed internally, it is important that the testers have as much knowledge about vulnerabilities as possible.  It is often said that a pen test is just testing the tester’s capabilities.  In many ways that is true.  Every tester is different, each having different techniques, skills, and strengths. Companies rely on these tests to assess the risk the application poses to the company.

In an effort to help add knowledge to the testers, I have put together a workflow to aid in testing for Cross Site Request Forgery (CSRF) vulnerabilities.  This can also be used by developers to determine if, by their settings, their application may be vulnerable.  This does not cover every possible configuration, but focuses on the most common.  The workflow can be found here: CSRF Workflow.  I have also included the full link below.

Full Link: http://www.jardinesoftware.com/Documents/ASP_Net_Web_Forms_CSRF_Workflow.pdf

Happy Testing!!

 

The information is provided as-is and is for educational purposes only.  Jardine Software is not liable or responsible for inappropriate use of this information.

ViewStateMAC: Seriously, Enable It!

February 1, 2012 by · Comments Off on ViewStateMAC: Seriously, Enable It!
Filed under: Development, Security 

I have been doing a lot of research lately around event validation and view state.  I have always been interested in how Event Validation worked under the covers and if it could be tampered with.  I will attempt to explain that it is, in fact, possible to tamper with the Event Validation field in a similar manner that view state can be tampered.  I know, the title of the post reads “ViewStateMAC”, don’t worry I will get to that.  But first, it is important to discuss a little about how Event Validation works to understand why ViewStateMAC is important.

__EVENTVALIDATION – Basics

Event Validation is a feature that is built into ASP.Net web forms.  It is enabled by default and it serves the purpose to ensure that only valid data is received for  controls that register valid events or data.  As a quick example, think for a moment about a drop down list.  Each value that is programmatically added to the control will be registered with Event Validation.  Code Example 1 demonstrates loading values into a drop down list (data binding is also very common).  Each of these values will now exist in the Event Validation feature.  When a user attempts to submit a form, or post back, the application will verify the value submitted for that control is a valid value.  If it is not, a not so pretty exception is generated.

Example 1
private void FillDDL2()
{
  ddlList.Items.Add(new ListItem("1", "1"));
  ddlList.Items.Add(new ListItem("2", "2"));
  ddlList.Items.Add(new ListItem("3", "3"));
  ddlList.Items.Add(new ListItem("4", "4"));
  ddlList.Items.Add(new ListItem("5", "5"));
}

__EVENTVALIDATION – Hash

Event Validation is primarily based on storing a hash value for each of the values it needs to check for validity.  More specifically, there is a specific routine that is run to create an integer based hash from the control’s unique id and the specified value (the routine is beyond the scope of this post).  Every value that gets stored in Event Validation has a corresponding integer hash value.  These hash values are stored in an array list which gets serialized into the string that we see in the __EVENTVALIDATION hidden form field on the web page. 

__EVENTVALIDATION – Page Response

When a page is requested by the user it goes through an entire lifecycle of events.  To understand how Event Validation really works, lets first take a look at how the field is generated.  Before the page is rendered, each control or event that is registered for event validation will have its value hashed (see previous section) and added to the array list.  As mentioned before, this can be values for a list control, valid events for the page or controls (for example, button click events), and even View State.  This array is serialized and stored in the __EVENTVALIDATION hidden field.

__EVENTVALIDATION – Post Back Request

The request is where Event Validation takes action.  When a user submits a post back to the server, event validation will validate the values that have been registered.  So in the Drop Down List example in "Example 1” Event Validation is there to make sure that only the values 1-5 are submitted for ddlList.  It does this by taking the value that was sent (Request.Form[“ddlList”]) and re-generates the numeric hash.  The hash is then compared to the list and if it exists, the value is allowed.  If it doesn’t exist in the de-serialized Event Validation list, then an exception is thrown and the page cannot continue processing.

__EVENTVALIDATION – Manipulation

De-serializing the Event Validation value is pretty easy.  This is very similar to how it is done for View State.  After writing my own tool to tamper with the Event Validation, I found the ViewState Viewer (http://labs.neohapsis.com/2009/08/03/viewstateviewer-a-gui-tool-for-deserializingreserializing-viewstate/) plug-in for Fiddler.  The ViewState Viewer plugs right into Fiddler with no issues.  Don’t let the name mislead you, this tool works great with the Event Validation data as well.  When you paste in your Event Validation string and click the “Decode” button, it generates a nice XML snippet of the contents.  The screen shot below demonstrates the Event Validation value and its decoded value from a test page I created.

Once you have the information decoded, you can now add in your own integers to the System.Collections.ArrayList.  Look closely and you might see that the last integer –439972587 is not aligned with the rest of the items.  This is because that is a custom value that I added to the event validation.  These numbers don’t look like they really mean anything, but to Event Validation, they mean everything.  If we can determine how to create our own numbers, we can manipulate what the server will see as valid data.  Once you have made your modifications, click the “Encode” button and the value in the top box will refresh with the new __EVENTVALIDATION value.  It may be possible to attempt brute forcing the data you want (if you can’t create the exact hash code) by just padding a bunch of integers into the list and submitting your modified data.  This is definitely hit or miss, could be time consuming, and would probably generate a lot of errors for someone to notice.  We are monitoring our error logs right?

__EVENTVALIDATION – Thoughts

Maybe just me, but I always thought that if I had event validation enabled, as a developer, I didn’t have to validate the data from drop down lists that was submitted.  I thought that this type of data was protected because event validation enforced these constraints.  This is obviously not the case and honestly brings up a very important topic for another day; “We shouldn’t be relying solely on configuration for protection”.  Although this post uses the drop down lists as an example, this has a much greater effect.   What about buttons that are made visible based on your role.  If event validation can be tampered with, now those buttons that didn’t exist, can have their events added to the acceptable list.  If you are not checking that the user has the proper role within that event, you may be in big trouble. 

So what types of attacks are possible?

  • Parameter tampering
  • Authorization bypass
  • Cross Site Scripting
  • Maybe More…

ViewStateMAC – Finally!!

Ok, it is not all bad news and finally we come to our friend (or worst enemy if it is disabled) ViewStateMAC.  Keep in mind that ViewStateMAC is enabled by default, so if this is disabled, it was done explicitly.  ViewStateMAC adds a message authentication code to ViewState obviously, judging by its name.   Basically, it adds a hash to the view state so that an attacker cannot tamper with its data.  So if we go back to the drop down list, if a developer uses code like Example 2 to access the selected item, then you have to be able to tamper the view state, otherwise the first item in the original item will get selected.  But if you use code like Example 3 to access that data, you could add your value to the EventValidation and get it accepted by the application.   Or can you?

Example 2
protected void cmdSubmit_Click(object sender, EventArgs e)
{
  Response.Write(ddlList.SelectedItem.Value);
}

Example 3
protected void cmdSubmit_Click(object sender, EventArgs e)
{
  Response.Write(Request.Form["ddlList"].ToString());
}

Actually, ViewStateMAC does more than sign ViewState, it also signs the Event Validation value.  I was not able to identify any documentation on MSDN that indicates this feature, but apparently __PREVIOUSPAGE may get signed with this as well.  I have run extensive tests and can confirm that ViewStateMAC is critical to signing Event Validation.  So in general, If ViewStateMAC is enabled, it protects both ViewState and Event Validation from being tampered with.  That is pretty important and I am not sure why it is not listed on MSDN.  Unfortunately, disable it and it creates a much greater security risk than initially thought because it effects more than ViewState. 

ViewStateMAC – Not a Replacement for Input Validation

In no way should a developer rely solely on ViewStateMAC, Event Validation and ViewState as their means of input validation.  The application should be developed as if these features do not even exist.  Drop down lists should be validated that only valid values were submitted.  Control events should be verified that they are allowed.   Why not use these features?  I am not saying that you should not use these features, but they should be in addition to your own input validation.  What if ViewStateMAC were to get disabled during testing, or for some other unknown reason?  Even if Event Validation is still enabled, it is not looking good.  Unless you have ViewState being encrypted, which would help block tampering with the view state, an attacker could still manipulate the event validation code. 

Conclusion

The details provided here have been high level with not much actual detail in actually manipulating the Event Validation field.  The post would be too long to include all the details here.  Hopefully there is enough information to make developer’s aware of the severity of ViewStateMAC and how Event Validation actually works.  From a penetration tester’s view, if you visit a .net webform application with ViewStateMAC disabled, this should be researched more to help accurately identify risk for the application.  Devs, please, please, please do not disable this feature.  If you are on a web farm, make sure the same machine key is set for each machine and this should be supported. Remember, these features are helpers, but not complete solutions.   You are responsible for performing proper input validation to ensure that the data you expect is what you accept.

The information provided is for informational and educational purposes only.  The information is provided as-is with no claim to be error free.  Use this information at your own risk.

ASP.Net 4: Change the Default Encoder

July 9, 2011 by · Comments Off on ASP.Net 4: Change the Default Encoder
Filed under: Development, Security 

In ASP.Net 4.0, Microsoft added the ability to override the default encoder.  This is specifically focused on the HTMLEncode, HTMLAttributeEncode, and URLEncode functionality.  These functions are used, in the eyes of security, to help mitigate cross-site scripting (XSS).  The problem with the built in .Net routines is that they are built on a black-list methodology, rather than a white-list methodology.  The built in routines use a very small list of characters that get encoded.  For example, the .Net version of HTMLEncode encodes the following characters: <,>,”,&.   The Microsoft Web Protection Library (previously known as the Anti-XSS Library) instead determines all characters that don’t need encoding, a-z0-9 for example, and then encodes all the rest.  This is a much safer approach to encoding. 

In this post, I will show you how to use the Web Protection Library as the default encoder for an ASP.Net 4.0 application.  The first step is to download the Web Protection Library.  In this example, I use version 4.0 which can be found at: http://wpl.codeplex.com/

Next, you will need to have an application to implement this.  You can use an existing application, or create a new one.  Add a reference to the AntiXSSLibrary.dll found in” Program Files\Microsoft Information Security\AntiXSS Library v4.0”.

To use the library, it is time to create a new class.  You can see the code in my class in Figure 1.  I named the class “MyEncoder” and this is just a sample. (THIS IS NOT PRODUCTION CODE)  There are two important factors to this class:

1.  The class must inherit from System.Web.Util.HttpEncoder.

2.  You must override each Encode Method you want to change.

If you only wanted to update the HTMLEncode and leave the other methods alone, just leave them out of the class.

Figure 1

using System;
using System.Web;

public class MyEncoder : System.Web.Util.HttpEncoder
{
  public MyEncoder(){}

    protected override void HtmlEncode(string value, System.IO.TextWriter output)
    {
        if (null == value)
            return;

        output.Write(Microsoft.Security.Application.Encoder.HtmlEncode(value));
    }
    protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
    {
        if (null == value)
            return;

        output.Write(Microsoft.Security.Application.Encoder.HtmlAttributeEncode(value));
    }
}

The final step to implementing this custom encoding is to update the web.config file. To do this, modify your httpRuntime element to have the “encoderType” attribute set, as seen in Figure 2.  Change “MyEncoder” to the name of the class you created.  If you do not have the httpRuntime element, just add it in.

Figure 2

  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    <httpRuntime encoderType="MyEncoder"/>
    .....

Although it would be really nice if the .Net Framework would just start using the Web Protection Library, they are just not ready for that yet.  It is important that plenty of testing is always done when working with output encoding.  Different encoders produce different outputs and may cause display defects.  It is also important to note that this only effects items that get auto-encoded by the framework.  For example, a text property of a textbox.

This is just a small example of modifying the default encoding type of your application.  There is much more that you could potentially do with this.  This is just a sample and this code is NOT FOR PRODUCTION USE.