7 ポイント 投稿者 GN⁺ 9 시간 전 | 2件のコメント | WhatsAppで共有
  • Don't Roll Your Own ... の原則は暗号化だけでなく Web UI にも当てはまり、ブラウザがすでに安定して提供している機能を不必要に置き換えるべきではない
  • 独自スクロール、リンク処理、テキスト選択、コピー・ペーストのような 基本動作の置き換え は、慣れ親しんだ入力反応を壊し、ユーザーに操作方法そのものを再び意識させてしまう
  • GitHub のファイル・Issue リンクのように JavaScript が リンク遷移 を横取りすると、現在のタブで処理されるのを待つより新しいタブで開くほうが速いことがある
  • 標準の パスワードフィールド<input type="date"> は、自動補完、パスワードマネージャー、アクセシビリティツール、モバイルキーボードと連携するため、偽の UI に置き換えると機能が壊れることがある
  • 数か月ごとに変わるレイアウトやフォームコントロールは、ユーザーに作業より再学習へ時間を使わせるため、安定したブラウザ標準動作を維持するほうが望ましい

「自前で作るな」原則の Web UI への適用

  • 暗号化を自前実装してはいけない というのは、機密データを保護する運用ソフトウェアで、検証されていない私的実装に依存するなという原則である
  • 誰も暗号化コードを書いてはいけないという意味ではなく、可能な限り レビューされ検証済みのパッケージやツール を使うべきだ、という意味に近い
  • 約20年前には、不適切な初期化ベクトル、予測可能なキーストリーム、平文の一部漏えいといった問題を抱えた独自 RC4 実装が実際に存在した
  • 現在、主要な EC サイトや銀行は一般に Web サービスで独自暗号化を使っておらず、決済・医療・個人情報処理のような規制分野では、強力な暗号化要件への違反が高額な罰金につながり得る
  • Web サイト設計は暗号化と同じではないが、ブラウザがすでにうまく処理し、ユーザーが毎日頼っている機能を再実装すると、ユーザー体験が悪化することがある

ブラウザ標準機能を置き換えるときに生じる問題

  • ページスクロール を自前実装すると、マウス、タッチパッド、キーボード入力に対する慣れた反応が崩れることがある
  • 既定のスクロール動作を上書きすると、ページが遅すぎたり速すぎたり動き、キーボードスクロールが機能しないこともある
  • ユーザーが無意識に使っていた動作が見慣れないものに変わると、ページ操作そのものを改めて意識しなければならなくなる
  • 自前実装すべきでない代表的な機能には、リンク遷移、テキスト選択、コンテキストメニュー、コピー・ペースト、パスワードフィールド、日付ピッカーが含まれる
  • 真面目な業務用 Web サイトにユーザーインターフェース機能を入れる際は、派手な機能を追加するか、ブラウザ標準動作に任せるかを保守的に判断する必要がある

リンク遷移と GitHub の事例

  • Web ブラウザはリンクをたどる処理をすでにうまくこなしており、リンク遷移はブラウザの中核機能である
  • 正常なリンク動作を妨げる必要があると感じるなら、達成したい目標が通常の リンク遷移 を壊してまで重要なのかを見直すべきである
  • GitHub では、ファイルリンクや Issue リンクをクリックすると、JavaScript で実装された大きな機能がクリック処理を代行する
  • Firefox や Chrome で F12 から開発者ツールを開き、Debugger または Sources タブの Event Listener BreakpointsMouseclick を選んでから GitHub のリンクをクリックすると、この挙動を確認できる
  • GitHub では、現在のタブで JavaScript の遷移処理を待つより、新しいタブでリンクを開くほうが速いことがある

パスワード入力と日付ピッカー

  • ブラウザの パスワード入力フィールド は、パスワード保存、自動入力、新規アカウント向けの強力なパスワード生成機能を提供できる
  • 標準のパスワードフィールドは、安全でない HTTP 接続でパスワードが送信される際に警告を出し、パスワードマネージャー・自動補完・モバイルキーボード・アクセシビリティツールとも連携する
  • 偽のパスワードフィールドに置き換えるとこうした機能が壊れることがあり、通常のテキストフィールドを自前でマスクすると、ブラウザ・OS・支援ツールがパスワードを通常の可視テキストとして扱う可能性がある
  • <input type="date"> は日付範囲選択を直接サポートしないが、開始日と終了日の入力欄を2つ用意すれば、ブラウザ標準の日付ピッカーを維持できる
  • カスタム日付ピッカー は実装ごとに方式が異なり、年表示まで拡大しなければならなかったり、生年を選ぶために前年ボタンを何十回も押さなければならなかったり、日付の直接入力ができなかったりする
  • 標準の日付ピッカー対応が不十分なブラウザ向けにカレンダーウィジェットが必要なら、<input type="date"> を置き換えるのではなく、同じフィールドを操作する補助ウィジェットとして追加するほうがよい

