Jinja: urlencodeはスラッシュをエスケープしません

作成日 2015年11月20日  ·  21コメント  ·  ソース: pallets/jinja

これは#444で発生しましたが、このコードはPython 3.4.1では常にb'/'評価されるため、スラッシュはエスケープされません。

最も参考になるコメント

API呼び出しを介してgitlabリポジトリにファイルを作成しようとすると、この問題が発生します。 gitlab apiでは、スラッシュをエンコードする必要があります。 この作業を行うには、次のようにします。{{myvar | urlencode | regex_replace( '/'、 '%2F')}}。 プレイブックのタスクでAnsibleフィルターとJinja2フィルターを使用しています。 これが機能することを確認したので、これをヒットした人にとっては回避策になる可能性があります。

全てのコメント21件

ただ頭を上げる@mitsuhiko
理由はわかりませんが、 do_urlencodeはスラッシュをエスケープしませんが、 unicode_urlencodeは期待どおりに機能します。

Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import jinja2
>>> jinja2.utils.unicode_urlencode("http://url.by", for_qs=True)
'http%3A%2F%2Furl.by'
>>> jinja2.filters.do_urlencode("http://url.by")
'http%3A//url.by'
>>> jinja2.__version__
'2.9.dev'

urlencodeフィルターはスラッシュをエスケープしないためです。 それがしなければならない特定の理由はありますか? これを明確にするために:渡されたキー/値ペアの値の位置でスラッシュのみをエンコードします。

これは、URLのエンコードを目的とした関数の標準的な動作だと思います。 http://meyerweb.com/eric/tools/dencoder/のようなツールはこのように動作します。 また、社内に少なくとも1つのツールがあり、スラッシュがエスケープされたGETリクエスト内でURLが渡されることを想定しています。
また、 unicode_urlencodedo_urlencodefor_qs=True呼び出された理由もわかりません。
何かおかしいことがわかったのかもしれません。

スラッシュはパスコンポーネント内の予約文字であり、より一般的な動作はすべてをエンコードすることですが、エンコードされた動作をURLに強制する場合はスラッシュ以外のすべてをエンコードします。 バックエンドサーバーは通常%2f/を区別できないため、セキュリティの問題のためにほとんどのサーバーがこれらの要求を完全に拒否するため、代替手段(スラッシュを%2fにエンコードする)は意味がありません。デコードされたオクテットを操作するときのパスコンポーネント。

したがって、スラッシュが実際にエンコードに意味をなす唯一の部分はクエリ文字列であり、これはurlencodeが持つdictベースのエンコーダがそのように機能する場所です。 ただし、スラッシュをエンコードする必要がない場合でも、強制的にエンコードする必要はありません。

urlencode関数は、デフォルトでほとんどの人に使用されるはずです。そのため、スラッシュはエンコードされません。 カスタム要件がある場合は、フィルター登録の機能をオーバーライドできます。

Ok。 アーミンありがとう。

こんにちは、私はスラッシュを拒否することで同じ問題を抱えています、ここにコードがあります:

jinja2.Template( "{{disks | require( 'sameas'、 '/')| list}}")。render(disks = ["/"、 "/ mnt / disk0"、 "/ mnt / disk1"])
u "['/'、 '/ mnt / disk0'、 '/ mnt / disk1']"

ルートディスクを拒否したいのですが、機能しなくなりました。どうすれば解決できますか?

>>> import jinja2
>>> jinja2.Template("{{ disks|reject('sameas', '/')|list }}").render(disks=["/", "/mnt/disk0", "/mnt/disk1"])
u"['/mnt/disk0', '/mnt/disk1']"
>>> jinja2.__version__
Out[3]: '2.8'

私のために働きます。

それでも私には機能しません、 @ ThiefMaster 、Pythonの問題はありますか? 使用したPythonのバージョンは何ですか。

    Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import jinja2
    >>> jinja2.Template("{{ disks|reject('sameas', '/')|list }}").render(disks=["/", "/mnt/disk0", "/mnt/disk1"])
    u"['/', '/mnt/disk0', '/mnt/disk1']"
    >>> jinja2.__version__
    '2.8'

ああ.. sameasisを使用します(そして'foo' is 'foo'が機能することは期待できません)。 equaltoを使用する==です。

