.Net 4.0 is encoding single quote when using Attributes.Add
Asked Answered
Q

6

11

.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?

Quidnunc answered 6/8, 2013 at 9:7 Comment(0)
Q
0

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.

Quidnunc answered 4/12, 2013 at 12:26 Comment(0)
B
4

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.

Beera answered 6/8, 2013 at 11:49 Comment(2)
The java script that sets the attirbute client side was there, but the event didnt fire, I tried it on Chrome and IEQuidnunc
Same here - I can see the script to add the attribute - but it doesn't fire.Premiere
S
2

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'));
}
Spire answered 25/6, 2014 at 10:2 Comment(1)
the example you give does not really show a solution as the text you use contains no quotes. Consider this: link.Attributes["my_command"] = "myfunc('hello world')"; link.Attributes["onclick"] = "eval(this.my_command)";. The new attribute my_command does get encoded but is decoded by the eval() method.Bagwig
M
0

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

Meteorology answered 6/8, 2013 at 11:41 Comment(0)
Q
0

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.

Quidnunc answered 4/12, 2013 at 12:26 Comment(0)
I
0

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.

Illimani answered 23/4, 2014 at 17:18 Comment(0)
C
-3

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
Cobb answered 3/1, 2015 at 12:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.