web-dev-qa-db-ja.com

Firebug / Chrome Dev Toolsを介してユーザーがパスワードを見つけられないようにする

Hidden Password

パスポート入力フィールドの場合:

<input type="text" required="" tabindex="2" class="std_textbox" placeholder="Enter your account password." id="pass" name="pass">

<input type="password"><input type="text">に変更すると、パスワードが明らかになります。これは、パスワードを保存したシステム、またはパスワードマネージャから生成されたシステムでは危険な場合があります。

Revealed Password

ここでクライアント側の暗号化を使用できますか?どのように実装できますか?

23
Manoj Kumar

短い答え:残念ながらそれを防ぐことはできません。これは、すべてのクライアント側コード(JavaScript)がクライアント自体によって変更可能であるため、クライアントベースのセキュリティシステムが脆弱になるためです。

私が考えることができる唯一の実行可能な解決策は、生のパスワードではなく、パスワードのhashed表現を格納することです。これにより(ハッシュブルートフォース攻撃を無視した場合)、未加工のパスワードが安全に保たれます。

ハッシュは元のテキストの表現であり、元に戻すことはできません。つまり、元の文字列は、ハッシュのみを使用するアルゴリズムでは取得できません。ハッシュの例は、MD5とSHAです。この手法は、ルーターでよく使用されます。ルーターでは、パスワードがブラウザーに保存されることがよくあります。

説明:パスワードをプレーンテキストで保存しないでください。また、この事前入力パスワードの手法を採用する場合は、ハッシュや暗号化はサーバー側で行う必要があります。

21
Eric

私はさまざまな答えで解決策を見ました。それらのすべてにおいて、パスワードを見るのはもっと難しいですが、それは誰かがそれを見るのを妨げません。

:クライアント側では、JavaScriptオブジェクトを操作および検査できます。他の回答で提供されているソリューションでは、パスワード情報に簡単にアクセスできました。


他の人が述べたように、ユーザーがクライアント側の開発者ツールを使用してパスワードを表示することを防ぐことはできません。

ユースケースは考えられませんでしたが、自動フォームフィラーRemember meオプションについて言及しました。

自動フォームフィラー、私の知る限り、マスターパスワードで保護されています。彼らはする必要があります;安全にスイッチをオンまたはオフにできない場合は使用しません。この場合、私がコンピュータを共有している状況にいるときはいつでも、ログアウトするのが私の責任です。

Remember meオプションは、Webサイトで頻繁に宣伝されているように、それが個人のコンピューターであり、デバイスを他の人と共有することを想定していない場合にのみ使用してください。それを使用したり、他人があなたのアカウントを使用しないようにしてください。繰り返しますが、それはあなたの責任です。

今でも、そのような攻撃を防ぐ必要があることに気付きました。私が思いつくことができるすべては以下です:

  1. クライアント側に実行可能なソリューションはありません。したがって、ソリューションはサーバー側で機能する必要があります。
  2. サーバー側では、関数を暗号化またはハッシュできます。詳細は この質問 を参照してください。これについては、この回答の残りの部分で詳しく説明します。どちらのソリューションも選択できますが、実装は異なります。

暗号化を使用する場合は、いつでも復号化できます。

これは、次のシナリオで役立つ場合があります。パスワードは常に暗号化してください。それらは常に一致している必要があります。ただし、ユーザーがパスワードを変更する場合は、クリアテキストになります。ユーザーは暗号化された形式で入力することはできません。あなたはそれを解決しなければなりません。解決策があります。きっと理解できると思います。

(暗号化)ハッシュを使用する場合、それはクラックするのが非常に難しい )。復号化することはできません。

これは、次のシナリオで役立つ場合があります。サーバーはハッシュバージョンのみを送信します。このようにして、攻撃者はこの情報を使用できません。それに応じて設計する必要がありますが、あなたもそれを理解していると思います。

とはいえ、要件に適したユースケースは実際には見当たりません。

その理由を説明させてください。ユーザーがパスワードを覚えているか、自動フォーム入力機能を使用している場合に、攻撃者がパスワードを見るのを防ぎたいとします。攻撃者がユーザーのコンピュータにアクセスできる場合、単純にログインすることができますが、なぜパスワードがわからないのですか?

