2

私が取り組んでいるプロジェクトで、さらに別のばかげたサニタイズされていないSQLインジェクションの欠陥に(偶然に)偶然出くわしました...そして私はそれにとてもうんざりしています。
このような悪いSQLステートメントを排除し、可能な限り準備済みステートメントを強制する方法について何かアドバイスはありますか? 今、私は次のような解決策を好むでしょう

REVOKE DarnInlineDataStatements ON * TO xyz
しかし、これはありそうもないので、これらのものを見つけるための静的コード分析ツールなどはありますか (一定の信頼性まで)? または他に何かお勧めはありますか?
編集:ソフトスキルのアプローチ「それらを使用しないでください。(通常)より良い方法があります」は、過去にはあまりうまく機能していないようでした. したがって、そもそもそのようなクエリを防止するものを本当に好むでしょう。既存のコードを故意に壊すのではなく、将来のプロジェクトのために、「そのようなクエリはありません」という解決策があります;-)

4

5 に答える 5

3

SQL をストアド プロシージャに移動すると、アプリケーション ユーザーの SELECT、CREATE、ALTER、UPDATE、DELETE、DROP などのアクセス許可を無効にして、EXEC アクセスのみを残すことができます。これは SQL Server を想定していますが、Oracle/MySQL などでも同様の設定が可能であると確信しています。

また、これは準備されたステートメントを保証するものではないことに注意してください: 安全でない方法でストアド プロシージャを呼び出すことはできます。しかし、多くのストアド プロシージャを使用していない場合は、正しくコーディングされていない場所を見つけることができます。また、何か見落としがあると、SQL インジェクション攻撃の成功が非常に困難になります。

于 2009-02-28T01:37:12.987 に答える
2

SELECT、INSERT、UPDATE、DELETE などの一般的な T-SQL コンストラクトをコード ベースで検索するだけで済みます。

Visual Studio 2008 Team System を使用している場合、SQL の問題をチェックする組み込みのコード分析ルールがあります。それ以外の場合は、無料のFxCopがあります。

于 2009-02-28T01:20:56.380 に答える
1

すでに静的コード分析ツールを使用している場合は、特定のメソッドの使用を探すように構成できConnection.createStatementますConnection.prepareStatement

より良いアプローチは、連結を使用して動的 SQL を作成することの悪影響についてチームを教育することだと思います。コーディング標準ドキュメントに追加する必要があります!

于 2009-02-28T01:22:22.007 に答える
0

ソフトウェア内のパラメータ化されていないすべてのクエリを簡単に見つけることができれば幸いです。PHP の PDO や Perl の DBI などのほとんどのデータベース アクセス レイヤーでは、クエリを準備するときと SQL を実行するときの呼び出しが異なります。これらの呼び出しが何であるかを把握し、コードを検索することから始めるとよいでしょう。Linux を使用している場合は、grep が役に立ちます。

そこから、それらを修正するのは簡単です(私は願っています)。プロジェクトの規模はわかりませんが、クエリを共通の場所に配置するか、Active Record / DataMapper / Table Row Gateway のような共通のパターンに基づいてレイヤーを開発することをお勧めします。

自動的に強制する良い方法はないと思います。おそらく、同僚と心を合わせる必要があるだけです。インライン SQL はよくありません。話の終わり。あなたがリーダーなら、任務は適切だと思います。

于 2009-02-28T01:30:30.133 に答える
0

アプリケーションからコードを直接データベース サーバーに送信するのではなく、中間層を介して送信します。DBに送信されるものを簡単に解析し、それにいくつかの制約を適用できます。たとえば、すべての SQL コードを強制的に 1 つのステートメントで構成しそれを拒否するか、複数ある場合は最初のステートメントのみを実行します。

基本的な SQL インジェクション攻撃には、次のようなコードが含まれます。

DECLARE @SQL VARCHAR(4000), @Table VARCHAR(50) 
SET @Table='Employees' -- Imagine this actually comes as a parameter from app
SET @SQL='SELECT * FROM '+@Table
EXEC(@SQL)

攻撃者は、文字列「systables';UPDATE BankAccount SET Money=Money+10000 WHERE AccountCode=12345;DROP TABLE AuditTrails;」を渡す可能性があります。DB に - それは悲惨な結果をもたらすでしょう。

中間層が文字列に対してこの最小限の解析を行うことで、最も単純な SQL インジェクション攻撃から保護されます。他の場合は、それらを中間層に追加できます (また、結果のキャッシュ、帯域幅のスロットリングなども処理できます)。

アプリから複数の SQL ステートメントを渡す必要がある場合は、あなたのやり方が間違っていると思います。そのロジックをストアド プロシージャにカプセル化するか、少なくとも中間層自体にカプセル化する必要があります。

于 2009-02-28T05:40:47.083 に答える