0

私のクライアントのサイトは、それらのサーバーがテストに合格すると、IPごとに顧客に証明書を提供します。この認定は、テストされたIPにのみ有効です。したがって、証明書を表示しているサイトが実際にテストされたことを検証できるように、証明書を提供するのは私たちである必要があります。したがって、顧客のユーザーが証明書へのリンクをクリックすると、そのサイトが実際に私たちによってテストされたと信頼できます(サイトは私たちによってテストされていない別のサーバーによって提供されていませんが、そうであると主張しています) 。

ユーザーは、次のようなリンクを介して当社のサイトに誘導されます。

siteB.com/certificate.php?companyid=1234&serverid=4321

簡略化されたプロセス:

  • ユーザーはサイトAにいます
  • ユーザーが自分のサイト(サイトB)に移動するリンクをクリックして、サイトAの証明書を表示します。
  • 私のサイトであるサイトBは、サイトAが取得した証明書を表示しようとしているのが実際にサイトAであることを検証する必要があります。

当初、$ _ SERVER変数には参照元サーバーが誰であるかを示す値があるのではないかと思いましたが、それに関する質問を投稿したときに受け取った回答は、その情報が$ _SERVER ["HTTP_REFERER"]に格納されているが、そうではないことを示していました。信頼できません(プラグインまたはユーザーがこの値を変更する可能性があります)。

私はそれに頼ることができないので、参照元のサーバーが彼らが主張する人物であることを検証する別の方法が必要です。使い捨てトークンの使用を検討しましたが、有効なサーバーは、顧客が所有する他のサーバー(テストされていない)にトークンを循環させるだけで、顧客は任意の数のサーバーが認定されていると主張できます。 1回のテストの価格で(証明書の整合性を損なうだけでなく)、私たちが作成します。

この問題を確実に解決することは不可能かどうか疑問に思っています。実行できる最善の方法は、制御されていないエンドポイント(顧客のサーバー)が証明書であることを示すためのキーを投稿する手段を難読化することです。 (たとえば、卑劣な顧客は、システムをだますために、厄介な難読化されたjavascriptを読むか、クローズドソースのクライアント側プログラムを分解する必要があります)。

これまでの私の考えはこれです(そしてそれはひどいです):


クライアント側を実行するためのクローズドソースプログラムを作成する必要があります。おそらく、顧客のWebサイト(サイトA)の証明書リンクをクリックすると開始されるネイティブクライアントを介して、最初に自分のサイト(サイトB)で検証されます。 )次に、サイトAのサーバー、サイトBのサーバー、およびユーザーとの3方向の通信回線を開きます。この場合、サイトBは、サイトAが本人であることを検証し、証明書または証明書を読み込めなかった理由(接続がタイムアウトしたなど)を示すエラーメッセージ。

ユーザーNaClプログラムへのオープンストリームを持つサイトBのスクリプトは、curlを使用してサイトAのサーバーのIPアドレスを取得し、検証します。


私にとって、これは非常に大雑把な解決策です(それが解決策であるとしても)、ほとんどのユーザーは誰かの証明書を見ることを気にしないでしょうが、気にかけるユーザーはフープ(NaClプログラムのインストールと実行)を通過させます証明書を見るのはただの狂気です。

これは少しばかげた質問のように感じますが、代わりにこれをフラッシュとして実行することは、NaClプログラムを実行することと同じくらい安全/危険ですか?

確かに、これをすべて行うためのより良い方法があります...

4

2 に答える 2

2

最善の策は、REFERERを信頼するか、ORIGINヘッダーを使用することです(ORIGINを使用するには、サイトにドロップできるAJAXスクリプトをセットアップする必要があります)。

サーバーが受信するものはすべて、クライアントコンピューターによって簡単にスプーフィングされる可能性がありますが、アクセスしているサーバーによってはスプーフィングされません(クライアントの同意なしに)。あなたのサービスはクライアント向けのようですので、クレデンシャルを偽造する理由はありません。特定のプラグインとプロキシで潜在的な問題が発生する可能性がありますが、警告メッセージでそれを説明できます。

クローズドソースのクライアント側コードのようなものはありません。誰でも簡単に逆コンパイルしたり、ランタイムをエミュレートしたりできるので、セキュリティを強化する必要はありません。

公開鍵/秘密鍵も機能しません(サイトはエンコードするものを生成します。問題のサーバーは秘密鍵を使用してエンコードする必要があり、クライアントは公開鍵を使用してチェックします)。それらは依然として同じ問題に対して脆弱です。偽のサイトは、完全にコピーされたヘッダーとともに要求を実際のサイトに転送して処理する可能性があります。

覚えておくべきこと:

  • AJAXを使用すると、最新のブラウザーで保証されているORIGINヘッダーを除いて、クライアントサーバーでヘッダーを変更できます(ただし、クライアントが作業を行うことで変更できます) 。
  • 標準のURLリクエストには、ブラウザによって生成されたすべてのヘッダーがあるため、信頼できます(クライアントのみが変更できます) 。
  • クライアントコンピューターに送信されるコードまたはシークレット(コンパイル、難読化など)は、パブリックと見なす必要があります。
  • ブラウザからのものではないリクエストは、IPアドレスを除いて、あらゆる点で偽造される可能性があります(さらにはプロキシされる可能性もあります)
于 2013-03-05T01:41:31.907 に答える
1

私の考え..可能であれば、証明書発行サーバーに、hashその参照サーバーの名前とsalt、ユーザーのIPアドレスを使用するなど、動的であるが予測可能な方法で生成される別の一連の基準に基づいてCookieを作成するように依頼します。プラス曜日を指定し、時間数または現在の分数を入力することもできます(基準の期間が短すぎると、誤検知認証が失敗する可能性があるため、注意してください)。次に、ユーザーがサイトに到着したら、Cookieのハッシュを読み取り、$_SERVER[“HTTP_REFERER”]事前に確立された基準から生成されたものと比較します。これの欠点は、参照サーバーがディックスになりたい場合に安全なアルゴリズムを公開できることです。

もう1つのより安全なオプションは、サーバーにAJAX呼び出しを送信し、サーバーが上記と同じ種類の基準に基づいてハッシュを返す参照サーバーに提供するJavaScriptアプリを作成することです。その後、Cookieは、返されたハッシュに基づいて参照サーバーによって設定され、AJAXサイトにアクセスすると、前述したのと同じ方法でチェックされます。ただし、すべての処理はサーバー上で行われるため、完全に安全です。かっこいいプロジェクトのようですね。頑張ってください。

于 2013-03-05T00:36:08.340 に答える