私は、ユーザーがサーバーに変数を代入する文字列を提供できるWebアプリケーションに取り組んでいます。Pythonの文字列.format()は、信頼できない書式文字列に対して安全にすることはできますか?
私はPEP 3101 format()構文を使いたいと思います。私は信頼できない入力に対して安全にするためにFormatterのメソッドをオーバーライドする可能性について検討しています。ここで
は、そのまま私は(.formatで見ることができるリスク)がある:。フォーマット(..)を実行できます。
- パディングはとても '{> 9999999999は}'、あなたは任意の長さを指定することができますサーバがメモリ不足になり、DOSになる可能性があります。私はこれを無効にする必要があります。
- フォーマットはオブジェクト内のフィールドにアクセスすることができますが、これは便利ですが、dunder変数にアクセスして標準ライブラリのビットを掘り下げるのは気の利いたことです。副作用があるgetattr()があるかもしれないとか、何か秘密を返すかもしれません。 get_field()をオーバーライドして、属性/インデックスアクセスをホワイトリスト化します。
- 自然に例外をいくつかキャッチする必要があります。
私の仮定は以下のとおりです。パラメータを指定すると、直接スレッドのスタックからポップするのではなく、コレクションに境界-確認のアクセスであるため、従来のC形式の文字列の悪用の
- なし、Pythonのには適用されません。
- 私が使用しているWebフレームワークは、ページテンプレートに代入されるすべての変数をエスケープします。出力前の最後の停止であれば、脱エスケープからのクロスサイトスクリプティング攻撃から安全です。
あなたの考えは?可能?不可能?ただ賢明ではない?
編集:アーミンRonacherはあなたがdunder変数へのアクセスをフィルタリングしていない場合は厄介な情報が漏洩し概説するが、(形式を確保考えているようだ)として実現可能:
{local_foo.__init__.__globals__[secret_global]}
http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/
(個人的には、私の製品で実際には信頼できないフォーマット()のルートには行きませんでしたが、完全性のために更新しています)
賢明に聞こえません。あなたは 'replace()'を使うことはできませんか? – grc
まあ、最初にreplace()は文字列に含まれる可能性のある各変数を渡す必要がありますが、ひどく規模が大きくなります。 –
Lemmieはそれを編集する私のチャンスを逃したので、見ることにそれを広げる。私のユースケースは、多大な潜在的な変数を持つ大量の文字列フォーマットを行うつもりであるMUDのような状況です。 'string.Template'のような弱い形式の文字列に戻すこともできますが、オブジェクトの中のフィールドを参照できるということは私の場合でも非常に便利です。それは、すべての呼び出しのすべての引数からすべてのフィールドのパラメータマップを作成することでエミュレートできるものですが、スケールが改善されていることを確認することができます。 –