Skip to content

Power Pages: Escape Filters

Nicholas Hayduk April 27, 2026 3 Min.To Read

If you give your Power Pages code to an AI tool for analysis, there is a good chance that it might tell you that you have unescaped Liquid code. In this post, I’ll cover what that means, whether it is as bad as the tool might say, and what your options are to fix it.

Category:

Escaping Your HTML

HTML is a markup language (it literally stands for HyperText Markup Language) – this means that HTML is a mix of the actual content that the users see, as well as the XML tags that define how it is displayed.

For example, to distinguish between different paragraphs of text, the <p> tag is used. If you look at the source code of a page, you’ll see paragraphs start with an opening <p> tag, and finish with an ending </p> tag. The user doesn’t see either of these tags, they just see the results of the tags being there because that text is shown as a paragraph.

So in your HTML, if you put in <p>, the user won’t see it. But what if you actually want the user to see the three characters of <p> on the page (like I’m doing here)? Then you have to escape it.

To actually display a < character, you put &lt; in the HTML code (where lt stands for less than). &gt;, greater than, is used for >. So, if you put &lt;p&gt; in your HTML, the user sees <p>.

This is called escaping – replacing special characters, in this case the < and > symbols, with representations that are displayed as literal text, in this case &lt; and &gt;.

Escaping Your Liquid

Within Liquid, we have a number of filters that perform common types of escaping:

  • escape (or its alias ‘h’): HTML escaping
  • html_safe_escape: strips out unsafe HTML elements (such as JavaScript), but safe HTML elements like img, p, h1, etc. remain as is
  • xml_escape: XML escaping
  • url_escape: escaping URLs for use in links

Note that escape and xml_escape often produce the same output, since HTML is a form of XML. Use escape (or h) when outputting to the browser, and use xml_escape when adding to other XML, such as FetchXML.

But What Does This Have To Do With Security?

As with many things in security, it all comes down to trust. When you use Liquid to display some data from Dataverse, do you trust that data?

For example, consider this Liquid code:

{{ entities['new_customtable'][request.params.id].new_description }}

This will send whatever exists within the Description column for that row to the user’s browser. Maybe it is some simple text. Maybe it is some text formatted with HTML tags. Or maybe it contains a <script> tag that will execute some JavaScript.

If the Description comes from the users of the site, the answer is you should not trust it.

If the Description comes from administrators of the site, some would argue the answer should still be no, since it is possible for access to Dataverse to be compromised. Now, if your Dataverse is compromised, then your Power Pages site might not be at the top of the list in terms of worries, but even still, if you can protect yourself, that is never a bad thing.

So if you are dealing with data you don’t trust, it is best to handle that data carefully.

How Do Escape Filters Help?

Escape filters help protect us by removing things that we don’t expect to be there.

  • We use escape (or h) when we display something where we are only expecting simple text. That way, if a bad actor put in HTML, or even worse, JavaScript, the user sees the full markup, but nothing is executed.
  • We use html_safe_escape when we display something where we are OK with HTML formatting tags, but don’t want to include JavaScript.

The big risk is a bad actor adding some JavaScript that executes in all of the users’ browsers – this is a type of Cross Site Scripting (XSS). Using either of these filters will help prevent that.

So, if we are expecting simple text, use:

{{ entities['new_customtable'][request.params.id].new_description | escape }}

If you are OK with HTML, but want to prevent JavaScript, use:

{{ entities['new_customtable'][request.params.id].new_description | html_safe_escape }}

Of course, if your Dataverse is compromised, the bad actor could remove the filters as well. But the filters do make it harder.

Should I Go Back To Add Escape Filters?

If you have a site that is in production, should you go and add any missing escape filters?

If the data is coming from an untrusted source, like users, definitely.

If the data is coming from Power Pages makers or administrators, I don’t think it is as urgent. I would start using escape filters moving forward, and add them to existing code if you are working on other things in that file.

But to go through an entire site just to add escape filters on data coming from trusted sources does not seem to me to be worth the effort, compared to the actual risk.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top