返回介绍

Mechanisms

发布于 2024-10-11 20:34:02 字数 12170 浏览 0 评论 0 收藏 0

To understand how template injections work, you need to understand the mechanisms of the template engines they target. Simply put, template engines combine application data with web templates to produce web pages. These web templates, written in template languages such as Jinja, provide developers with a way to specify how a page should be rendered. Together, web templates and template engines allow developers to separate server-side application logic and client-side presentation code during web development.

要了解模板注入的工作原理,您需要了解它们所针对的模板引擎的机制。简而言之,模板引擎将应用程序数据与 Web 模板组合在一起,生成 Web 页面。这些 Web 模板是用诸如 Jinja 之类的模板语言编写的,为开发人员提供了一种指定如何呈现页面的方法。Web 模板和模板引擎一起,在 Web 开发期间允许开发人员分离服务器端应用程序逻辑和客户端呈现代码。

Template Engines

Let’s take a look at Jinja, a template language for Python. Here is a template file written in Jinja. We will store this file with the name example.jinja :

让我们来看看 Jinja,这是 Python 的一个模板语言。这是一个用 Jinja 编写的模板文件。我们将把这个文件保存为 example.jinja 的名称:

<html>
  <body>
1 <h1>{{ list_title }}</h1>
  <h2>{{ list_description }}</h2>
2 {% for item in item_list %}
    {{ item }}
    {% if not loop.last %},{% endif %}
  {% endfor %}
  </body>
</html>

As you can see, this template file looks like normal HTML. However, it contains special syntax to indicate content that the template engine should interpret as template code. In Jinja, any code surrounded by double curly brackets {{ }} is to be interpreted as a Python expression, and code surrounded by bracket and percent sign pairings {% %} should be interpreted as a Python statement.

你可以看到,这个模板文件看起来像普通 HTML。然而,它包含特殊的语法来指示模板引擎应该将其解析为模板代码的内容。在 Jinja 中,任何被双花括号{{}} 包围的代码都将被解释为 Python 表达式,而被括号和百分号配对{% %}包围的代码将被解释为 Python 语句。

In programming languages, an expression is either a variable or a function that returns a value, whereas a statement is code that doesn’t return anything. Here, you can see that the template first embeds the expressions list_title and list_description in HTML header tags 1 . Then it creates a loop to render all items in the item_list variable in the HTML body 2 .

在编程语言中,表达式指的是变量或返回值的函数,而语句则是不返回任何值的代码。在这里,你可以看到该模板首先将表达式 list_title 和 list_description 嵌入到 HTML 头标签 1 中。然后,它创建一个循环来在 HTML 正文 2 中呈现 item_list 变量中的所有项目。

Now the developer can combine the template with Python code to create the complete HTML page. The following piece of Python code reads the template file from example.jinja and generates an HTML page dynamically by providing the template engine with values to insert into the template:

现在开发者可以将模板与 Python 代码结合使用,创建完整的 HTML 页面。下面的 Python 代码从 example.jinja 读取模板文件,并通过向模板引擎提供待插入模板的值,动态生成 HTML 页面:

from jinja2 import Template
  with open('example.jinja') as f: 1
    tmpl = Template(f.read())
  print(tmpl.render( 2
    list_title = 3 "Chapter Contents",
    list_description = 4 "Here are the contents of chapter 16.",
    item_list = 5 ["Mechanisms Of Template Injection", "Preventing Template Injection", "Hunting For Template Injection", \
"Escalating Template Injection", "Automating Template Injection", "Find Your First Template Injection!"]
))

First, the Python code reads the template file named example.jinja 1 . It then generates an HTML page dynamically by providing the template with the values it needs 2 . You can see that the code is rendering the template with the values Chapter Contents as the list_title 3 , and Here are the contents of chapter 16. as the list_description 4 , and a list of values— Mechanisms Of Template Injection , Preventing Template Injection , Hunting For Template Injection , Escalating Template Injection , Automating Template Injection , and Find Your First Template Injection! —as the item_list 5 .