頻繁な UI 変更のコスト

  • フォームコントロールを安易に変えると、既存の問題を解決する一方で、ほぼ必ず新たな問題を持ち込む
  • Web サイトのレイアウトやインターフェースを数か月ごとに変えると、一部のユーザーは適応できても、高齢のユーザーは毎回新しい道具を学ぶのに等しい負担を負う
  • 複数の Web サイトが絶えずインターフェースを変えると、ユーザーは機能的な利得もないまま、慣れたものを学び直すために相当な時間を費やすことになる
  • Linux ディストリビューションが数か月ごとに中核コマンドとコマンドラインオプションを全面的に再設計したり、洗濯機のボタン配置が毎朝変わったりするように、反復的な UI 再配置は不快な体験になる
  • Web UI はユーザーが仕事を終えるために使う道具なのだから、ブラウザがすでに提供している慣れた安定動作を不必要に置き換えないほうが望ましい

2件のコメント

 
kirinonakar 3 시간 전

韓国のように独自の暗号化や独自のセキュリティプログラムがこれほど多い国はないように思います。

 
GN⁺ 9 시간 전
Lobste.rs の意見
  • ページスクロールを自前で実装するべきではない、という点には同意する。ネイティブほど良くは作れないし、例外として認められるのは、地図のようにスクロールがズームに対応づけられる慣例がある場合くらいだろう

    しかし、リンクナビゲーションを自前実装しないことをルールにするのには強く反対する。一般的なコンテンツサイトならクライアントサイドルーティング(CSR)は勧めないが、アプリによってはむしろ積極的に推奨できるし、GitHubのようなサービスはその中間にある

    ただし、常に実際の `` 要素を使ってブラウザのネイティブ機能が動作するようにすべきだ。WebメールクライアントのようなアプリではCSRを使うのが妥当で、GitHubも以前のように軽く適用していた頃は改善になっていたが、最近のフロントエンドのアプローチはかなり悪くなっている

    問題は、CSRがあまりにも頻繁に雑に実装され、劣悪なネットワーク条件に対して堅牢に作られていないことだ。ブラウザはこうした状況に強く、タブの読み込み表示やbfcacheのような最適化もCSRでは妨げられることがある

    テキスト選択の自前実装は、モバイルで指を蛍光ペンのように使う注釈アプリのような、ごく特殊な場合だけ例外と見なせるだろう。むしろ ::selection も使わないでほしいと付け加えたい。::selection{} をスタイルシートに追加するだけで選択範囲が見えなくなるのは悪い設計だ

    コンテキストメニューの自前実装禁止には反対する。メールクライアント、ファイルマネージャー、ワープロのようなアプリでは独自項目が必要で、ブラウザが拡張手段を提供していない以上、完全なカスタムメニューは今のところ実用的な選択だ。Firefoxでは Shift+右クリックでネイティブメニューを強制的に開けるのはありがたい

    コピー/ペーストの自前実装禁止については、解釈次第で賛成も反対もできるので、もっと明確であるべきだ

    パスワードフィールドを自前実装した例は、技術デモ以外ではほとんど見た記憶がない。表示/非表示ボタンで `` を password から text に切り替える程度は、これには当たらないと思う

    日付ピッカーを自前実装するな、という点にも反対する。ネイティブコントロールは推奨したいが、制限や不一致が大きく、この10年ほとんど改善しようという関心もなかった。ピッカーに情報を付加できないし、生年月日のような昔の日付を選ぶ操作は、プラットフォームによってはひどい。例: Safari's date-picker is the cause of 1/3 of our customer support issues

    カスタム日付ピッカーにはアクセシビリティ上の問題が多いが、一般ユーザーにとってはより良いことも多く、ネイティブコントロールにない機能が必要で使えない場合も多い。単純な日付選択なら、私の使うブラウザでは直接入力できるのでネイティブを好むが、多くのユーザーにとってはネイティブは十分に良くない。日付範囲を `` 2つで作るのは、多くの人にとってはるかに悪くなる可能性が高い

    • アクセシビリティへの配慮が必要な人や、その恩恵を受ける人たちを「普通の人」と対比させる表現は、一部の読者を疎外しやすい。実際、アクセシビリティ支援を使う人たちの体験や必要性をかなり気にかけているように見えるので、なおさら指摘したくなる

    • Safariの日付ピッカーを実際に使ってみて、どれほど制限が多いかは分かった。だが、なぜWebサイトがネイティブの日付ピッカーをカレンダーウィジェットで置き換えるのかは、ずっと疑問だった

      カレンダーウィジェットをネイティブウィジェットの横に併設することはできないのだろうか。入力方法が2つあるように見えてUIが紛らわしくなるかもしれないが、片方を高度な日付ピッカーだと適切にラベル付けすれば解決できそうに思う。そうすれば、ネイティブの日付ピッカーを快適に使える人を失わずに、ブラウザの日付ピッカーが不十分な人も助けられる

      文書作成ツールやダイアグラム作成ツールのようなWebアプリでコンテキストメニューが必要なのは分かるが、右クリックしたときにブラウザの通常メニューが消えるのはやはり不便だ。なのでFirefoxの設定ではたいてい dom.event.contextmenu.enabled = false にしている。するとFirefoxのメニューが先に、その後ろにWebアプリのメニューが出るが、ネイティブメニューが使えるので悪くない回避策だ。可能ならWebアプリのメニューバーを使い、ブラウザのネイティブコンテキストメニューには手を付けないほうがよい。Shift+右クリックのヒントも良い解決策だ

    • アクセシブルなコントロールが必要な人たちも普通の人

    • パスワードフィールドの自前実装例なら、ペルーのほぼすべての銀行で見られる

      日付ピッカーはネイティブを使いたいが、実装側には改善しようという関心があまりないように見える。Firefoxには時間/時計選択UIの問題があり、進展も遅い: https://bugzilla.mozilla.org/show_bug.cgi?id=datetime

  • Webフォームでは良い指摘だ。ブラウザに任せるのが最もシンプルで速く、ほとんど常に最も一貫した方法だ

    ただし、暗号コードは別だ。正しい暗号コードを書くのは簡単ではないが、不可能でもない。状況によっては選択肢が少なすぎて、自分で作るのが最善なこともありうる

    ここで問題なのはセキュリティ正統派が、新しい暗号コードを書くには自分たちの内輪に属していなければならない、と決めつけがちなことだ。暗号学の博士号やDJB、Dan Bonehのもとでのインターン経験を示せなければ暗号コードを書いてはいけない、という言い方になる。「学習用」ならよいが、学んだことを実際に適用しようとすると駄目だと言う。外部集団にいる人の実力を見極めるのも苦手なことすらある。興味深いのは、この手のセキュリティ正統派と、論文を書く実際の暗号研究者との重なりが非常に小さく見えることだ

    今では、メモリ安全でない言語では何も書くな、という方向にまで拡張されている。致命的脆弱性の70%がそうだとしても、実際の原因は何だったのか。スタックに置かれない小さなオブジェクトごとに malloc() や明示的な new を使ったことや、ヌル終端文字列の扱いで大半の問題が起きたのだと思う。アリーナとスライスを使っていれば、そうした問題はずっと少なかったはずだ。もちろん、高リスクのシナリオでは特定のバグ種別を完全に排除する必要があり、その場合はメモリ安全性が最優先になる

    次は、信頼できない入力を処理するものは何も書くな、ということになるのだろうか。既存の車輪が全部四角くても車輪を再発明するな、ということだろうか。それでもJavaScriptの肥大化を避け、ブラウザが提供するフォームを使っているなら、自作のWebフレームワークを作ることまで大きな問題視はしない気がする

    • Cの原罪は、配列を渡すときに上限情報が失われてポインタに崩壊してしまう点にあると思う

    • 「自前で暗号を作るな」は絶対命題ではなく、強い警告だと理解してきた。博士号がなくても安全に実装できるというのはその通りだが、それでも膨大な学習が必要だ

      仕様をきっちり実装するだけなら、必要な学習はずっと少ないかもしれない。だが、たいていのソフトウェアは高速な暗号実装を求め、それによって複雑さが大きく増す。リンク先のMonocypherの脆弱性も良い例だ。突然、birational equivalence と Edwards点、Montgomery ladder がどうつながるかを理解する必要が出てくる

      博士号のような資格は、その人が何をしているかを分かっていると他人が信頼する助けになる。監査も別の経路だ。MonocypherはCure53の博士号保持者2名による監査を受けたようだ。問題は、ほとんどのプログラマが暗号ライブラリの安全性を判断する準備ができていないため、資格や監査人の資格といった非技術的シグナルに頼ることになる点だ。もっと直接的な方法があればよいが、資格はかなりうまく機能している

    • 自前で暗号を書くこと自体は、もちろん可能だ。不可能なら暗号ライブラリも存在しなかったはずだ。問題は、できるかどうかではなく、ユーザーのパスワードをハッシュし個人データを保護する本番環境で、あなたや私が手で書いた暗号を信頼できるかということだ。私は信頼しない

    • 以前の職場で、古いコードがライセンス検証にMD5を使っていて、古いC++コードを実行できない環境で検証しなければならず、MD5を再実装する必要があった。既存ライブラリも探したが、IV変更をサポートするものがなかった

    • 自前で暗号を作る勇気はないが、セキュリティ業界が今では独自認証すらするなと言い出しているのは、少し行き過ぎにも思える

  • ブラウザが自前実装なしでも使い物になる複数選択フィールドを提供してくれるといいのだが

    • あるにはあるが、ひどい
  • `` 2つで開始日と終了日を受け取る方式は、日付範囲には煩雑で直感的でもない。概念的には1つのものを、視覚的には無関係に見える2つの別々のビューに分けることになる

    日付範囲がないことは `` の多くの問題の1つにすぎない。たとえば特定の日付を除外できないので、予約サービスを提供するほぼあらゆるケースで出発点から使えない

    日付をどこでも同じように使うために、入力欄2つという小さなコストを受け入れるべきだ、という立場が多数派なのかは疑わしい。平均的なユーザーはフィールドを嫌い、1フィールドより悪いのは2フィールドだ。慣れの論理も説得力が弱い。私の経験では、Web上でネイティブの日付入力は珍しい

    • 開始日と終了日に対してそれぞれまともに動かないカスタムカレンダーウィジェットを2つ並べたWebサイトを何度も見た。泣きっ面に蜂だ

    • 日付範囲の部分には私も同意しなかった。日付範囲は概念上は単一コントロールだが、実際にはどれほど複雑になりうるかを示す例としてよく使う。「常にネイティブコントロールを使え」というスローガンは、問題により特化したより良いコントロールを提供できる場面で、むしろユーザー体験を悪化させることがある

      ネイティブでは実装できない日付/日付範囲コントロールの有用な機能として、価格表示がある。航空券やホテルを探すとき、どの日が安いか高いかを日付ピッカー内でそのまま見られるのは非常に便利だ。ネイティブコントロールだと、その情報を見るにはずっと多くクリックするか、別の表を見る必要があるが、カスタムコントロールなら日付ごとにそうしたメタデータを付けられる

      古典的な例は生年月日入力だ。日付ピッカーは通常、現在の月をデフォルト表示するが、これは目的の日付とほとんど関係がなく最悪だ。ここではカスタムコントロールを使うこともできるが、テキストボックスの組み合わせのほうが良い場合も多い。完全な自前コントロールというよりネイティブコントロールの組み合わせではあるが、要するに、あらゆるケースをうまく処理する「万能」日付ピッカーは存在しないということだ

  • 数年前の話なので再確認が必要だが、html5日付ピッカーの代わりに自前実装せざるを得なかった残念な理由があった。一部ブラウザの `` UI が本当にひどかったのだ

    コンテキストメニューの自前実装は稀だが、必要なときには非常に有用だ。たとえばWebページ内でダイアグラムエディタを作るなら、ダイアグラムのノードをクリックして便利な操作ができるよう、カスタムコンテキストメニューを用意してほしい。すべての操作を左クリックUI、たとえばアクションパレットとノードを交互にクリックする方式に押し込むのはよくない

    リストの残りの項目には強く同意する

  • 暗号の例とスクロール動作の問題をどう一緒に解釈すべきか分からない。両者はかなり別の領域に感じる

    Webサイトがやりすぎている、という総論には同意する。ただ、その動作はユーザーとWebサイトの目的によって変わる

    prefers-reduced-motion のように、prefers-user-scroll のような設定が中間的な解決策になりえないだろうか?

    • 縦スクロール領域を実装するためにスクロールジャッキングを使う正当なユースケースはない。そんなコードはそもそも書かれるべきではなかった

      ただし、これは縦スクロール領域に限った話だ。スクロールを非スクロール動作に再マッピングする場合にはユースケースがあり、依然として非常に問題は多いが、縦書き文字体系で縦を横にマッピングするケースなどは議論の余地がある。そのほかにも1つ2つ正当なユースケースはあるかもしれないが、実際の実装方法はたいてい依然として間違っている

  • ページスクロールの自前実装禁止には強く賛成する。KotlinConfで、Compose Multiplatform for Web のスクロール実装の難しさを扱った興味深い発表を聞いた

    問題の1つは、Webブラウザがネイティブアプリよりスクロールイベントを少なく送るため、スクロール方向を計算するアルゴリズムが失敗したことだった。すべての点を通る放物線を引き、最後の点での傾きを使う方式なのだが、点が少なすぎるとスクロール方向が逆に出てしまうことがある

    他プラットフォームから移植したり、こうした相互作用を再実装したりするときには、誤った前提から始めたり、ブラウザが標準で提供する「奇妙な」動作を忘れがちだ

    • 元のアプリでは、そうしたスクロールイベントは何に使われていて、なぜWebの文脈でも再現する必要があったのか気になる。スクロールを何かの駆動入力として使う方式には少し懐疑的だ
  • 「プラットフォームに頼れ」という助言は正しいが、プラットフォームに追従し続けることは難しい。enterkeyhintinputmode のように、存在は何となく知っていても効果を忘れがちなものがある

    今週、私たちのチームはそれを助けるために [0] を公開した。実装のベストプラクティスをスキルの形で提供するものだ。ドキュメントも人間が読んでかなり分かりやすい。例: [1]

    [0] https://github.com/GoogleChrome/modern-web-guidance [1] https://github.com/GoogleChrome/modern-web-guidance/…

  • 文章のトーンがちぐはぐだ。人々が、いつ、なぜ車輪を再発明する必要がないのかを十分理解できるよう説明するほうが、ずっと生産的だ

    記事は理由の説明自体はうまいが、「自前で作るな」という独断的な表現のせいで損をしている

    「自前で暗号を作るな」というスローガンも、結局は教条のように感じられる。それを言える専門家とは誰で、誰が彼らを任命したのか。そう言う前に自分でコードを見たのか。Heartbleedのような脆弱性を見れば、実際には初歩的なミスだったと分かるのではないか

    • 彼らは暗号学に人生を捧げてきた人たちだ。誰かに任命されたのではなく、有用な研究を発表し、その分野を知る人たちの検証を経て資格を得てきた

      アルゴリズムは公開され、レビューされ、公に攻撃され、改善され、標準化される。密室で行われているわけではない。論文も公開され、コードも公開されている。いつでも見られる。あなたが見ていないからといって、誰も見ていないわけではない。人々は中身を調べ、破ろうとしている。私たちが使うのは、攻撃に耐えてきたからだ

      Heartbleedを見て出す解決策が、OpenSSLを自分で再実装することなら、あなたの作るOpenSSLには本物のOpenSSLのHeartbleed1件につき50件のHeartbleedが入ると断言する。違いは、本物のOpenSSLは分かっている人たちがレビューし、テストし、監査し、攻撃し、修正することだ。あなたのものは、非公開のまま間違った状態で残るだけだ

    • 要点は、AESを平然と呼び出せる完璧な専門家がいるという話ではない。安全に動く人気のラッパーを使えば、バグが出ても1か所で見つけて修正できるということだ

      新しいサイドチャネル攻撃が見つかっても、1か所で対処できる。自作のものは、新しい攻撃を追い続けることに専業で時間を使わない限り、そうした改善を得られない

  • これはWebの道具をひどく使う人たちへの不満に近い。自前実装が妥当なユースケースまで扱っていれば、もっと面白かっただろう。そうすれば読者は、「絶対に自前でやるな」という幼稚なモデルではなく、役に立つことを学べたはずだ

    熟練とは、自分で作る知識と技術を持ち、同時に、いつそうしないべきかを知る知恵を持つことだ

    それでも不満には共感する。私にも似た不満は多かった。問題は、WebインタラクションをWeb開発者が簡単に参照できるほど徹底的かつ包括的に文書化しようとする努力があまりなかったことにある。プログラミング隣接知識が適切に文書化されず次世代へ引き継がれない深刻な問題があり、そのせいで同じ問題を何度も再発見することになる。普通は業界の中で標準的な動作やインタラクションの束が勝ち残るが、誰もそれを書き留めない