はい、動作します。私はJinja2の家族ではありません。 ありがとう、 @ ThiefMaster

したがって、スラッシュが実際にエンコードに意味をなす唯一の部分はクエリ文字列であり、これはurlencodeが持つdictベースのエンコーダーがそのように機能する場所です。 ただし、スラッシュをエンコードする必要がない場合でも、強制的にエンコードする必要はありません。

いいえ、たとえば、ユーザー名とパスワードにも/をエンコードする必要があります。
これは、JSが持っている理由ですencodeURI __and__ encodeURIComponentで処理します

それは十分に公平ですが、実際にはそこにも必要ではなく、含まれているクレデンシャルはとにかく非推奨になっています。 それらがテンプレート内で生成される可能性は低いため、検討する価値のないエッジケースです。

AnsibleはJinjaを使用しており、システムをセットアップするときにセキュリティクレデンシャルを処理することはかなり一般的です。 自動生成されたパスワードに、データベースURLを生成するためにurlencodeに置き換えられなかったスラッシュが含まれている場合がありますが、これは非常に残念です。 現在の動作を壊すのは問題がありますが、スラッシュをエスケープする2番目のフィルターを導入してみませんか?

Ansibleはそれを行うことができます。 Jinja自体にそのような変更を加える必要はありません。カスタムフィルターを追加したり、組み込みフィルターを置き換えたりするのに十分な拡張性があります。

@ThiefMaster Jinja自体に含めるのに役立つものを決定するときに、HTMLテンプレートの作成以外のユースケースは関係ありませんか? たとえば、Ansibleと同様の目的を持つSaltstackプロジェクトも、テンプレート作成にJinjaを使用しており、同じ変更の恩恵を受けます。

@danielkza saltstackがそれを行うフィルターを提供するのを

@mitsuhikoなぜJinjaに組み込みのフィルターが含まれているのですか? 複数のユースケースで役立つからだと思います。 URLのスラッシュをエスケープできることが望まれる2つの例として、AnsibleとSaltを使用しました。したがって、すべての人が利用できるようにしておくことは価値があります。

Pythonのurllib.url_quoteように、 safe引数をurlencodeに追加して、デフォルトでスラッシュが保持されるようにするにはどうでしょうか。ただし、簡単にオーバーライドできます。

Jinjaは、一般的に使用されるいくつかの機能を提供しようとします。 urlencodingには2つのモードがあり、約95%がそこにあります。 dictをエンコードすることでクエリ文字列全体をエンコードでき、文字列のurlencodeを介したパスに有効な共通セットにエンコードできます。

utf-8またはそれ以外は何もしません。 どこで止まるので。 URLの部分が多すぎて、アイリスがあり、それらはすべて独自のねじれを持っています。 私たちがそこにいるとき、なぜnetlocにpunycodeエンコーダーも提供しないのですか?

API呼び出しを介してgitlabリポジトリにファイルを作成しようとすると、この問題が発生します。 gitlab apiでは、スラッシュをエンコードする必要があります。 この作業を行うには、次のようにします。{{myvar | urlencode | regex_replace( '/'、 '%2F')}}。 プレイブックのタスクでAnsibleフィルターとJinja2フィルターを使用しています。 これが機能することを確認したので、これをヒットした人にとっては回避策になる可能性があります。

どの文字をパーセントエンコードする必要があるかについていくつかの議論がありますが、私の理解では、これは現在RFC3986でカバーされています。 https://tools.ietf.org/html/rfc3986#section -2.2

私のユースケースではありますが、 回避策を提供しています。

また出てきたので閉じたいです。 これを持っていることに反対する私の議論はすでにここにありましたが、GitLabのAPIを支援するために別のフィルターを追加することを提案するPRが現在開いている(#864)ので、繰り返したいと思います。

GitLabのAPIは、あらゆる種類のプロキシセットアップの背後に配置されていると壊れており、問題が発生しています(問題の)。 代わりに、回避策と、なぜ人々がそれをすべきでないのかを文書化することを提案します。

回避策の例は次のとおりです。

{{ value|urlencode|replace("/", "%2f") }}

これは少しスタンスを取っていますが、これを行うことで、人々が自分の前に来た他の人の過ちを繰り返さないように促すことができます。

このページは役に立ちましたか?
0 / 5 - 0 評価