Javaのインタビューのレビューサマリー(MySQLの記事10) - SQLインジェクションについて話をするJavaパースペクティブ

序文

レンジ準備

まず、私たちは情報の問合せマネージャを提供することができ、Webインターフェイスのサービスを、準備し、ここでは、データベースが最も一般的に使用されるのmysqlで、ビルドWebサービスフレームワークにspringboot +ジャージを使用します。以下は、次のように我々はSQL、最初のユーザーテーブルjwtk_adminを作成し、テスト環境を準備します。

次に、デフォルトの管理者を挿入します。

我々は持っているので、2つの内蔵のシステム管理者、MD5を使用して管理者パスワードは、もちろん、これはそう何の非常に広い分野があり、テーブルの調査の範囲についての非常に単純ではありません、ハッシュを搭載しました。

次に、我々は次のように、管理者のユーザー名の固有の情報を経由して管理者を照会するためのインタフェースを提供春ブーツ+ジャージRESTfulなWebサービスの構築を、作成します。

SQLインジェクションのテスト

まず、我々は前方管理者に送信するには、Webサービスのクエリ要求を開発するために考えている、ここでは郵便配達ツールでGETリクエストを送信します

私たちは期待して開発することができませんでした、Webインターフェースは、私たちが望む結果、管理者管理者情報のユーザ名を返します。OK、今完了した開発作業は、Gitのプッシュは、タスクのJIRAのポイントは、このインターフェイスは本当に問題ありません、テストするには?今、私たちは、このようなGETリクエストを送信します。

バックエンドのWebサービスは次のエラーの例外MySQLSyntaxErrorExceptionを投げるようになった一方で、要求を送信した後、我々は、郵便配達が戻って受信されませんが見つかりました:

あなたのSQL構文でエラーが発生しています。マニュアルをチェックし、その行1の「」XXXX「」」の近くに使用する権利構文についてはMySQLサーバのバージョンに対応

その理由は、SQL文の構文で私達の照会XXXX」で、正しいにはつながらないということです。ここでは、我々は、実験再びクエリにGETリクエストを構築していき、SQL構文を議論していません。

この時点で、我々はだけでなく、クエリインターフェイス与えられていない、見つけて驚いたが、私たちのデータベース管理者のjwti_adminテーブル内のすべての情報は外にクエリですしました。

地獄、また、テーブル名= xxxx'or'a「=」ユーザーの管理者は何ですか?これは、SQLインジェクションです。

インジェクション原則分析

私たちは、インタフェースのString nameパラメータを受信し、クエリ文字列連結方法によって構築されます。通常の状況下では、利用者が正当な名前のクエリを渡しますが、文字列の連結は、まだ有効なSQLクエリの後に、それはハッカーがパラメータ限り、引数が渡さ細工します、その後、SQLインジェクションが発生します。名前= xxxx'or'a私たちの上記入力「=」スプライシング、クエリインターフェイスの設定次のSQL文のように:

インタフェースの実行文のSQLは、それが離れてハッカーにバックグラウンドシステムと同等である場合には、ハッカーが直接あなたのバックオフィスシステムをログに記録する123456パスワードで、取りませんCMD5がチェック管理者パスワードのハッシュを見ました。なぜ?MD5ハッシュ123456あまりにも一般的なので、笑っていない、これが横行し、多くの小さなサイト、弱いパスワードの現実である、あなたが泣きますよ!

さて、今、私たちは理解しておく必要があり、SQLインジェクションの理由は、システムに渡される引数が発生し、正当なSQL SQLスプライシングとなっているされているので、その本質はコード実行など、ユーザーが入力したデータです。長い点が発見されたハッカーのSQLインジェクションがあるとしてシステムでは、その後、SQL文を実行することができますハッカーは基本的に「パンツオフ」など、さえクエリすべてのテーブルとを、管理者を追加するなど、任意のを実行したいので、当然のことながら、この記事では、SQLを説明することではありません注入技術の記事は、ここで我々は唯一のSQLインジェクションが発生した原因や予防法を検討します。

JDBC前処理