グーグルやフェイスブックのような会社があなたのユースケースのためのソリューションを持っていなかった理由があります。は別の道を進み、2要素認証によってセキュリティを強化するためにプッシュしようとしました

それを使用できる場合は、それを実行してください。問題を完全に解決するわけではありませんが、セキュリティの向上が期待できます。特に攻撃者にとっては困難です。

8
Ely

クライアントサイドであるため、これを防ぐための実際の方法はありません。セキュリティモデルに関しては、クライアントを信頼することはできません。ただし、その一方で、サードパーティのデバイスを使用せずにこれを異なる方法で実装する実際の方法はありません。

サードパーティのデバイスに認証を支援させる問題に対処するつもりなら、ウェブサイトでランダムシードを生成して表示し、デバイスにシードとパスワードを要求してハッシュを生成し、サイトで認証してもらいます。ハッシュ。もちろん、ハッシュはWebデバッガーを使用する場合でも表示されますが、ハッシュはセッションごとに異なるため、少なくとも保存/読み取りする意味はありません。ちなみに、この方法はプレーンテキスト攻撃を選択する傾向があるため、これも完全に安全ではありません。

あなたがこのすべての問題を通過することをいとわないなら、称賛。このアプリを書いて、スマートフォンの機能をサードパーティのデバイスとして使えると思います。

4
Chavez

まあ、それは現在の技術では不可能です。他の人が述べたように、クライアント側のすべてのコードを検査して、DOMを操作することができます。

他の解決策は、銀行ログインのように実装することです。ユーザーがログインするたびにパスワードシーケンスをランダム化します。たとえば、パスワードの長さが10の場合、ユーザーに3つのパスワードフィールドを与え、パスワードのシーケンスを尋ねます。 3、5、10。これは、ユーザーがログインしようとするたびに変わります。そして、サーバー側でそれらを比較します。

3
Tom Marulak

あなたが直面している問題は、同じコンピューターを使用している複数の人であると考えています。1人のユーザーがサイトにパスワードを保存した場合、同じpcでサイトにアクセスする他の誰もがフィールドを操作してパスワードを明らかにすることができます。

これを防ぐ1つの方法は、オートコンプリートを無効にすることです。 autocomplete="off"このコードをinput要素に配置すると、パスワードが保存されていても表示されません。 <input autocomplete="off" type="text" required="" tabindex="2" class="std_textbox" placeholder="Enter your account password." id="pass" name="pass">

