HTML hidden入力:送信値・JavaScriptでの変更と安全性の限界
input type="hidden"は、入力ボックスを表示せずにフォームに名前と値を含めます。nameは送信されたフィールド名で、valueはその値です。ユーザーはこれを確認または変更できるため、パスワード、権限、価格、その他の機密的な決定を保護するためには使用しないでください。
隠し入力はいつ使用すべきですか?
編集フォームとともに対象の投稿IDを送信するため、または検索条件を次のリクエストに引き継ぐために使用します。ユーザーが入力する必要のない値を渡しますが、それらが有効かどうかを判断する責任はサーバー側にあります。
投稿IDを受け取ったからといって、その投稿を編集する許可があるわけではありません。サーバーは認証済みセッションを通じてユーザーを識別し、投稿へのアクセス権を確認する必要があります。クライアントが隠しフィールドで送信しただけのアカウント情報やクライアントIP情報を信用してはいけません。
| タイプ | 画面上の挙動 | フォームデータ |
|---|---|---|
type="hidden" |
入力用のUIはなく、フォーカスも受けません。 | 名前が付けられていて無効にされていなければ含まれます。 |
disabled |
コントロールを無効にします。 | 除外されます。 |
| 通常の入力はCSSの display: none で非表示にされます。 | CSSは通常の入力をレイアウトから隠します。 | CSSだけで隠しても、送信からは除外されません。 |
id はスクリプトで要素を見つけることはできますが、送信される名前を置き換えることはありません。名前なしの隠し入力は、通常のフォーム送信では名前/値のエントリとして含まれません。required が付いていても、隠し入力はブラウザの制約バリデーションには参加しません。
見えない値が送信されることを確認してください
この完全なコードをhidden.htmlとして保存し、ブラウザで開いてください。サーバーは必要ありません。送信すると、ネットワークリクエストを行うのではなく、FormDataで作成された名前/値エントリーが表示されます。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>hidden値の確認</title>
<style>
body { margin: 24px; font-family: sans-serif; }
label { display: block; margin: 12px 0; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<h1>色を選択</h1>
<form id="demo">
<label><input type="checkbox" name="color" value="blue" checked> 青</label>
<label><input type="checkbox" name="color" value="red"> 赤</label>
<input type="hidden" id="size" name="size" value="big">
<input type="hidden" name="excluded" value="not-sent" disabled>
<button type="submit">送信値を確認</button>
<button type="button" id="change">hidden値をsmallに変更</button>
<button type="button" id="restore">hidden値をbigに戻す</button>
</form>
<p id="status" aria-live="polite">初期のhidden値はbigです。</p>
<pre id="result" aria-live="polite"></pre>
<script>
const form = document.querySelector('#demo');
const size = document.querySelector('#size');
const result = document.querySelector('#result');
const status = document.querySelector('#status');
form.addEventListener('submit', (event) => {
event.preventDefault();
result.textContent = JSON.stringify([...new FormData(form).entries()], null, 2);
});
function setSize(value) {
size.value = value;
status.textContent = `現在のhidden値:${value}。もう一度「送信値を確認」を押してください。`;
}
document.querySelector('#change').addEventListener('click', () => setSize('small'));
document.querySelector('#restore').addEventListener('click', () => setSize('big'));
</script>
</body>
</html>
- 最初に送信する:
color=blueとsize=bigが表示されます。サイズボックスは表示されませんが、その値は含まれます。excludedは無効になっているため省略されます。 - 赤を選択して再度送信すると、繰り返されたカラー名の下に青と赤が表示されます。両方のチェックボックスをクリアすると、サイズだけが残ります。
- 隠し値をsmallに変更するボタンを押して再度送信すると、
size=smallが表示されます。隠し値はJavaScriptを通じても変更できます。 - 復元ボタンで
bigに戻して再度送信します。変更ボタンは動作を観察するための練習用であり、すべてのサービスに必要な機能ではありません。
フォームを実際のサーバーに送信します
実際のサービスでは、アクションを既存の処理ルートに設定し、method="post"のようなサポートされているメソッドを選択してください。例の送信ハンドラーはリクエストをブロックします; それを削除するか、データを送信するサーバーリクエストコードに置き換えてください。サーバーのフォーム処理機能は、通常のテキストフィールドと同様に隠しフィールドも受け取ります。
名前が同じ複数のチェックボックスを受け取る場合は、サーバーフレームワークの配列および複数値ルールを確認してください。一部のパーサーは最後に繰り返された値のみを読み取ります。JavaScriptの出力は繰り返された名前を保持するので、その違いを確認できます。
隠すこととセキュリティを混同しないでください
隠し値はHTMLソース、開発者ツール、ネットワークリクエストで確認可能です。HTTPSは値を送信するユーザーから隠すものではありません。製品IDを受け取った場合は、サーバーで製品と価格を確認し、許可されたサイズの値を信頼できるサーバー情報と照合してください。
隠しフィールドはCSRF(Cross-Site Request Forgery、サイト間リクエスト偽造)トークンを保持できます。保護は、サーバー側での適切なトークン発行と検証から来ます。隠し入力に任意の固定文字列を入れても、それだけでは偽造リクエストを防ぐことはできません。
MDN 隠し入力リファレンス は、その動作とバリデーション対象外であることを説明しています。