より基本的なデータベース操作が直接、古いシステムでJDBC DAOを構築JDBCの方法を用いて、上記のインタフェース、DAOではまだ非常に一般的ですが、それは場合、我々は、JDBCを使用して安全ではないだろうという意味ではありません私はそれがSQLインジェクションを生成しません、パラメータ名クエリとしてパラメータを渡すxxxx'or'a「=」全体ます。JDBCには、(実行文を前処理)PreparedStatementを提供し、次のように、それは前のコードを使用してクエリのSQLステートメントをパラメータ化することができます。

同様に、我々は上記を注入する注入法を使用して、我々はこの時点で、SQLインジェクションが失敗したことがわかります。さて、SQLでの外観は、前処理された後に印刷させて、何が起こるかを参照してください。

参照してください?すべてをあなたは、それによってSQLインジェクションを防ぐ、SQLクエリパラメータは、パラメータが悪意のある実行されませんであることを確認することができるようにアウトエスケープ「しています」。

MyBatisのガード下で注入しました

MyBatisのは、JDBCコードとマニュアル設定パラメータのほとんどすべて回避し、結果セットを取得するカスタムSQL、ストアドプロシージャと高度なマッピングをサポートするための優れた永続化フレームワークです。一方、MyBatisのは、そのためになりました市場金利が非常にある使用してMyBatisの、データベースのレコードに簡単なXMLまたは注釈、インタフェースとJavaのPOJO(プレーン古いJavaは普通のJavaオブジェクト、オブジェクト)を使用している設定およびネイティブ地図できます高いです。ここでは、管理者のユーザー名のクエリインターフェイスによって実装、マッパーとして定義します。

また、Webアクセス・インターフェースを提供します。

次に、我々はSQLインジェクション名フィールドを試してみました、あなたは注入が成功しなかった見つけることができます、あなたはMyBatisののログパラメータは注入を防止するために前処理されている印刷することにより、MyBatisのフレームを見ることができます:

あなただけのSQLインジェクションのリスクを回避しなければならないMyBatisのそれを使用していますか?私たちは、マッパー以下の修正を行い、パラメータは#{名前} $ {name}の変更、および名前=「XXXX」または使用している「を」=パラメータとして「」GETリクエストは、SQLインジェクションが起こった見つけることができます:

