ウェブサイト監査
ウェブサイトのフォームをチェックする方法:ラベル、入力タイプ、HTTPS、CSRF
フォームは、訪問者があなたにデータを預ける場所です。すべてのフォームで確認すべきこと、よくある問題の直し方、そして Rudra がフォームを一切送信せずに点検する理由を解説します。
このページの内容
問い合わせフォーム、会員登録、ログイン、購入手続き、検索ボックスは、サイトが訪問者に何かをしてもらう場所です。わかりにくいフォーム、スマートフォンで入力しにくいフォーム、安全でないフォームは、見込み客と信頼を失わせます。しかも、フォームの問題は誰かが苦情を言うまでほとんど表に出てきません。途中であきらめた人は、そのことを教えてくれないからです。
フォームの問題のほとんどは HTML を見ればわかるので、何も入力せずにチェックできます。確認すべき点を紹介します。
使いやすさとアクセシビリティ
すべての入力欄にラベルが必要
各入力欄には、for と id で関連付けた(または入力欄を囲んだ)<label> が必要です。スクリーンリーダーはラベルを読み上げ、ラベルをクリックすると入力欄にフォーカスが移ります。プレースホルダーはラベルではありません。入力を始めたとたんに消え、コントラストが低いことが多く、確実に読み上げられるとも限りません。デザイン上どうしても目に見えるラベルを表示できない場合は aria-label が代替手段になりますが、目に見えるラベルはすべての人の役に立ちます。ラベルについては、アクセシビリティガイドでさらに詳しく解説しています。
正しい入力タイプを使う
type="email"、type="tel"、type="url" を指定すると、スマートフォンで適切なキーボードが表示され、ブラウザによる基本的な入力チェックも働きます。電話番号の欄が type="text" になっていると、モバイルの訪問者は数字キーを探さなければなりません。type="number" には注意が必要です。これは数量のためのもので、電話番号、カード番号、郵便番号には向いていません。
autocomplete のヒントを追加する
autocomplete 属性は、各入力欄が何であるかをブラウザやパスワードマネージャーに伝えます。指定できる値には、name、email、tel、street-address、postal-code、cc-number、current-password、new-password、one-time-code などがあります。訪問者はワンタップでフォームを入力できるようになり、ユーザー自身に関する情報を集める入力欄については WCAG 2.1 の要件(達成基準 1.3.5)でもあります。パスワード欄に autocomplete="off" を指定してはいけません。弱いパスワードや使い回しのパスワードを使うよう、利用者を追い込むことになります。
本物の送信ボタンと、親切な入力チェック
<button type="submit"> を使えば、Enter キーでも、独自の JavaScript がなくてもフォームが動作します。必須項目には required 属性を付けたうえで、ラベルにも必須であることを明記し、エラーメッセージは該当する入力欄のそばに、わかりやすい言葉で表示します。novalidate を追加すると、ブラウザに組み込まれたチェックが無効になります。これは、独自のチェックで置き換える場合に限って問題ありません。
セキュリティ
- ページと action の両方を HTTPS にする:HTTP のページにあるパスワード欄や、
actionがhttp://のURLを指しているフォームは、入力された内容を平文で送信します。ページも action も HTTPS でなければなりません。 - パスワードには決して GET を使わない:
method="get"では、フォームの値がURLに含まれ、そこからブラウザの履歴、サーバーログ、リファラーヘッダーにも残ります。機密性のあるものにはmethod="post"を使ってください。 - CSRF 対策:何かを変更するフォーム(ログイン、アカウントの更新、注文)は、クロスサイトリクエストフォージェリから保護すべきです。通常は、サーバーが検証する秘密のトークンを隠しフィールドに入れ、あわせて
SameSiteCookie を使います。Cookie のセキュリティを確認する方法をご覧ください。 - データの送信先を把握する:メール配信サービスや CRM サービスなど、別のドメインに送信するフォームは想定どおりの場合もあります。ただし、それが意図したものであり、プライバシーポリシーに記載されていることを確認してください。
- サーバー側で検証する:ブラウザでの入力チェックは、善意の訪問者のための便利な機能にすぎず、誰でも回避できます。サーバーはすべての値をあらためて検証しなければなりません。
フォームを送信せずに点検する
Rudra の無料リンク切れチェッカーは、ページ上の各フォームを読み取り、安全でない action、GET で送信されるパスワード、ラベルの欠落などを指摘します。フォームの送信、クリック、入力は一切行いません。
Rudra はフォームを送信せずにどうチェックするのか
無料リンク切れチェッカーとウェブサイト監査は、実際のブラウザでページを読み込み、ページ上のフォームを最大10個まで点検します。該当するフォーム名とフィールド名を添えて、次の点を指摘します。
- HTTP のページにあるパスワード欄、
http://に送信するフォーム、GET を使うパスワードフォーム(それぞれ10点の減点) - ラベルがプレースホルダーしかない入力欄(3点の減点)
- アクセシブルなラベルのない入力欄、項目の内容に合っていない入力タイプ(メールアドレス欄に
type="text"を使っているなど)、autocomplete のヒントの欠落、パスワード欄のautocomplete="off"、別のホストに送信するフォーム、送信ボタンのないフォーム、入力制約のない必須のメールアドレス欄や電話番号欄、novalidate(いずれも参考情報) - CSRF 対策らしきトークンが見当たらない POST フォーム。これは低い確度での指摘です。トークンが JavaScript で追加されている場合や、サーバーが別の方法でフォームを保護している場合があるためです。
さらに、必須と指定された入力欄が空のまま送信されたらブロックするかどうかを、ブラウザに1回だけ問い合わせます。これは各入力欄の検証状態を読み取るだけで、フォーカスも入力も行わず、サイト独自の入力チェック処理を起動することもありません。
フォームを決して送信しない理由
フォームを送信すると、現実に影響が生じます。誰かの受信トレイにメールが届き、アカウントが作成され、注文やサポートチケットが発生し、レート制限や不正検知フィルターが作動します。自動ツールには、どのフォームなら送信しても安全なのかを知る手段がありません。そのため、私たちのツールは一切送信しません。フォームの送信、クリック、フォーカス、入力は決して行わず、レポートに含まれるのはフィールド名とラベルだけで、値は決して含まれません。
その代わり、フォームを実際に送信しなければテストできないこともあり、それはご自身で確認していただく必要があります。送信内容がきちんと届くか、確認メッセージやエラーメッセージがどう表示されるか、サーバーが不正な入力や他サイトからの入力を拒否するか、スパム対策が機能しているか、といった点です。
フォームごとに行う手動テスト
- スマートフォンで入力し、各入力欄で適切なキーボードが表示されるか、自動入力が正しく働くかを確認します。
- キーボードだけで最後まで入力し、次に NVDA や VoiceOver などのスクリーンリーダーでも試します。
- 空のまま送信し、また誤ったメールアドレスを入力して送信し、エラーメッセージを読みます。
- 正しく入力して送信し、メッセージが届くべき場所に届くことを確認します。
- ログインフォームやアカウント関連のフォームについては、CSRF 対策とサーバー側の検証を開発者に確認してもらいます。
よくある質問
フォームは保護されているのに、なぜ Rudra は CSRF トークンがないと指摘するのですか?
このチェックで確認できるのは、HTML に隠しフィールドとして存在するトークンだけです。お使いのフレームワークがトークンを JavaScript で追加している場合や、SameSite Cookie やカスタムヘッダーでフォームを保護している場合もあります。そのため、この指摘は低い確度とされ、手動での確認をお願いしています。
プレースホルダーのテキストだけでラベルの代わりになりますか?
いいえ。プレースホルダーは入力を始めると消え、コントラストが低いことが多く、スクリーンリーダーで確実に読み上げられるとも限りません。目に見える label 要素を使ってください。
フォームの autocomplete は無効にすべきですか?
一般的には、いいえ。autocomplete はフォームをすばやく正確に入力する助けになり、WCAG 2.1 では個人情報の入力欄に必須とされています。パスワード欄で無効にすると、パスワードマネージャーが役に立ちにくくなります。
Rudra は、問い合わせフォームからメールが送信されるかどうかをテストできますか?
いいえ。フォームは決して送信されないので、メールの到達、確認メッセージ、サーバー側の検証は、ご自身でフォームを送信してテストする必要があります。