2

.extra() パラメータを使用して生の SQL クエリを実行する manager.py ファイルがあります。例えば:

class MyManager(models.Manager):

    def order_null_last(self, field):
        return super(DecisionManager, self).get_query_set()\
            .extra(select={'has_field': "CASE WHEN " + field + " IS NULL THEN 1 ELSE 0 END"}).order_by('has_field', field)

この種のクエリは、インジェクションによる攻撃に対して脆弱である可能性があることが示唆されています。

変数 'field' は、正当な値のグループに属していることを確認するために解析されますが、このチェックはビューで行われます。例えば:

class ModelList(ListView):
    model = MyModel

    def get(self, request, *args, **kwargs):
        self.set_sorting(request)

    def set_sorting(self, request):
        self.sort_field = request.GET.get('sort', '-id')
        if not self.sort_field in self.sort_options:
            self.sort_field = 'id'

そのため、誰かが上記のマネージャーを使用して新しいビューを作成したが、パラメーターをフィルタリングするのを忘れた場合、エクスプロイトが可能になります。

では、循環インポートを取得せずにマネージャーのモデル フィールドに対してパラメーターを検証する方法はありますか? つまり、マネージャは許可されたフィールドのリストを取得するためにモデルをインポートする必要がありますが、モデルはマネージャをインポートする必要があります。

4

2 に答える 2

1

追加でselect_paramsを使用すると、SQLインジェクションが回避されます。

class MyManager(models.Manager):

def order_null_last(self, field):
    return super(DecisionManager, self).get_query_set()\
        .extra(select={'has_field': "CASE WHEN %s IS NULL THEN 1 ELSE 0 END"}, select_params=(field,)).order_by('has_field', field)
于 2012-11-13T18:24:12.917 に答える
0

モデル マネージャーはモデルにアクセスできるため、self.model を介してフィールドにアクセスできます。

だから私はこれを書くことができます:

クラス MyManager(models.Manager):

def order_null_last(self, field):
    if field in [modelfield.name for modelfield in self.model._meta.fields]:
        return super(DecisionManager, self).get_query_set()\
            .extra(select={'has_field': "CASE WHEN " + field + " IS NULL THEN 1 ELSE 0 END"}).order_by('has_field', field)
    else:
        return super(DecisionManager, self).get_query_set()
于 2012-12-07T11:44:33.950 に答える