まあ、これはなぜ、どこ差MyBatisのは、$ {}と{#}ですか?

宣言は、もともとMyBatisののSQLパラメータとして渡された場合は、パラメータはMyBatisの前処理が直接、動的SQLステートメントをスプライスされることはありません、その後、注入される危険性があり、それはMyBatisのよう回避フレームの永続性に使用する必要があります養子縁組

パラメータを渡されたSQL文の形式では、パラメータはMyBatisの前処理は、直接、動的SQLステートメントをスプライスされることはありません、その後、注入される危険性があり、それが渡されたSQL文の持続的な形として避けフレームMyBatisのために使用する必要がありますパラメータ。

前処理パラメータは、その後注入されるおそれがある、直接スプライシングさ動的SQLステートメントではありませんMyBatisの避けられない場合には(フレーム形式{}パラメータ渡しを使用して永続的なMyBatisのを避けるように使用されるべきですそのような他のプログラマによって順序が依然として方法マス参加$ {}を選択してもよい、で、等のようないくつかのSQL)は、フィルタ自体をエスケープするためにパラメータを渡す必要があります。

JPAの予防注射

SunのJPAは、ORM技術を統合するために使用され、世界はORMれるJava Persistence API(Javaの永続化API)の標準的な定義を正規化し、JPAは、インターフェースのセットだけで、現在のプロジェクトは、とJPAの導入は、その具体的な実現として、休止状態を使用していますでしょうノー人気の春ブート構成フレームワークでは、好ましい技術としてJPAますます永続それはプログラマが既存の機能を完了するために以下のコードを書くことができますので。

例えば、強いJpaRepository、通常のSQLクエリは、単に命名規則に定義されたインタフェースに従ってください、あなたが書くことはできませんSQL(JPQL / SQL)クエリがビューのSQLインジェクションの防止の観点から運用データを達成することができ、これはセキュリティの責任をスローしますフレームに自分の保険プログラマ制御に依存するよりも。そのため、データアクセス層としてJPAを使用してプロジェクト場合は、基本的には大部分がSQLインジェクションのリスクを排除することができます。

しかし、言葉は古いプログラマはまだ文字列連結方法を使用してクエリインターフェイスを構築するためにJPQLの使用に慣れていないが存在する永続化フレームワークとしてJPAを使用するが、しかし、私が今まで見てきた春のブートプロジェクトでは、あまりにも死んだと言うことはできませんビジネスを実現し、セキュリティ上の潜在的な問題を投影します。

細心のセキュリティニーズ、セキュリティ100 - サービス1 = 0、攻撃へのあなたの防衛の場合でも99%が、それはまた、それは非常に深刻な結果をもたらす可能性を秘めている、侵略された限りそこに一度、勝つされていません。

(例えばCVE-2016から6652など)に属し、脆弱性の枠組みの範囲の枠組みの中でインジェクションの脆弱性、プログラマは単にJPA仕様の開発に続く、心配注入問題への必要は両方のフレームワークのために、存在しないため、SQLインジェクションJPAについては、我々は、詳細に説明していませんあなたは、舞台裏で仕事をします。

SQLインジェクションを防ぐために、他の方法

多くの企業がそこに古いシステムは、SQLインジェクションの多数の問題のリスクコードを持っているが、それは長い時間のために、同社の事業の安定した支持を持っているので、SQLインジェクションを防ぐために彼の方法の使用を考慮する必要があるので、注入の問題を解消する方法大面積のコード更新を使用すべきではありません。しばしばアーキテクチャによって、またはSQLインジェクションを防止するフィルタリング効果を達成するための他の方法を介して、SQL実装でSQLインジェクションを防止することに加えて。

すべての入力が安全ではない:そのようなインタフェースの管理クエリなどのフォーマットに合わせて、インターフェースのための呼び出しパラメータ、名前で(ユーザー名に特殊文字があってはならないので)、パスのマッチングはそう、定期的に試合を使用する必要があります確か着信パラメータは、プロセス制御の範囲内のパラメータは、よく悪い入力を拒否することが知られている唯一の入力値を受け入れる、すなわち、であること。注:このパラメータの検証には、符号化技術の出力と組み合わせて使用​​する必要があります。

既存のプロジェクト、変更することは困難で、既存のコードインジェクションの前に、Webサービスを増やすことを検討している場合、パブリックネットワーク環境へのDAOアクセス層界面への露出を最小限にするために、フロント静的可能:階層設計を使用することの危険性を回避するために、もちろん、コードがハッカーの悪用に残されていないWAFフィルタトラフィックが最善の解決策でした。フレームワークでは、トラフィックのフィルタリングをOpenRestryを使用しない、nginxのを持つことができ、いくつかの特殊文字をエスケープ。

プリコンパイルされたSQL文を使用してみてください:動的SQL文のソースは、SQLインジェクションの原因となったよう。利用アセンブリへのプリコンパイルされたSQLクエリステートメント。

スケーリング所定のコーデックと出力フィルタパラメータの入力を搭載した後、符号化処理を入力し、すべての非標準符号化フォーマットを拒否する。

概要

ASP.NET MVCフレームワークとEntity Frameworkのは、寒さの範囲は、常に高くなっているサポートされていながら、実際には、ORM技術の発展に伴い、トレンド上のJava Web開発は、ますます離れSQLインジェクションの問題からです。現在のインターネットでは、ビルドのSQLインジェクションにPHPやPythonのWebアプリケーションは、現在、最も深刻な打撃を受けています。この記事は、研究の質問JAVA SQLインジェクションの観点からではなく、原則上の他の開発言語にも同様に適用可能であるが、私は類推により、テキストを介してリーダを願っています。

チェリッシュデータは、離れステッチ、政界を入力する場所があるでしょう...

发布了142 篇原创文章 · 获赞 31 · 访问量 2万+

おすすめ

転載: blog.csdn.net/qq_38905818/article/details/103698300