長所
ユーザーがコンピュータを共有していることや、パスワードが大部分明らかにされることを心配する必要はありません。
短所
ユーザーは自分のパスワードは保存されていると考えているかもしれません(ただし、パスワードを保存することはできます)が、サイトにアクセスしても表示されません。
[〜#〜]注[〜#〜]これは、ユーザーがフォームを操作するのを防ぐ完全な方法ではありません他のユーザーのパスワードを取得します。

補足として、パスワードとユーザー名を入力してもサイトが更新されない場合、Webブラウザーはパスワードの保存を要求しません。たとえば、フォーム送信の代わりにajax呼び出しを使用します。

JavaScriptを使用して、ページが読み込まれたときにパスワードフィールド内のテキストを消去できます。より良いスタイルは、次のようにJavaScriptでページが読み込まれるときにフィールドを追加することです。varx = document.createElement( "INPUT"); x.setAttribute( "type"、 "password");

Autocomplete = "off"の代替 ​​autocomplete alternative バックエンドから名前を生成し、それをフィールドの名前として使用することで、オートコンプリートがユーザーの保存データをどこに置くかを決して知らない

3
Jacob Finamore

絶対違う。エンドユーザーが開発者ツールまたはFirebugから[〜#〜] dom [〜#〜]を操作するのを防ぐことはできません。

クライアント側のトリックを使用しても、ユーザーがそうすることを防ぐことはできません。ブラウザーがユーザーの操作を制限するまで、またはそれを行わない限り。

3
naim shaikh

できません。できません。これは、Webサイトで取り組むべきセキュリティ上の問題ではありません。パスワードを安全に保つのはユーザー次第です。開発コンソールを使用したり、ページにJavaScriptを挿入したりできる場合、ユーザーが何をしても、ユーザーのパスワードは危険にさらされます。

ユーザーが自分のパスワードをブラウザーに保存することを選択した場合、ユーザーの手に渡るのを防ぐのはユーザー次第であり、サイト上でそれに対してできることはまったくありません。実際、Chromeを使用していて、パスワードを保存している場合は、chrome:// settings/passwordsに移動して、いくつかのパスワードフィールドをクリックします。

他の回答はパスワードのハッシュなどについて話します。それはあなたが間違いなくやるべきことですが、あなたのサーバー上でです。もちろん、パスワードをサーバーに送信する前にハッシュ化または暗号化することもできます(実際にはhttpsを使用する必要もあります)が、それはまったく別の問題です。

2
Schlaus

まあ、できません。

しかし、再び。もちろん、開発者コンソールを使用してユーザーに表示されないようにする方法が1つあります。パスワードのあるINPUTフィールドを表示しないでください。

別の方法としては、フィールドの動作をエミュレートして、そこにあるように見えてもそうではないようにすることです。私はまだ技術的に健全な解決策を見つけていませんが、それをどのように行うことができるかを以下に示します:(更新済み) http://jsfiddle.net/858kef4h/

この例では、アイデアは、パスワードINPUTのように見え、ユーザーからのキープレスをリッスンし、値をJavaScript変数に保存するDIVベースの疑似フィールドを作成することです。

<div class="pwField">
  <div class="pwData"></div>
  <div class="cursor"><div class="tfarea"></div></div>
</div>

この単純なハックには、パスワード、フォーカス状態、および隠しテキスト領域の3つの状態変数があります。

var pw = "", bHasFocus = false, tfArea;

JavaScriptを使用して「カーソル」クラスをオン/オフに切り替えて、実際のカーソルをエミュレートします

setInterval( function() {
   $(".cursor").toggleClass("blink");
},600);

Divをクリックすると、カーソルの位置にテキスト領域が作成され、それにフォーカスが移動します。

$(".pwField").on("click", function() {
    // enable cursor and create element if needed
    $(".pwField").addClass("active");
    if(tfArea) { // if already created, just focus to the field
        tfArea.focus(); 
        bHasFocus = true;
        return;
    }
    tfArea = document.createElement("textarea");
    tfArea.value="";
    $(".tfarea").append(tfArea);
    tfArea.focus();   
    bHasFocus = true;
    $(tfArea).on("blur", function() {
        // disable cursor and exit
        $(".pwField").removeClass("active");
        bHasFocus = false; 
    });
});

次に、キーアップ/キーダウンを聞いて値を記録できます

$(document).keydown(function(  ) {
    if(!bHasFocus) return;
    pw = tfArea.value;
    // print asterisks
    $(".pwData").html( asterisks( pw.length ) );
});

そして、ログインの準備ができたら、値は「pw」変数にあります。

この動的に作成されたTEXTAREAは、パスワードマネージャーが期待するINPUTフィールドではないため、自動パスワードマネージャーに気付かれない可能性があります。

フィールドを編集するユーザーは、Chrome開発者ツールを使用してこの要素の値を自然に検査できますが、ここでのポイントは、PWマネージャーがそのフィールドをパスワードと見なさない場合-フィールド前のユーザーのパスワードが入力されていません。

これを使用することはお勧めしません。これは単に好奇心から作られました。アイデアは、ユーザーに表示されないようにすることはできませんが、要素については、パスワードマネージャから結果を非表示にできる場合があります。しかし、古いことわざのように、「一部の時間にそれらのいくつかをだますことができますが、すべての時間ですべてではない」

ユーザーエクスペリエンスは標準入力の場合と同じではありませんが、改善される可能性があります。 1つの問題は、パスワードが表示されないようにしたいと思っていても、それがユーザーが本当に望んでいることかもしれません。パスワードマネージャーを使用することもできます。しかし、この場合はとにかく運が悪いです。

また、ブラウザによっては、クリック、フォーカス、ぼかしに問題がある可能性があります。期待どおりにモバイルデバイスで動作しない可能性があります。この種のハックを使用する場合は、慎重にテストする必要があります。ユーザーが使用しているブラウザーの種類が正確で、JavaScriptが有効になっていることがわかっている場合に使用できます。

編集:一部のモバイルデバイスでこのアプローチをテストしましたが、いくらか機能するように見えましたが、iPadでは、非表示のテキスト領域を配置しても、カーソルを表示してズームを変更すると、非表示のテキストエリアが疑似カーソルDIV内に配置され、ズームがそれに追従するはずです。

2
Tero Tolonen

単純なJavascriptコードを使用して、パスワード値を変数onblurに格納し、それをonfoucsまたは/およびonsubmitに復元できます。

次のデモコードとそのオンラインデモを見てください here

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
<script>
password = '';
function setPasswordBack(){
  showPassword();
}
function hidePassword(){
  p = document.getElementById('pass');
  password = p.value;
  p.value = '*********';
}
function showPassword(){
  p = document.getElementById('pass');  
  p.type= "password"; 
  p.value = password;
}
</script>
</head>
<body>
<form action="" method="get" onsubmit="setPasswordBack()">
<input type="password" value="" name="password" id="pass" onblur="hidePassword()" onfocus="showPassword()" />
<input type="submit" />
</form>
</body>
</html>

ソリューションがJavaScript依存のソリューションであることは明らかです。そのため、JavaScriptを無効にする場合は、noscriptを使用して、JavaScript対応のブラウザーを要求できます。

2
SaidbakR

すでに述べたように、input要素にパスワードを含めると、ユーザーはパスワードを簡単に明らかにできます。

...そして、@ Elyasinが尋ねるように、あなたは本当にあなたのユースケースが何であるかを私たちに知らせるべきです。

ユースケースが暗闇の中で、ユーザーが有料で購読できるWebサイトがあり、1人のログインを共有する複数のユーザーが購読料の支払いを回避したくないと仮定します。

ユーザーがサイトにサブスクライブしていることを確認するためにCookie認証を使用する場合があります。

  1. 新しいユーザーがサブスクライブするときに、Webサイトの特別な登録ページへのリンクを含むメールを送信します。

  2. ユーザーがそのリンクをたどったら、有効なサブスクライバーであることを示すCookieをユーザーのコンピューターに配置します。

  3. サイトにランディングページを作成します。このランディングページは、ユーザーのコンピューターからCookieを読み取り、実際に有効なサブスクライバーであることを認証します。

  4. サイトの他のすべてのページでは、ユーザーが検証用Cookieを持っていない場合、ユーザーをランディングページにリダイレクトする必要があります。

  5. サブスクライブしていないユーザーはランディングページにリダイレクトされる可能性があるため、ランディングページでサブスクライバーになることを提案する場合があります。

  6. サブスクライブしたユーザーのサブスクリプションの有効期限が切れている場合、次回ユーザーがサイトにアクセスしたときに、(現在はサブスクライブしていない)ユーザーのコンピューターからCookieを削除します。サブスクライブしていないユーザーと同様に、ユーザーをランディングページにリダイレクトします。

Cookieが傍受または盗まれる可能性があることは事実ですが、通常、それは通常のユーザーの能力を超えています。

Cookieを使用してセキュリティを強化したい場合は、ユーザーが最初にサブスクライブするときにユーザーのIPアドレスをキャプチャできます。次に、ユーザーが検証用Cookieを持っていること、およびユーザーが最初にサブスクライブしたのと同じIPアドレスからアクセスしていることを確認できます。もちろん、これにより、サブスクライブが元のIPアドレスのみを使用してサイトにアクセスするように制限されます。

2
markE

注:ブラウザの基本的な機能が損なわれるので、これは避けてください。

しかし、主張する場合は、入力を別の入力フィールドに「委任」し、ランダムな文字をパスワードフィールドに入力することで、誰かがパスワードを明かすようにharderにすることができます。

以下は、そのための1つの方法の例です。 prevent誰かがリクエストの本文から直接パスワードを取得したり、「隠された」デリゲート要素を見つけたりしないようにしてください。

!function() {

    var passwordEl, delegateEl;

    function syncPassword() {
        passwordEl.value = 
            Array(delegateEl.value.length + 1).join('*');
    }

    function createDelegate() {
        delegateEl = document.createElement('input');
        delegateEl.style.position = 'absolute';
        delegateEl.style.top = '-9999px';

        delegateEl
            .addEventListener('keyup', syncPassword, false);

        document.body.appendChild(delegateEl);
    }

    window.addEventListener('load', function() {
        passwordEl = document.getElementById('passwordId');
        createDelegate();

        // steal the focus from the password input
        passwordEl.addEventListener('focus', function(e) {
            e.preventDefault();
            delegateEl.focus();
        }, false);

        syncPassword(); // clear if was auto completed

    }, false);
}();

これで、フォームの送信時に正しいパスワードでパスワード入力を再入力するか、委任されたフィールドからパスワードが届くことをサーバーに期待するかを選択できます。

必要に応じて、デリゲートフィールドがフォーカスされているときにパスワードフィールドに適切なスタイルを追加して、ユーザーがパスワードフィールド自体にまだフォーカスしているような印象を与えることができます。

しかし、しないでください。

2
Peleg

この質問の前提は、クライアントコンピューターが危険にさらされており、アクセスを許可されていないユーザーによって使用されていることです。各ログインフォームの自動入力の前にマスターパスワードを必要としないパスワードマネージャー(Chromeなど)が使用されていると想定すると、攻撃者がアカウントにアクセスできないようにする方法はありません。

アクセスの問題がそれよりも深い場合、アプリケーションレベルで問題を解決しようとしています。

ボブが自分のコンピューターからログアウトするのを忘れたとします。攻撃者(Eve)が開いているWindowsセッションに遭遇し、自分のPaypalアカウントにアクセスしたいと考えています。 Bobは、Gmail、Paypal、Redditアカウントなど、複数のアカウントにパスワードマネージャを使用しています。 Paypalがアプリケーションレベルの予防策を講じて、Eveがパスワードマネージャーの自動入力からBobのパスワードを学習できないようにしたとします。 Eveは、Bobが戻るまでの間、BobのPaypalアカウントを制御することしかできないと考えています。しかし、その後、EveはPaypalのパスワードリセットリンク機能に気づきました。ボブのメールアカウントもパスワードマネージャーにあるため、侵害されます。イブはボブのメールアカウントにアクセスできるため、ボブのパスワードをリセットできます。彼女はボブのコンピューターにキーロガーをインストールすることでアクセスを維持することができました。

結論として、対処しようとしているセキュリティ上の懸念は、対処する力を超えています(従来のユーザー名とパスワードのモデルを想定)。アプリケーションについて何も想定していなくても、イブはボブのコンピューターに物理的にアクセスできるため、ボブはさまざまな方法でコンピューターを危険にさらす可能性があります。

ユーザーに2要素認証を使用させる(Twilioを介してテキストメッセージでコードを送信する)場合は、ハードウェアUSBキーなどを持ち歩くようにします。セキュリティを強化し、手元にあるパスワードマネージャーの問題を回避できます。

しかし最終的には、セキュリティと使いやすさのトレードオフに直面します。ボブがPCからログアウトするのが面倒/物忘れ/無関心/無関心である場合、あなたが書いたJavaScriptの量で彼を救うことはできません。

1
Kevin Dice

まあ、2019年にはトリッキーな方法があります.. divでJavaScript/jQueryを使用してフォームを生成し、それらを読み取り専用に置くことができます。攻撃者がJavaScriptを無効にすると、genコードは機能せず、どのフォームにもならないでしょう...

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <title>Basic security for mr. Hacker</title>
 </head>
 <body>
 <div id="ticketAF0122"></div><!-- it is assumed that id is generated every time !!!  -->
 <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
 <script>
    $(document).ready(function(){
        function readonly(){
            $('div#ticketAF0122').html('My password<form method="post" action=""><input type="password" name="password"><input type="submit"></form>');
        }
        readonly()
        $('div#ticketAF0122').bind("DOMSubtreeModified", function(){
            readonly();
        });
    });
    /*

    Basicly you can load this part from an encoding external php file:
    <script src="page.php?ticket=ticketAF0122">< /script>

    and the php file generate something like:
    $(document).ready(function(){
        function readonly(){
            $('div#ticketAF0122').html('My password<form method="post" action=""><input type="password" name="password"><input type="submit"></form>');
        }
        readonly()
        $('div#ticketAF0122').bind("DOMSubtreeModified", function(){
            readonly();
        });
    });

    */

 </script>
 </body>
</html>

私はすでにこれをxampp/windows 10でfirefoxでチェックし、インスペクターでtype = "password"からtype = "text"に変更すると、スクリプトは再び「修復」します

エッジでは動作がバギーです:インスペクターで私がそのものを変更すると、すべてのフォームがストリップされ、htmlドキュメントの上に挿入されます

0
Constantin