If you look at anti-XSS libraries they typically have different encodings for HTML content and HTML attributes. For instance using Microsoft's WPL implementation:
<@ Imports Namespace="Microsoft.Security.Application" %>
<span attribute="<%= AntiXss.HtmlAttributeEncode(attrVariable) %>">
<%= AntiXss.HtmlEncode(contentVariable) %>
</span>
Now ASP.Net has added encode bee-stings that make this easier:
<span attribute="<%: attrVariable %>">
<%: contentVariable %>
</span>
You can then specify the encoder to use in the web.config:
<system.web>
<httpRuntime encoderType="AntiXssEncoder, AssemblyName"/>
The encoder here knows whether to call HtmlAttributeEncode
or HtmlEncode
depending on the context.
My problem is that I have a smart class that implements IHtmlString
- this tells the <%:
syntax to bypass it entirely. However I still want to encode differently based on context:
<% var item = GetImplementationOfIHtmlString() %>
<span attribute="<%: item %>"> <!-- attribute encodes -->
<%: item %> <!-- HTML encodes -->
</span>
Is there any way for IHtmlString.ToHtmlString
to be aware of the context (encoding for HTML content or inside an attribute)?
No. The contract for custom HtmlEncode methods is that they must also be suitable for attribute encoding (when the attribute value is surrounded by quotes). This way the <%: %> syntax doesn't need contextual awareness.