将输入模板化为yaml文件 - 我需要进行哪些清理?

时间:2017-02-09 00:10:04

标签: yaml sanitization

我有一个yaml文件,我通过模板语言生成(在本例中为jinja2。)这是一个简单的片段:

services_to_install:
  {% for service in services if service.install -%}
  - {{ service.name }}
  {% endfor -%}
user_data: |
  #! /bin/bash
  set -o errexit
  /usr/local/bin/ansible-playbook -i 127.0.0.1, -c local /tmp/ansible/playbook.yml --extra-vars 'app={{ app }}'

我知道,例如,如果我让service.name包含换行符,它可能会逃脱它应该包含的列表,并且可以编写任意yaml语法。所以我限制换行。

然而,我并不知道"代码注入"所有其他可能的滥用行为。 (即编写任意yaml语法)可能存在。抛开可能在运行时创建对象的语言特定标签,我还需要注意哪些其他事项?

换句话说,如何清理模板化yaml文件的输入,就像清理模板化html文件的输入一样?

P.S。我没有和一个模板引擎结婚,我对yaml语法更感兴趣。

编辑在我的示例中添加了一个块元素,因为我也使用了这些元素。

1 个答案:

答案 0 :(得分:2)

最安全的做法是编写一个过滤字符串并将其放在双引号中的过滤器。 Here是YAML双引号标量样式中转义序列的完整列表。

话虽如此,如果你想把它写成普通的(即没有引用的)标量,让我们看一下被禁止的内容:

可能无法启动普通标量的字符

某些字符可能无法启动普通标量,因此不得在开头出现。这些被称为indicator characters,包括:

  • 流式指标(,[]{}
  • 引号开头引用的标量('"
  • 用于启动标记,锚点或别名的字符(!&*
  • 评论指标(#
  • 指令指标(%
  • 保留字符(@`
  • 块式指标(|>?:-)。但是,?:-如果没有空格,则允许

结束普通标量的字符

启动普通标量后,大多数字符都被允许。但是,某些字符将标记普通标量的结尾:

  • 流式指标(,[]{}),但仅限于流式
  • 映射键指示符(:如果后跟空格
  • 评论指标(#如果前面有空格
  • 如果下一个非空行缩进小于当前缩进,则换行符

请注意,尽管可以在标量中包含换行符(如果缩进处理正确),但这些换行符合line folding,因此,在使用此值之前,您需要将转换应用于原始值如果您希望将其解析为相同的值,请使用样式。

完全禁止的字符组合

在文档中,字符序列---...可能永远不会出现在行的开头(它们在其他地方都很好)因为它们表示结束当前的文件,也可能是新文件的开头。

结论

普通标量没有转义机制,因此它们可以代表什么字符串受到限制。双引号标量是唯一能够表示所有可能字符串的表示形式,因此也是您想要的结果。

选择是将字符串表示为普通字符串还是引用标量通常是YAML实现的任务,因为决策制定很复杂且有许多警告。如果使用模板引擎生成YAML,则可能无法访问所有信息来做出决定 - 例如,当前缩进,状态(流式和块式)等。因此,为了安全起见,请使用过滤器转义特殊字符并使用双引号样式。