In website content management, especially when the content includes rich formats or user input, how to safely output HTML tags is a crucial issue.AnQiCMS (AnQiCMS) took this into consideration from the outset, its template engine defaults to escaping output variables to effectively prevent cross-site scripting attacks (XSS) and other security risks.
Understanding the default behavior of template engines
The template engine of AnQi CMS borrows syntax from mainstream frameworks such as Django, one of its core concepts being 'Security First'. This means that when you use directly in the template,{{ 变量 }}When outputting content, all characters that may be interpreted as HTML tags (such as</>/&/"/') will be automatically converted to their corresponding entity characters (such as</>/&This automatic escaping mechanism is a powerful security shield that can prevent malicious users from attacking your website visitors by injecting malicious scripts into the content.
However, in the actual content operation, we inevitably encounter situations where it is necessary to display the real HTML content.For example, the main text of an article is usually edited using a rich text editor, which may contain paragraphs, images, links, and other HTML structures;Or in some custom fields, we want to embed specific style or widget HTML code.In this case, if the content is escaped by default, then the user will see the original HTML code, rather than the rendering effect we expect.
When do you need to avoid escaping?
In the following common scenarios, we may need to explicitly instruct the template engine not to escape HTML tags:
- Content generated by rich text editors:Website articles, product descriptions, single-page content, etc., which are usually created through a rich text editor (such as the one provided by AnQiCMS), inherently contain HTML structure.
- Rendered Markdown content:If the Markdown editor is enabled on the backend and the content is stored in Markdown format, the system will convert it to HTML when rendering.In order for these HTML to display normally, it is necessary to avoid escaping.
- Small amount of safe and controlled HTML fragments:In some cases, you may need to directly output a short segment of HTML code in the template, such as specific ad code, social sharing button code, or complex layout structures, and you are confident that the code is safe.
Important reminder:Only when you completely trust the source of content and are sure that it does not contain any malicious code should you consider avoiding escaping.Directly outputting untrusted input without escaping can pose serious security risks to the website.
The solution in AnQiCMS:safeFilters andautoescapeTag
AnQiCMS provides two main ways to control the escaping behavior of HTML tags:
1. Use|safeFilter
This is the most commonly used, most direct method, suitable for non-escaped output of a single variable. When you are sure that the content of a variable is safe HTML and you want the browser to render it, you can add|safefilter.
For example, on the article detail page, we usually displayarchive.ContentIf the content comes from a rich text editor, it is likely to contain HTML. At this point, we can output it like this:
<div>
{%- archiveDetail articleContent with name="Content" %}
{{ articleContent|safe }}
</div>
Here{{ articleContent|safe }}Tell the template engine explicitly,articleContentThe content in the variable is “safe”, no need for HTML escaping, output directly in HTML format.
For fields that may contain HTML, such as category descriptions, single-page content, and so on, the same applies:
{# 输出分类描述,假设其中可能包含HTML #}
<div>分类描述:{% categoryDetail categoryDescription with name="Description" %}{{categoryDescription|safe}}</div>
{# 输出单页内容,如果启用了Markdown渲染且需要避免转义 #}
<div>单页内容:{% pageDetail pageContent with name="Content" render=true %}{{pageContent|safe}}</div>
Please note,render=trueThe parameter only indicates that the system should convert Markdown content to HTML, but whether the converted HTML is escaped ultimately depends on|safethe filter.
2. Use{% autoescape off/on %}Tag
autoescapeThe tag allows you to control the escaping behavior of all variables within a template code block. This is very convenient when a large number of variables need non-escaped output in a specific area.
{% autoescape off %}: All variables within this tag block are not escaped by default.{% autoescape on %}: All variables within this tag block are escaped by default (the same as the default behavior).
For example, if you have an area that needs to display multiple custom HTML snippets, and all these snippets have been strictly reviewed:
{% autoescape off %}
<div class="custom-html-block">
{# 这里的 {{ variable_a }} 和 {{ variable_b }} 都不会被转义 #}
{{ variable_a }}
<p>这是一个不需要转义的文本。</p>
{{ variable_b }}
</div>
{% endautoescape %}
autoescapeThe tags have the following priority rules:
- In
autoescape offblock,{{ 变量 }}By default, it will not be escaped. - Even inside
autoescape offa block, you can still use{{ 变量|escape }}to force a specific variable to be escaped. - In
autoescape onAll variables inside the block will be escaped, unless you explicitly use{{ 变量|safe }}to declare it as safe content.
Practical suggestions in content management
- Clarify the purpose of the field: When adding or editing content model fields in the background, clarify whether the field allows HTML content. If allowed, prepare to use it in the template output.
|safe. - Default to secure, allow as needed:Always consider content escaping as the default safety mechanism. Only use it when the rendering effect does not meet expectations and you have carefully reviewed the content safety.
|safeorautoescape off. - Treat third-party content with caution:Any HTML content originating from external sources or directly input by users should be strictly sanitized and filtered, even if it has been used
|safeAlso, be vigilant. The security mechanisms provided by Anqi CMS, such as sensitive word filtering and anti-crawling, can be used as辅助, but control over the output at the template level is still a key skill you need to master.
By using it reasonably|safeFilters andautoescapeTags, you can flexibly control the output of HTML tags in AnQi CMS, ensuring the richness of website content while maintaining the security of the website to the greatest extent possible.
Frequently Asked Questions (FAQ)
1. Why does my article content, which is supposed to be in HTML format, display the raw tags after publishing, for example?<p>or<strong>?
This is because the template engine of Anqi CMS defaults to escaping all output variables to prevent XSS attacks.When you see the original HTML tags, it means the template engine has escaped them as plain text.To solve this problem, you need to find the template location that outputs this content and add it after the variable|safeFilter, for example, to convert{{ archive.Content }}is modified to{{ archive.Content|safe }}.
2.|safeFilters and{% autoescape off %}What is the difference between tags, and how should I choose?
They are all used to avoid HTML escaping, but their scope is different.|safeFilters act on a single variable, when you output{{ variable|safe }}at this time, only thisvariablecontent will not be escaped. And{% autoescape off %}The tag is applied to a code block, where all variables output are not escaped by default. If you only need to unescape one or two variables, use|safeMore precise; if you have a large number of variables that need to be non-escaped in a template area, useautoescape offThis can avoid duplication|safeBut make sure that all the content in this area is safe.
3. I am usingContentthe field and found that Markdown rendering did not work, or the rendered HTML was still escaped, why is that?
Does Markdown rendering work, usually depending on whether the Markdown editor is enabled on the backend. If Markdown is enabled,archiveDetailtags are being retrievedContentWhen a fieldrenderParameters such asrender=true), indicates that the system will convert Markdown to HTML.However, even if the content is successfully converted to HTML, the template engine will still default to escaping the output.Therefore, you need to ensure that the Markdown rendering is done in the template.Contentthe variable is also applied|safeFilter, for example{{ articleContent|safe }}so that the converted HTML can be displayed normally.