6

「静的」クエリとは、常に同じクエリです。たとえば、Stackoverflow の「タグ」ボタンや、Digg の「7 日間」ボタンです。つまり、これらは常に特定のデータベース クエリにマップされるため、設計時に作成できます。

しかし、ユーザーが基本的に実行時にデータベースクエリを作成する方法を指示する「動的」クエリを実行する方法を理解しようとしています。たとえば、Stackoverflow では、タグを組み合わせて、好きな方法で投稿をフィルタリングできます。組み合わせることができるのはタグの世界であるため、これは非常に単純なクエリですが、動的なクエリです。より複雑な例は、タグとユーザーを組み合わせることができる場合です。

まず第一に、動的クエリがある場合、クエリ要素はユーザーがクエリに含めることを決定したものに依存するため、SQL インジェクションを回避するために置換 API を使用できなくなったようです。文字列の追加を使用する以外に、このクエリを作成する方法がわかりません。

次に、クエリが複数のテーブルにまたがる可能性があります。たとえば、SO でユーザーがユーザーとタグに基づいてフィルター処理できるようにし、これらがおそらく 2 つの異なるテーブルにある場合、クエリの作成は、列と WHERE 句を追加するよりも少し複雑になります。

このようなものを実装するにはどうすればよいですか?

4

4 に答える 4

2

最初の規則は、ユーザーがSQL 式で値を指定することは許可されていますが、SQL構文では許可されていないということです。すべてのクエリ構文は、ユーザー入力ではなく、コードで文字通り指定する必要があります。ユーザーが指定する値は、クエリ パラメータとして SQL に提供できます。これは、SQL インジェクションのリスクを制限する最も効果的な方法です。

多くのアプリケーションは、コードを使用して SQL クエリを「構築」する必要があります。これは、指摘したように、一部の式、テーブル結合、基準による順序などはユーザーの選択に依存するためです。SQL クエリを 1 つずつ作成する場合、結果が有効な SQL 構文であることを確認するのが難しい場合があります。

Zend_Db_Select私は、これを支援する API を提供するという PHP クラスに取り組みました。PHP が好きなら、そのコードを見てアイデアを得ることができます。想像できるクエリは処理しませんが、多くのことを行います。

他のいくつかの PHP データベース フレームワークには、同様のソリューションがあります。

于 2008-11-10T18:07:26.673 に答える
1

一般的な解決策ではありませんが、動的でありながら安全なクエリの問題を軽減するために実行できるいくつかの手順を次に示します。

カーディナリティが任意の値のセットに列値が属する基準は、動的である必要はありません。instr 関数を使用するか、結合する特別なフィルター テーブルを使用することを検討してください。このアプローチは、列の数がわかっている限り、複数の列に簡単に拡張できます。ユーザーとタグのフィルタリングは、このアプローチで簡単に処理できます。

フィルタリング基準の列数が任意でまだ少ない場合は、可能性ごとに異なる静的クエリを使用することを検討してください。

フィルター条件の列数が任意であり、潜在的に大きい場合にのみ、動的クエリの使用を検討する必要があります。その場合...

SQL インジェクションから保護するには、その攻撃を防御するライブラリを構築または取得します。より困難ではありますが、これは不可能な作業ではありません。これは主に、フィルタリングする値の SQL 文字列区切り文字をエスケープすることに関するものです。

コストのかかるクエリから保​​護するには、この目的のために特別に作成されたビューと、これらのビューの呼び出し方法を制限する事前ロジックを使用することを検討してください。これは、開発者の時間と労力の点で最も困難です。

于 2008-11-10T18:27:16.010 に答える
0

オプションは何かにマップする必要があります。

CONCATオプションにパラメーターを引き続き使用する場合、SQL クエリ文字列は問題になりません。

于 2008-11-10T18:01:17.420 に答える
0

Python を使用してデータベースにアクセスしていた場合は、Django モデル システムを使用することをお勧めします。Python と他の言語 (特に ruby​​ on rails) の両方に同様の API が多数あります。SQL を使用してデータベースと直接やり取りする必要がなくなるため、時間を大幅に節約できます。

例のリンクから:

#Model definition
class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __unicode__(self):
        return self.name

モデルの使用法 (これは実質的に挿入ステートメントです)

from mysite.blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()

クエリはさらに複雑になります。クエリ オブジェクトを渡し、フィルターや並べ替え要素を追加できます。最終的にクエリを使用する準備が整うと、Django は、クエリ オブジェクトを調整したすべての方法を反映する SQL ステートメントを作成します。とても可愛いと思います。

この抽象化のその他の利点

  • モデルは、Django による外部キーと制約を持つデータベース テーブルとして作成できます。
  • 多くのデータベースがサポートされています (Postgresql、Mysql、sql lite など)
  • DJango はテンプレートを分析し、テンプレートから自動管理サイトを作成します。
于 2008-11-10T20:11:03.007 に答える