首先,Python 代码读取名为 example.jinja1 的模板文件。然后,通过向模板提供所需的值,动态生成 HTML 页面。您可以看到,该代码将列表标题渲染为“章节目录”,将列表描述渲染为“以下是第 16 章的内容”,将值列表渲染为“模板注入机制、防止模板注入、寻找模板注入、升级模板注入、自动化模板注入和发现您的第一个模板注入!”。

The template engine will combine the data provided in the Python script and the template file example.jinja to create this HTML page:

模板引擎将组合 Python 脚本中提供的数据和模板文件 example.jinja,以创建此 HTML 页面:

<html>
  <body>
  <h1>Chapter Contents</h1>
  <h2>Here are the contents of chapter 16.</h2>
  Mechanisms Of Template Injection,
  Preventing Template Injection,
  Hunting For Template Injection,
  Escalating Template Injection,
  Automating Template Injection,
  Find Your First Template Injection!
  </body>
</html>

Template engines make rendering web pages more efficient, as developers can present different sets of data in a standardized way by reusing templates. This functionality is especially useful when developers need to generate pages of the same format with custom content, such as bulk emails, individual item pages on an online marketplace, and the profile pages of different users. Separating HTML code and application logic also makes it easier for developers to modify and maintain parts of the HTML code.

模板引擎使渲染网页更加高效,因为开发人员可以通过重用模板以标准化的方式呈现不同组数据。当开发人员需要生成具有自定义内容的相同格式的页面时,例如群发电子邮件,在线市场上的单个商品页面和不同用户的个人资料页面时,这种功能特别有用。将 HTML 代码与应用程序逻辑分离还使得开发人员更容易修改和维护 HTML 代码的部分。

Popular template engines on the market include Jinja, Django, and Mako (which work with Python), Smarty and Twig (which work with PHP), and Apache FreeMarker and Apache Velocity (which work with Java). We’ll talk more about how to identify these template engines in applications later in this chapter.

市场上流行的模板引擎包括 Jinja、Django 和 Mako(适用于 Python),Smarty 和 Twig(适用于 PHP),以及 Apache FreeMarker 和 Apache Velocity(适用于 Java)。我们稍后将在本章更多地谈论如何在应用程序中识别这些模板引擎。

Injecting Template Code

Template injection vulnerabilities happen when a user is able to inject input into templates without proper sanitization. Our previous example isn’t vulnerable to template injection vulnerabilities because it does not embed user input into templates. It simply passes a list of hardcoded values as the list_title , list_description , and item_list into the template. Even if the preceding Python snippet does pass user input into the template like this, the code would not be vulnerable to template injection because it is safely passing user input into the template as data:

“当用户能够注入未经适当消毒处理的输入到模板中时,就会发生模板注入漏洞。我们之前的例子并不容易受到模板注入漏洞的攻击,因为它并未嵌入用户输入到模板中。它只是将一组硬编码的值作为 list_title、list_description 和 item_list 传递到模板中。即使前面的 Python 代码将用户输入作为数据传递到模板中,该代码也不会受到模板注入的攻击,因为它将用户输入安全地传递到模板中作为数据。”

from jinja2 import Template
with open('example.jinja') as f:
    tmpl = Template(f.read())
print(tmpl.render(
   1 list_title = user_input.title,
   2 list_description = user_input.description,
   3 item_list = user_input.list,
))

As you can see, the code is clearly defining that the title portion of the user_input can be used only as the list_title 1 , the description portion of the user_input is the list_description 2 , and the list portion of the user_input can be used for the item_list of the template 3 .

可以看到,代码清楚地定义了用户输入的标题部分只能用作 list_title1,用户输入的描述部分是 list_description2,而用户输入的列表部分可以用于模板 3 的 item_list。

However, sometimes developers treat templates like strings in programming languages and directly concatenate user input into them. This is where things go wrong, as the template engine won’t be able to distinguish between user input and the developer’s template code.

