Do I need to html-encode title attributes (tooltips)? - asp.net

In my markup I am using HTML title attributes which I set by the Tooltip property of various ASP.NET controls like an asp:Label. The content of those titles come from a database and I use data binding syntax, for instance:
<asp:Label ID="PersonLabel" runat="server"
Text='<%# HttpUtility.HtmlEncode(Eval("PersonShortName")) %>'
ToolTip='<%# HttpUtility.HtmlEncode(Eval("PersonFullName")) %>' />
Now, tooltips seem to be displayed as plain text on Windows and in the browsers I have tested. So the HTML-encoding is not what I really want and I am inclined to remove the encoding.
Can this be dangerous in any way if the database fields may contain script tags for example? My question is basically: Is it always guaranteed that HTML-title attributes are displayed as plain text? Are they always displayed as tooltips at all, or is it possible that some browsers (or OSs) display them in another way and allow and render HTML content in the title attributes?
Edit:
Looking at some of the answers it seems I didn't phrase my question well, so here are some additions:
If I have in the code snippet above a PersonShortName of "PM" in my database and as the PersonFullName a name with non-ASCII characters in it like Umlauts in "Peter Müller" the browser displays in the tooltip Peter Müller when I apply HttpUtility.HtmlEncode like in the code example - which is ugly.
I've also tested a simple HTML fragment like:
<span title="<script>alert('Evil script')</script>" >Hello</span>
The script in the title attribute didn't run in a browser with enabled Javascript (tested with Firefox), instead it was displayed in the tooltip as plain text. Therefore my guess was that title attributes are always rendered as plain text.
But as Felipe Alsacreations answered below there exist "rich tooltip plugins" which may render the title attribute as HTML. So in this case encoding is a good thing. But how can I know that?
Perhaps HttpUtility.HtmlEncode isn't the right solution and I have to filter only HTML tags but not encode simple special characters to make sure that the plain text is displayed correctly and to protect "rich HTML tooltips" at the same time. But it looks like a costly work - only for a simple tooltip.

Always sanitize output to the browser.
If a value like "><script>blabla</script> is inserted as a value for your fields, a user can essentially take over your entire site. It will probably make a mess when it comes to validation and correct code, but the script will still be run.
So to answer your question: No, it is not guaranteed that HTML-title attributes are displayed as plain text if the user knows what he/she is doing.

Beside security reasons:
Title attributes should always be plain text but certain JS plugins misuse them to display 'rich' tooltips (i.e. HTML code with bold text, emphasis, links and so on).
As for browsers and AFAIK they are displayed as plain text and tooltips, never displayed to those who use tabbed navigation (keyboard) and scren readers give to their users (blind and partially sighted people) many options, like reading the longest between link title and its text or always title or never ...

Surprisingly, still, no right answer in 5 years. The answer is: yes, you need to encode the title attribute, but not everything that is encoded in the innerText of the element.
The proper way to do it in asp.net if you do your own markup is:
string markup = string.Format("<div class='myClass' title='{0}'>{1}</div>",
System.Web.HttpUtility.HtmlAttributeEncode(myText),
System.Web.HttpUtility.HtmlEncode(myText));
The above will set both innerText and title of the div to myText, which is customary for elements that may contain long text but are constrained in width (as I believe the question implies).

The ToolTip property of a ASP.NET control will auto encode the value on output/rendering.
This means it is safe to set the tooltip to plain text as the page will sanitize the text on rendering.
Label1.ToolTip = "Some encoded text < Tag >"
Renders HTML output as:
<span title="Some encoded text < Tag >"></span>
If you need to use text that is already encoded, you can set the title attribute instead. The title attribute will not be automatically encoded on rendering:
Label1.Attributes("title") = "Some encoded text < Tag >"
Renders HTML output as:
<span title="Some encoded text < Tag >"></span>

