Building website templates in AnQiCMS (AnQiCMS), ensuring the safe display of content is a core issue, especially when the content may contain HTML tags or JavaScript code, and how to effectively prevent cross-site scripting (XSS) attacks is particularly important.The AnQi CMS is a Go language content management system that prioritizes security and considered these security challenges from the outset, providing mechanisms to help users manage and control the rendering of content.
Understand XSS attacks and their dangers
Firstly, we need to understand what XSS attacks are. XSS, or Cross-Site Scripting, refers to an attack where an attacker injects malicious scripts (usually JavaScript) into a webpage. When a user visits a page with injected scripts, these scripts will be executed in the user's browser.Malicious scripts can steal users' Cookie information (which may include session credentials, leading to account theft), modify web content (for phishing scams), redirect users to malicious websites, and even exploit browser vulnerabilities for deeper attacks.For a website, XSS attacks not only harm the interests of users, but also seriously affect the reputation and security of the website.
The default security mechanism of Anqi CMS: automatic escaping
The AnQi CMS template engine uses syntax similar to the Django template engine, one of its core advantages being the default automatic escaping of output content. This means that when you use it directly in the template,{{变量}}When displaying any content from the backend, the system will automatically convert HTML tags (such as<script>/<img>/<a>etc.) and special characters (such as&/"/'/</>) into their corresponding HTML entities.
For example, if a content field contains<script>alert('XSS');</script>By default, it will not be parsed by the browser as executable JavaScript code, but will be displayed as text<script>alert('XSS');</script>This automatic escaping mechanism is the first and most important line of defense against XSS attacks, ensuring the security of user input in most cases.
When is it necessary to display native HTML or JavaScript?
Even though automatic escaping provides strong protection, in certain specific business scenarios, we indeed need templates to be able to directly render HTML content. The most common scenarios include:
- Rich text editor content:When content (such as article details, product descriptions, single-page content, category introductions, etc.) is entered through the backend rich text editor, the content usually includes paragraphs, images, links, bold, italic, and other HTML tags, which are expected to be parsed and displayed in formatted effects by the browser.
- Custom embedded code:Sometimes, in order to integrate third-party services (such as video players, maps, ad codes, etc.), it may be necessary to embed a section of HTML or JavaScript code manually added by the administrator in the template.
- A small amount of trusted HTML fragments by administrators:Certain specific, strictly reviewed HTML structures may need to be rendered directly in the template.
In cases where it is necessary to display native HTML content, Anqi CMS provides|safeFilter, allowing us to explicitly tell the template engine: 'This content is safe, please do not escape it.'
Use|safeFilter: Trust and responsibility
When we need to display unescaped HTML or JavaScript content, we can add it after the variable|safeFilter. For example, on the document detail page, we usually display the article content like this:
<div>
{%- archiveDetail articleContent with name="Content" %}
{{articleContent|safe}}
</div>
Or on the page details:
<div>单页内容:{% pageDetail pageContent with name="Content" %}{{pageContent|safe}}</div>
|safeThe filter's role is to bypass the automatic escaping mechanism of the template engine, outputting the content of the variable as is into the HTML.
However, using|safefilters means transferring a huge amount of security responsibility.Once used|safeIt is equivalent to you declaring to the template engine:
- “I confirm the variable
articleContentThe content in this variable has been strictly reviewed and verified.” - I guarantee that this content does not contain any malicious scripts, even if it comes from user input.
If a user input containing malicious script is stored in the database without review, then through|safeThe filter is displayed in the template, in which case XSS attacks will occur. Therefore, when using|safeEnsure that the content source is reliable, or that the content has been strictly sanitized on the server before being stored in the database.
The Anqi CMS in content management (such as document content, page content, category content, tag content, etc.) will treat the content input from the rich text editor as input from administrators or trusted users, therefore it is used in templates.|safeIt is common and reasonable to render this content. But if some of your fields allow ordinary users to directly input HTML or JavaScript, and you use|safeBe extremely careful when displaying it.
More fine-grained control:autoescapewith the tag and|escapeFilter
except|safeThe template engine of AnQi CMS also provides a filter,autoescapeTags and|escapeA filter used to control the escaping behavior more granularly:
{% autoescape off/on %}Tags:Can be used to turn on or off the automatic escaping feature within a module block.{% autoescape off %}to{% endautoescape %}The content between them will not be automatically escaped.{% autoescape on %}It will force the escape to be enabled, even if the external environment has set it to be disabled. In actual use, since AnQi CMS is set to enable automatic escaping by default,onstatus is usually implicit, andoffThe state should be used with caution and is usually used for those content blocks that you completely trust and need to parse HTML.
|escapeFilter:This filter will force the content to be escaped as HTML entities. In the default automatic escaping environment of Anqi CMS,|escapeIt is usually redundant, because it just repeats the default behavior. But in some specific scenarios, like when you have turned it off,autoescapeyou can use it when a variable still needs to be escaped.
Special handling of JavaScript content:|escapejsFilter
If your content needs to be embedded into a JavaScript code block (for example, as a JavaScript variable value), simply use|safeOr allowing automatic escaping may not be enough to prevent all types of JS injection. At this point,|escapejsThe filter comes into play.
|escapejsThe filter will replace special characters in the content (such as"/'/\/\nEscape sequences (e.g.,"will become\"newline characters become\nThis can effectively prevent attackers from executing malicious JavaScript by closing strings or injecting new code lines.
Example usage:
`twig
var pageTitle = "{{ page.Title|escapejs }}";
// 恶意用户输入的 page.Title 如果是 '); alert('XSS'); ( 则会被转义为 \'); alert(\'XSS\'); (
// 从而无法执行恶意代码
</