然而,有时开发人员会像在编程语言中处理字符串一样处理模板,直接将用户输入连接到它们中。这就是问题发生的地方,因为模板引擎无法区分用户输入和开发人员的模板代码。

Here’s an example. The following program takes user input and inserts it into a Jinja template to display the user’s name on an HTML page:

以下是一个示例。下面的程序将用户输入插入到 Jinja 模板中,以在 HTML 页面上显示用户的姓名:

from jinja2 import Template
tmpl = Template("
<html><h1>The user's name is: " + user_input + "</h1></html>")1 print(tmpl.render())2

The code first creates a template by concatenating HTML code and user input together 1 , then renders the template 2 .

该代码首先通过将 HTML 代码和用户输入连接起来创建一个模板,然后渲染该模板。

If users submit a GET request to that page, the website will return an HTML page that displays their name:

如果用户向该页面提交 GET 请求,则网站将返回一个显示他们姓名的 HTML 页面:

GET /display_name?name=Vickie
Host: example.com

This request will cause the template engine to render the following page:

这个请求将会导致模板引擎渲染以下页面:

<html>
  <h1>The user's name is: Vickie</h1>
</html>

Now, what if you submitted a payload like the following instead?

如果你提交了以下的有效载荷呢?

GET /display_name?name={{1+1}}
Host: example.com

Instead of supplying a name as the name parameter, you are submitting an expression that has special meaning for the template engine. Jinja2 interprets anything within double curly brackets {{ }} as Python code. You will notice something odd in the resulting HTML page. Instead of displaying the string The user's name is: {{1+1}} , the page displays the string The user's name is: 2 :

使用表达式作为名称参数而不是提供名称。对于模板引擎,括号内的所有内容都会被视为 Python 代码。在生成的 HTML 页面中,您会注意到一些奇怪的地方。页面不会显示字符串“The user's name is: {{1+1}}”,而是显示字符串“The user's name is: 2”。

<html>
  <h1>The user's name is: 2</h1>
</html>

What just happened? When you submitted {{1+1}} as your name, the template engine mistook the content enclosed in {{ }} as a Python expression, so it executed 1+1 and returned the number 2 in that field.

刚刚发生了什么?当您将{{1+1}}提交为您的名称时,模板引擎将{{ }}中的内容误认为是 Python 表达式,因此执行了 1+1 并返回了数字 2 在该字段中。

This means you can submit any Python code you’d like and get its results returned in the HTML page. For instance, upper() is a method in Python that converts a string to uppercase. Try submitting the code snippet {{'Vickie'.upper()}} , like this:

这意味着您可以提交任何 Python 代码,并在 HTML 页面中获取其结果返回。例如,upper() 是 Python 中将字符串转换为大写的方法。尝试提交代码片段{{'Vickie'.upper()}},就像这样:

GET /display_name?name={{'Vickie'.upper()}}
Host: example.com

You should see an HTML page like this returned:

你应该看到返回的一个像这样的 HTML 页面:

<html>
  <h1>The user's name is: VICKIE</h1>
</html>

You may have noticed that template injections are similar to SQL injections. If the template engine can’t determine where a piece of user-supplied data ends and where the template logic starts, the template engine will mistake user input for template code. In those cases, attackers can submit arbitrary code and get the template engine to execute their input as source code!

你可能会注意到模板注入和 SQL 注入类似。如果模板引擎无法确定用户输入数据在哪里结束,模板逻辑从哪里开始,则模板引擎会将用户输入误认为模板代码。在这种情况下,攻击者可以提交任意代码,并让模板引擎将其输入作为源代码执行!

Depending on the permissions of the compromised application, attackers might be able to use the template injection vulnerability to read sensitive files or escalate their privileges on the system. We will talk more about escalating template injections later in this chapter.

根据被侵入应用的权限,攻击者可能能够利用模板注入漏洞读取敏感文件或提升系统中的权限。我们稍后在本章中将详细讨论如何提升模板注入。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文