christok
christok

Reputation: 1107

Extending/overriding existing ASP.NET controls

I have a project with a whole bunch of labels, text boxes, and other web controls. There are literally hundreds of them.

I want now to be able to override certain properties in order to run content through an anti-XSS library. For example, when I set the text property of a label using data from a database I want to automatically run a function to scrub out any potentially malicious code.

I also tried overriding the text property using a class that implements IExtenderProvider but I could't get it to help.

Had I been building this from scratch I may have opted to create a new label class that inherits the system label class. Due to the size of the project I would rather not do that.

Any thoughts?

Upvotes: 5

Views: 1527

Answers (2)

Michael Liu
Michael Liu

Reputation: 55419

First, I'll note that the right way to avoid XSS vulnerabilities is to properly encode user input before embedding it in your page. For example, if you're assigning a plain text string to the Text property of a Label, you need to encode the value because the Text property is rendered verbatim as HTML:

label.Text = HttpUtility.HtmlEncode(user.Name)

(Note: By "plain text" I mean text where characters like < and & don't have any special meaning.)

Second, as an additional defense-in-depth measure, you should validate user input when you collect it. But input validation does not negate the need to properly encode user input (because something might slip by). Always encode user input!

Okay, let's assume you're going to do that as time and testing allow, but you need a quick fix right now. You can create control adapters that change how particular types of controls are rendered. Here's an example which adds some asterisks to every single <asp:Label> in your application:

Imports System.Web.UI
Imports System.Web.UI.WebControls.Adapters

Public Class LabelControlAdapter
    Inherits WebControlAdapter

    Protected Overrides Sub RenderContents(writer As HtmlTextWriter)
        Dim label As Label = Me.Control
        label.Text = "***" + label.Text + "***"  ' TODO: Use your anti-XSS library
        MyBase.RenderContents(writer)
    End Sub
End Class

You can create additional control adapters for other types of controls, or modify LabelControlAdapter to sniff the type of Me.Control and do something different.

You also need to add a .browser file to your site's App_Browsers folder that lists each of the control types you're adapting:

<browsers>
    <browser refID="Default">
        <controlAdapters>
            <adapter
                controlType="System.Web.UI.WebControls.Label"
                adapterType="TempVBWebApp.LabelControlAdapter, TempVBWebApp" />
        </controlAdapters>
    </browser>
</browsers>

Upvotes: 1

charlesw
charlesw

Reputation: 612

I assume that for some reason you are unable to modify the code of the existing controls, otherwise you could just add the anti-xss code to them.

In that case you can use the shadowing ability of VB.Net: http://msdn.microsoft.com/en-us/library/1h3wytf6.aspx

Here is an example of how you might implement it:

Module Module1

    Sub Main()

    End Sub

    'Placeholder for antiXSS library functions 
    Public Function antiXSS(ByVal input As String) As String
        Return input
    End Function

    'Original control class 
    Public Class originalControlClass
        Private _name As String
        Public Property name As String
            Get
                Return _name

            End Get
            Set(value As String)
                _name = value
            End Set
        End Property
    End Class

    Public Class securedControlClass
        Inherits originalControlClass
        Public Shadows Property name As String
            Get
                'return value from base class
                Return MyBase.name
            End Get
            Set(value As String)
                'Run anti-XSS code and pass result to base class
                MyBase.name = antiXSS(value)
            End Set
        End Property
    End Class
End Module 

Here, securedControlClass is inheriting originalControlClass but has shadowed the 'name' property. This means that any calls to securedControlClass.*name* will always go it its implementation of the property instead of originalControlClass's implementation.

With this solution you will have to create a new class for each control who's properties you wish to override. You will also have to go through your code and change all references to the original controls (i.e. originalControlClass) to your new version (i.e. securedControlClass). This may take a while depending on how many controls you have and how many times they are used, but I believe that it should result in minimal errors.

A couple issues to consider:

  1. This isn't great as a long term solution. It adds some complexity that could be avoided if you were able to modify the controls directly to add the XSS code.
  2. You have to make sure that everybody who works on the project uses the secured controls and not the other ones, otherwise you will have vulnerable controls :)

Upvotes: 0

Related Questions