あまりにも多くの企業にとって、それは 後 セキュリティ違反が発生しました Webセキュリティのベストプラクティスが優先事項になります。 ITセキュリティの専門家として働いていた数年間、Web開発のセキュリティ問題の世界が私の多くの人にとってどれほど曖昧になるかを何度も目にしました。 仲間のプログラマー 。
Webセキュリティの脅威に対する効果的なアプローチは、定義上、予防的かつ防御的でなければなりません。その目的に向けて、この投稿はセキュリティの考え方を刺激することを目的としており、読者に健康的な量のパラノイアを注入することを願っています。
特に、このガイドでは、Webセキュリティの10の一般的で重要な落とし穴に焦点を当てており、それらを軽減する方法に関する推奨事項も含まれています。焦点は Webの脆弱性トップ10 によって識別されます オープンWebアプリケーションセキュリティプロジェクト(OWASP) 、世界中のソフトウェアセキュリティを向上させることを目標とする国際的な非営利団体。
他のプログラマーやIT専門家と話すとき、認証と認証の違いについて混乱することがよくあります。そしてもちろん、略語という事実 auth 両方によく使用され、この一般的な混乱を悪化させるのに役立ちます。この混乱は非常に一般的であるため、この問題は「Common WebVulnerabilityZero」としてこの投稿に含める必要があります。
したがって、先に進む前に、これら2つの用語の違いを明確にしましょう。
別の言い方をすれば、 認証 エンティティが誰であるかを知っている間 承認 特定のエンティティが何ができるかを知っています。これを念頭に置いて、インターネットセキュリティの問題トップ10に入りましょう。
インジェクションの欠陥は、信頼できない入力をフィルタリングするという古典的な失敗に起因します。これは、フィルタリングされていないデータをSQLサーバー(SQLインジェクション)、ブラウザー(XSS –これについて説明します)に渡すときに発生する可能性があります。 後で )、LDAPサーバー(LDAPインジェクション)、またはその他の場所へ。ここでの問題は、攻撃者がこれらのエンティティにコマンドを挿入し、データを失い、クライアントのブラウザを乗っ取る可能性があることです。
アプリケーションが信頼できないソースから受け取るものはすべてフィルタリングする必要があります。 できればホワイトリストに従ってください。ブラックリストを正しく取得するのは非常に難しく、通常はバイパスしやすいため、ブラックリストを使用することはほとんどありません。ウイルス対策ソフトウェア製品は通常、失敗したブラックリストの優れた例を提供します。パターンマッチングは機能しません。
防止: 良いニュースは、インジェクションから保護することは、入力を適切にフィルタリングし、入力が信頼できるかどうかを考えることの「単純な」問題であるということです。しかし、悪いニュースはそれです すべて 間違いなく信頼できる場合を除いて、入力は適切にフィルタリングする必要があります(ただし、ここでは「決して言わない」という言葉が思い浮かびます)。
たとえば、1,000個の入力があるシステムでは、999個の入力を正常にフィルタリングするだけでは不十分です。これは、システムをダウンさせるためのアキレス腱として機能できるフィールドが1つ残っているためです。また、データベースは信頼されているため、SQLクエリの結果を別のクエリに入れるのは良い考えだと思うかもしれませんが、境界が信頼されていない場合、入力は悪意のある人から間接的に行われます。これは呼ばれます 二次SQLインジェクション 興味がある場合に備えて。
フィルタリングは(暗号のように)正しく行うのがかなり難しいので、私が通常アドバイスするのは、フレームワークのフィルタリング機能に依存することです。それらは機能することが証明されており、徹底的に精査されています。フレームワークを使用しない場合は、本当に ない それらを使用することは、サーバーのセキュリティコンテキストで本当に意味があります。 99%の確率でそうではありません。
これは、認証の失敗中に発生する可能性のある複数の問題のコレクションですが、すべてが同じ根本原因に起因するわけではありません。
誰かが2014年にまだ自分の認証コードをロールしたいと思っていると仮定すると(あなたは何を考えていますか??)、私はそれに反対することをお勧めします。正しく理解することは非常に困難であり、いくつか言及するだけで、考えられる落とし穴は無数にあります。
防止: このWebセキュリティの脆弱性を回避する最も簡単な方法は、フレームワークを使用することです。これを正しく実装できるかもしれませんが、前者の方がはるかに簡単です。独自のコードを作成したい場合は、非常に偏執的になり、落とし穴について自分自身を教育してください。かなりの数があります。
これはかなり広範囲にわたる入力サニタイズの失敗です(本質的には よくある間違い#1 )。攻撃者は、入力時にWebアプリケーションにJavaScriptタグを与えます。この入力がサニタイズされていないユーザーに返されると、ユーザーのブラウザがそれを実行します。リンクを作成してユーザーにクリックするように説得するのと同じくらい簡単な場合もあれば、もっと不吉なものにする場合もあります。ページの読み込み時にスクリプトが実行され、たとえば、攻撃者にCookieを投稿するために使用できます。
防止: シンプルなウェブセキュリティソリューションがあります。HTMLタグをクライアントに返さないでください。これには、HTMLインジェクション、つまり攻撃者がプレーンなHTMLコンテンツ(画像や大音量の非表示のFlash Playerなど)をインジェクトする同様の攻撃から防御するという追加の利点があります。通常、回避策は単にすべてを変換することです HTMLエンティティ 、したがって、として返されます。よく使用される他のサニタイズ方法は、正規表現を使用して、
<
で正規表現を使用してHTMLタグを削除することです。および>
ですが、多くのブラウザがひどく壊れたHTMLを問題なく解釈するため、これは危険です。すべての文字をエスケープされた対応する文字に変換することをお勧めします。
これは、ユーザー入力を信頼し、結果として生じるセキュリティの脆弱性に代償を払う典型的なケースです。直接オブジェクト参照とは、ファイルやデータベースキーなどの内部オブジェクトがユーザーに公開されることを意味します。これに伴う問題は、攻撃者がこの参照を提供でき、承認が強制されていない(または壊れている)場合、攻撃者はアクセスしたり、除外すべきことを実行したりできることです。
たとえば、コードにはdownload.php
がありますCGIパラメータを使用してファイル名を指定し、ユーザーがファイルを読み取ってダウンロードできるようにするモジュール(例:download.php?file=something.txt
)。誤って、または怠惰のために、開発者はコードから認証を省略しました。攻撃者はこれを使用して、PHPを実行しているユーザーがアクセスできるシステムファイルをダウンロードできます。たとえば、アプリケーションコード自体や、バックアップなど、サーバー上に残っている他のデータなどです。ええとああ。
ソフトウェアコードの書き方
もう1つの一般的な脆弱性の例は、ユーザー入力に依存してリセットするパスワードを決定するパスワードリセット機能です。有効なURLをクリックした後、攻撃者はusername
を変更するだけです。 URLのフィールドに「admin」のようなものを言います。
ちなみに、これらの例は両方とも、私自身が「野生で」頻繁に現れるのを見たものです。
防止: ユーザー認証を適切かつ一貫して実行し、選択肢をホワイトリストに登録します。ただし、多くの場合、データを内部に保存し、CGIパラメータを介してクライアントから渡されるデータに依存しないことで、問題全体を回避できます。ほとんどのフレームワークのセッション変数は、この目的に適しています。
私の経験では、誤って構成されたWebサーバーとアプリケーションは、適切に構成されたものよりもはるかに一般的です。おそらくこれは、失敗する方法に不足がないためです。いくつかの例:
防止: デプロイ時にテストを実行できる、優れた(できれば自動化された)「ビルドとデプロイ」プロセスを用意します。貧乏人のセキュリティ設定ミスの解決策は、コミット後のフックであり、デフォルトのパスワードや開発関連のものが組み込まれた状態でコードが送信されるのを防ぎます。
このWebセキュリティの脆弱性は、暗号化とリソース保護に関するものです。 機密データは、転送中および保存中を含め、常に暗号化する必要があります。例外なし。 クレジットカード情報とユーザーパスワードは 決して 旅行または暗号化せずに保存し、パスワードは常にハッシュする必要があります。明らかに、暗号化/ハッシュアルゴリズムは弱いものであってはなりません–疑わしい場合は、Webセキュリティ標準が推奨します AES(256ビット以上) そして RSA(2048ビット以上) 。
言うまでもなく、セッションIDと機密データがURLを移動してはならず、機密Cookieにセキュアフラグがオンになっている必要がありますが、これは非常に重要であり、強調しすぎることはありません。
防止:
輸送中: 使用する HTTPS 適切な証明書と PFS(Perfect Forward Secrecy) 。非HTTPS接続では何も受け入れないでください。 Cookieに安全なフラグを付けます。
ストレージ内: これは難しいです。何よりもまず、露出を下げる必要があります。機密データが必要ない場合は、細断処理してください。あなたが持っていないデータはありえない 盗まれた 。クレジットカード情報を保存しないでください これまで 、おそらくあなたは存在に対処する必要はないので PCI準拠 。次のような支払い処理業者にサインアップします 縞 または Braintree 。次に、実際に必要な機密データがある場合は、暗号化して保存し、すべてのパスワードがハッシュされていることを確認します。ハッシュには、 bcrypt がおすすめ。 bcryptを使用しない場合は、 塩漬け そして レインボーテーブル 。
そして、明白なことを述べるリスクを冒して、 保護されたデータの横に暗号化キーを保存しないでください 。これは、鍵が入ったロックを付けて自転車を保管するようなものです。バックアップを暗号化で保護し、キーを非常にプライベートに保ちます。そしてもちろん、鍵をなくさないでください!
これは単に認証の失敗です。これは、サーバーで関数が呼び出されたときに、適切な承認が実行されなかったことを意味します。多くの場合、開発者はサーバー側がUIを生成したという事実に依存しており、サーバーによって提供されていない機能にはクライアントがアクセスできないと考えています。攻撃者はいつでも「非表示」機能へのリクエストを偽造でき、UIがこの機能に簡単にアクセスできないという事実によって阻止されないため、それほど単純ではありません。 /admin
があると想像してみてくださいパネル、およびボタンは、ユーザーが実際に管理者である場合にのみUIに表示されます。攻撃者がこの機能を発見し、認証が欠落している場合に悪用することを妨げるものは何もありません。
防止: サーバー側では、認証は 常に 終わり。はい、いつも。例外や脆弱性が深刻な問題を引き起こすことはありません。
これは良い例です 混乱した副 ブラウザが他の当事者にだまされてその権限を悪用する攻撃。たとえば、サードパーティのサイトは、ユーザーのブラウザが攻撃者のために何かをする権限を悪用する可能性があります。
CSRFの場合、サードパーティのサイトは、Cookie /セッションでブラウザを使用してターゲットサイト(銀行など)にリクエストを発行します。たとえば、銀行のホームページの1つのタブにログインしていて、この攻撃に対して脆弱である場合、別のタブを使用すると、ブラウザが攻撃者に代わって資格情報を悪用し、代理の混乱を招く可能性があります。代理人は、攻撃者が指示したことを行うためにその権限(セッションCookie)を悪用するブラウザです。
この例を考えてみましょう。
攻撃者のアリスは、彼のお金の一部を彼女に送金することで、ターゲットのトッドの財布を軽くしたいと考えています。トッドの銀行はCSRFに対して脆弱です。送金するには、トッドは次のURLにアクセスする必要があります。
img / back-end / 29 / 10-most-common-web-security-vulnerabilities.jpg
このURLが開かれると、成功ページがToddに表示され、転送が行われます。アリスはまた、トッドが自分の管理下にあるblog.aliceisawesome.comのサイトに頻繁にアクセスし、次のスニペットを配置していることも知っています。
アリスのウェブサイトにアクセスすると、トッドのブラウザはアリスが画像にリンクしていると見なし、画像を取得するためにHTTP GETリクエストを自動的に発行しますが、これは実際にはトッドの銀行に$ 1500をアリスに送金するように指示します。
ちなみに、この例では、CSRFの脆弱性を示すだけでなく、それ自体が深刻な脆弱性であるべき等のHTTPGETリクエストを使用してサーバーの状態を変更することも示しています。 HTTPGETリクエスト しなければならない あります べき等 (安全)、つまり、アクセスされるリソースを変更できないことを意味します。サーバーの状態を変更するためにべき等メソッドを使用することは決してありません。
おもしろい事実:CSRFは、アフィリエイトが賢くなるまで、過去にCookieの詰め込みに使用されていた方法でもあります。
防止: サードパーティのサイトからアクセスできない非表示のフォームフィールドにシークレットトークンを保存します。もちろん、常にこの隠しフィールドを確認する必要があります。一部のサイトでは、機密性の高い設定を変更するときにもパスワードを要求されます(たとえば、パスワードのリマインダーメールなど)。ただし、これは、放棄されたセッションの誤用を防ぐためにあると思われます(たとえば、インターネットカフェで)。
タイトルがすべてを物語っています。これも、メンテナンス/導入の問題として分類します。新しいコードを組み込む前に、調査、場合によっては監査を行ってください。ランダムな人から入手したコードを使用する GitHub または、いくつかのフォーラムは非常に便利かもしれませんが、深刻なWebセキュリティの脆弱性のリスクがないわけではありません。
たとえば、サイトが取得した多くのインスタンスを見てきました 所有 (つまり、部外者がシステムへの管理アクセスを取得する場合)、プログラマーが愚かだったからではなく、サードパーティのソフトウェアが何年にもわたってパッチが適用されていないためです。これは、たとえばWordPressプラグインで常に発生しています。あなたが彼らがあなたの隠されたものを見つけられないと思うならphpmyadmin
インストール、dirbusterを紹介させてください。
ここでの教訓は、アプリケーションが展開されてもソフトウェア開発は終了しないということです。特にサードパーティまたはオープンソースのコンポーネントが含まれている場合は、更新を維持および維持する方法に関するドキュメント、テスト、および計画が必要です。
防止:
注意してください。 そのようなコンポーネントを使用するときに明らかに注意を払う以外に、コピー&ペーストコーダーにならないでください。ソフトウェアに挿入しようとしているコードは、修復できないほど壊れている可能性があるため、注意深く調べてください(または、場合によっては、意図的に悪意があります。Webセキュリティ攻撃が無意識のうちにこのように誘われることがあります)。
最新に保つ。 信頼できるものすべての最新バージョンを使用していることを確認し、定期的に更新する計画を立ててください。少なくとも、製品に関する新しいセキュリティの脆弱性に関するニュースレターを購読してください。
これもまた、入力フィルタリングの問題です。ターゲットサイトにredirect.php
があるとします。 URLをGET
として受け取るモジュールパラメータ。パラメータを操作すると、targetsite.com
にURLを作成できます。ブラウザをmalwareinstall.com
にリダイレクトします。ユーザーにリンクが表示されると、targetsite.com/blahblahblah
が表示されます。ユーザーが信頼でき、クリックしても安全だと考えるもの。これが実際にマルウェアドロップ(またはその他の悪意のある)ページに転送されることを彼らはほとんど知りません。または、攻撃者がブラウザをtargetsite.com/deleteprofile?confirm=1
にリダイレクトする可能性があります。
言及する価値があるのは、サニタイズされていないユーザー定義の入力をHTTPヘッダーに詰め込むと ヘッダーインジェクション これはかなり悪いです。
防止: オプションは次のとおりです。
この投稿であなたの脳を少しくすぐり、健康的な量のパラノイアとWebサイトのセキュリティ脆弱性の認識を紹介できたことを願っています。
ここでの重要なポイントは、古くからのソフトウェアプラクティスが理由で存在し、バッファオーバーフローに対して当時適用されていたものが、今日でもPythonのピクルス文字列に適用されていることです。セキュリティプロトコルは、すべてのプログラマーが目指すべき(より多くの)正しいプログラムを書くのに役立ちます。
この知識を責任を持って使用し、許可なくページをテストしないでください。
異文化コミュニケーションの障壁
詳細および詳細については 特定のサーバー側の攻撃 、 見て: https://www.owasp.org/index.php/Category:Attack 。
この投稿へのフィードバックとその緩和アドバイスを歓迎し、感謝しています。特にの問題に関して、将来の関連する投稿が計画されています 分散型サービス拒否(DDoS) および旧式の(Webではない)ITセキュリティの脆弱性。どのような種類のウェブ保護について書くべきかについて具体的な要求がある場合は、直接私に連絡してください。 [メール保護]
これがウェブサイトのセキュリティです!乾杯。
関連:インターネットセキュリティの脅威は、Webテクノロジを悪用して、Webサイト、そのユーザー、さらにはインターネット全体に損害を与える方法です。これらは、構成が誤っている、不注意で脆弱性がプログラムされている、またはそれ自体が脆弱なコンポーネントに依存しているWebサイトから発生します。
インターネットセキュリティの脅威のトップ10は、インジェクションと認証の欠陥、XSS、安全でない直接オブジェクト参照、セキュリティの設定ミス、機密データの公開、機能レベルの承認の欠如、CSRF、安全でないコンポーネント、フィルタリングされていないリダイレクトです。
サイトが(HTTPヘッダー、メタタグ、JavaScriptなどを介して)行うリダイレクトがユーザー入力に依存していないことを確認してください。依存している場合は、ユーザー入力がホワイトリストなどを介してサニタイズされていることを確認してください。
CSRFトークンは、リクエストが自分のサイトのユーザーからのものであり、ユーザーがアクセスしている他のWebサイトからのものではないことをサーバーに通知します。これは、すべてのリクエストで非表示のフォームフィールドを介して渡され、悪意のあるサイトがCSRF攻撃を介して視聴者に代わって行動するのを防ぐためです。
「ダーティ」または「信頼できない」入力とも呼ばれる未検証の入力は、サーバーに送信されるすべての入力です。最初にサニタイズせずにそのような入力を使用するコードは、セキュリティの脆弱性であり、あなた、あなたのユーザー、さらには無実の傍観者にさえも逆らう可能性があります。
SQLインジェクションは、パラメーター化されたクエリ(つまり、プレースホルダーを使用するクエリ)を使用する代わりに、コードが未検証の入力をSQLステートメントに直接入力する場合です。幸い、SQLインジェクション攻撃は、パラメーター化されたクエリのサポートがすべてのデータベースに組み込まれているため、最も簡単に軽減できるものの1つです。ライブラリにアクセスします。
XSSは、一般的なWebアプリケーションの「機能」の誤った実装を悪用します。1人のユーザーからHTMLを受け取り、それを他のユーザーに提示します。フィルタリングされていないHTMLにはJavaScriptが含まれている可能性があるため、攻撃者は他のユーザーが次に問題のWebアプリケーションを使用するときに、他のユーザーに代わってコードを実行できます。
多くの場合、セキュリティの設定ミスには、変更が必要なデフォルトの使用が含まれます。キーとパスワード、セットアップとテストの利便性のために最初は自由なデータとサービスへのアクセス、継続的なセキュリティ更新の無視です。
これは、サーバーが特定の機能の許可を検証するようにプログラムされていない場合です。多くの場合、これは「隠すことによるセキュリティ」の考え方に由来します。機密性の高い機能がすべての人に表示されない場合、潜在的な攻撃者はそれを知ることができないと誤って想定されています。
機密データの公開とは、アプリが(自身の欠陥または攻撃者による脆弱性の悪用によって)ユーザーの個人データ(クレジットカード番号など)を許可されていない第三者(他のユーザー、ビジネスパートナー、従業員、または公衆。