Question

.Net 4.0 is encoding single quotes when I am using Attributes.Add to add client side events to my asp.net objects. In the previous versions this didn't happen.

for example :

<asp:Image runat="server" ID="imgTest" ImageUrl="~/DateControl/cal.gif" />

 imgTest.Attributes.Add("onmouseover", "alert('Hello')");

When I view the client side output, I am getting

 <img id="ctl00_MainContent_calFromTimeStamp1_imgTest" onmouseover="alert(&#39;Hello&#39;)" src="../DateControl/cal.gif" style="border-width:0px;" />

I found a workaround by creating a custom encoder : creating custom encoding routines but I don't want to stop the encoding for the whole website just because of this issue. Anybody got a workaround or an idea of how to fix this?

Was it helpful?

Solution 4

Thanks to Franzo's link, where the following answer is copied and pasted:

You can turn off attribute encoding by creating a class like this:

public class HtmlAttributeEncodingNot : System.Web.Util.HttpEncoder
{
    protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
    {
        output.Write(value);
    }
}

and adding this to web.config under :

<httpRuntime encoderType="HtmlAttributeEncodingNot"/>

This gives me the control I need.

However, now we must worry that new controls may depend on the new standard 4.0 behaviour and not encode single quotes, so it's still imperfect, nay, worse than imperfect: security is even worse, because we don't know what is going on where, so it's not a great workaround really.

I think only Microsoft can fix this properly. Others have suggested the need for an HtmlAttributeString class here: link If there were such a class and Attributes.Add could take an object like this for its value parameter then we would have the control that we need again.

OTHER TIPS

According to Microsoft you should not be adding JavaScript to HTML attributes using WebControl.Attributes.Add(), exactly because it will encode the attribute value:

You cannot add client-side script to a WebControl instance using the Attributes collection. To add client-side script, use the ClientScript property on the Page control.

Source

The advice is to use the Page.ClientScript.RegisterExpandoAttribute(string controlId, string attributeName, string attributeValue, bool encode) method. In your case it would look like this:

Page.ClientScript.RegisterExpandoAttribute(
  imgTest.ClientID, 
  "onmouseover", 
  "alert('Hello')", 
  false /* Do not encode */
);

This will result in a piece of JavaScript in your page that sets the attribute client-side.

The best way to set event attributes in .NET is to call a single function :

imgTest.Attributes("message") = "Hello";
imgTest.Attributes("onmouseover") = "showMessage(this);"

And on your page, or registered script :

function showMessage(ctrl) 
{
  alert(ctrl.getAttribute('message'));
}

imgTest.Attributes.Add("onmouseover", "alert(\'Hello\')");

It's not recommended to turn off attribute encoding. If you try to prevent encoding by default, there are many strange behaviors occurring with your code in future and you have to pay price for bad practices.

.NET is always encoding any attributes to stop from injecting malicious script. So you should go by this default practice to protect your program.

You can use an escape character before any quote character :

Source :

this.Attributes.Add("onmouseover", string.Format("$(this).attr(\'src\',\'{0}\')",this.Page.ClientScript.GetWebResourceUrl(typeof(SwapImage), urlenabledkey)));

Render :

onmouseover="$(this).attr('src','/WebResource.axd?d=kHY3FE9nMsUOvDU-pPthg4KQvVrnXlcASyA7dFf6L
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top