Another point:
Who cares how the title attribute is rendered by a browser, when it is the presence of malicious strings in the source code that could present an issue?
It doesn't matter how it is displayed, the question is: how does it appear in the source code?
(As already stated, if you're pumping strings to the client, do something to sanitize those strings.)

I think there may be some confusion going on with this thread.
Firstly <asp:Label> is an ASP.NET Web Control. The Text and ToolTip attributes are "abstractions" of the inline content and 'title' attributes of an HTML tag respectively.
For these particular two properties Microsoft will perform the HTML Encoding for you automatically so if you set ToolTip="H&S<" then the <span> tag will be rendered as <span title="H&S<"...>. The same goes for the Text property.
NOTE: Not all properties perform automatic encoding (HTML or InnerContent properties for example)
If however you are generating HTML tags directly (Response.Write("<span...") for example) then you MUST http encode the text content and tooltip attributes content if:
Those values originate from a user / external unsanitised source or
If there is a possibility that the content may contain characters that should be escaped (& < > etc.)
Usually this means that it is safe to to:
Hardcoded content with no http characters:
Response.Write("<span title='Book Reference'>The art of zen</span>"); // SAFE
Hardcoded content with http characters that you manualle encode:
Response.Write("<span title='Book & Reference'>The art & zen</span>"); // SAFE
Dynamically sourced content:
Response.Write("<span title='"+sTitle+"'>"+sText+"</span>"); // UNSAFE
Response.Write("<span title='"+HttpUtility.HtmlEncode(sTitle)+"'>" +HttpUtility.HtmlEncode(sText)+"</span>"); // SAFE

Related

POST rendered text by Razor in ASP.NET MVC to server

I have a situation where I make a with some Razor. This is pretty standard, so imagine something like:
<div>
<strong>Undertegnede myndige skyldner</strong>:<br /><br />
#Model.ContractText.DebtorName, #Model.ContractText.DebtorFullAddress
#foreach (var reminder in Model.DemandStructure.ReminderFees_Lines)
{
#reminder.Label #: #reminder.Amount.ToCurrency()<br />
}
</div>
This becomes a nice piece of text.
What I want to do, is to POST this generated text, and store it on the server.
Possible solutions
Now, I could of course just generate this string on the server, but then I would loose the nice formatting of Razor.
I could use some templating language - but I am not familiar with anything that is easy and solves my problem to use on the server side?
Maybe it makes sense to wrap this in some kind of input field so it's POST-ed to server?
Does anyone have a simple and smart solution for how to POST a generated text-string to the server?
Do you mean post the text to the server in relation to a user action on the page?
If not, certainly do it server-side instead, and even in that case while yes, you potentially could wrap it in a form element (or probably wrap a copy of the text in for example a hidden element) and that will be submitted with any form submits - you probably shouldn't do this for a number of reasons;
The user will be able to edit the text before it is send to the server, and it looks like they shouldn't be able to, as then they could change the Amount value before it is stored
It will be hard to encode the newlines (they are br elements in your HTML but these don't post correctly to a newline in a string so you would have to convert them, or use a textarea instead)
It generates unnecessary network traffic.
What you should probably do is simply store it on the server-side code, using a format string to create the same resultant text;
var theText = $"Undertegnede myndige skyldner:{Envionment.NewLine}{Envionment.NewLine}{Model.ContractText.DebtorName}, {Model.ContractText.DebtorFullAddress}
{String.Join(Environment.NewLine, Model.DemandStructure.ReminderFees_Lines})";

Label html string being read by screen reader

I've got some dynamically generated html building a drop down menu using the Dojo library. I need to make my code Accessibility compliant and right now the screenreader looks at the menu item and reads it as plain html:
menu.addChild(new MenuItem({
label: "<a onclick=window.location.href='sampleurl.com'
href="sampleurl.com">Sample Link</a> ...
Excuse the onclick, it's for a different issue, but what I'm getting is basically:
Tab down to first menu item
Screenreader: "Less than a onclick equals window dot location dot href equals sampleurl"... etc
I've tried using aria-hidden, but the screen reader just reads that as text, I'm using voice over on Mac OS, but I need it compliant for JAWS as well. Any tips or advice? Thanks!
label is used for the label (which can be in HTML), not for putting the full link html tag.
See on the following page how to use the Dojo library to generate menu items:
https://dojotoolkit.org/reference-guide/1.10/dijit/Menu.html
Example:
menu.addChild(new MenuItem({
label: "Sample Link",
onclick: function() {window.location.href='sampleurl.com';}}));
This would be easier to debug with a working example along with something stating what screen reader / browser combo you are using. At the bare minimum, show us the HTML output of your script, considering it is writing HTML for the screen reader to parse.
That being said, I suspect the missing / inconsistent quotes. Note that you start a string with double quotes, then go into the onclick attribute with no quotes around, then single quotes around its value, and then use double quotes around the href.
Alternatively, you are writing the entire string into the page and somehow HTML encoding it.
I suggest using a linting tool to check your JS.

When does asp.net HTML encode elements?

In my database, I have a text field that contains escaped data:
"O'Neal"
I am trying to output it to my page like this:
LastName.InnerText = DB.LastName;
However, this results in this HTML on my page:
<h2 id="LastName">O&#39;Neal</h2>
What makes asp.net encode my HTML like this, and can I trust it to do this all the time?
Use InnerHtml instead of InnerText which will not encode data.
The official documentation of InnerText clearly says in the remarks section:
Unlike the InnerHtml property, the InnerText property automatically encodes special characters to and from HTML entities. HTML entities allow you to display special characters, such as the < character, that a browser would ordinarily interpret as having special meaning. The < character would be interpreted as the start of a tag and is not displayed on the page. To display the < character, you would need to use the entity <.
For example, if the InnerText property is set to "<b> Hello </b>", the < and > symbols are converted to < and >, respectively. The rendered output would be: <b> Hello </b>. The < and > entities would indicate to the browser that these characters are to be displayed on the page. The browser will not detect the <b> tags and display the text in a bold font. The text displayed on the page is: <b>Hello</b>.
To prevent automatic HTML encoding and decoding, use the InnerHtml property.

How to get value (non html) from ajax html editor

Please help me to get text (non html/ not formatted) from ajax text editor in asp.net i am using vs 2008.
i am using AjaxControlToolkit.HTMLEditor
you can see same kind of at : ajax HtmlEditor
Well, the documentation on the page you linked to only shows that the HTMLEditor has a Content property, which is the html text, not the plain text. However, the editor itself, on the page, allows you to view either the rendered html, or the html code (the markup).
The editor uses an <iframe> to contain the rendered html. If you want to get the plain text (no html tags), you'll have to do it on the clientside. The <iframe> has an id. You could use something like jquery to do this:
var plainText = $("#iframeID body").text();
$("#someHiddenField").val(plainText);
As long as someHiddenField is an <asp:HiddenField> control, it will contain the plain text of the editor when you post back. You just need to make sure you make the above assignment after you're done editing the HTMLEditor's content, but before you actually post back.
UPDATE
I answered another similar question, and my first answer might not actually get the text of the <iframe>. Try this:
var text = $("#iframeID").contents().find("body").text();
$("#ctl00_cpMainContent_Editor1_ctl02_ctl00").contents().find("body")[0].innerHTML

Input Validation When Using a Rich Text Editor

I have an ASP.NET MVC application and I'm using CKEditor for text entry. I have turned off input validation so the HTML created from CKEditor can be passed into the controller action. I am then showing the entered HTML on a web page.
I only have certain buttons on CKEditor enabled, but obviously someone could send whatever text they want down. I want to be able to show the HTML on the page after the user has entered it. How can I validate the input, but still be able to show the few things that are enabled in the editor?
So basically I want to sanitize everything except for a few key things like bold, italics, lists and links. This needs to be done server side.
How about AntiXSS?
See my full answer here from similar question:
I have found that replacing the angel
brackets with encoded angel brackets
solves most problems
You could create a "whitelist" of sorts for the html tags you'd like to allow. You could start by HTML encoding the whole thing. Then, replace a series of "allowed" sequences, such as:
"<strong>" and "</strong>" back to "<strong>" and "</strong>"
"<em>" and "</em>" back to "<em>" and "</em>"
"<li>" and "</li>" back to ... etc. etc.
For things like the A tag, you could resort to a regular expression (since you'd want the href attribute to be allowed too). You would still want to be careful about XSS; someone else already recommended AntiXSS.
Sample Regexp to replace the A tags:
<a href="([^"]+)">
Then replace as
<a href="$1">
Good luck!

Resources