web-dev-qa-db-ja.com

クライアント側のコーディング:悪意のある使用を防ぐ方法は?

ここ数年で、クライアント側(ブラウザ)アプリケーションの傾向は本当に顕著になりました。

私の最新のプロジェクトでは、時代とともに動き、クライアント側アプリケーションを作成することにしました。

このアプリケーションの一部には、トランザクションメールをユーザーに送信することが含まれます(たとえば、サインアップの検証、パスワードリセットメールなど)。サードパーティのAPIを使用してメールを送信しています。

通常、アプリケーションはサーバーで実行します。サーバー上のコードからサードパーティのAPIを呼び出します。

クライアント側のアプリケーションを実行するということは、これをユーザーのブラウザーで実行する必要があることを意味します。サードパーティのAPIは、これを実現するために必要なJavaScriptファイルを提供します。

私が目にする最初の明白な問題は、APIキーを使用する必要があることです。これは通常、サーバーに安全に格納されますが、おそらくクライアントブラウザーにこのキーを提供する必要があります。

私がこの問題を回避できると仮定すると、次の問題は、技術に精通したユーザーがブラウザーでJavaScript開発者ツールをロードし、アプリケーションで設定したルールに固執するのではなく、ブラウザーAPIを好きなように使用できなくなることです。 。

私の一般的な質問は、クライアント側アプリケーションの悪意のある使用をどのように防ぐことができるのでしょうか?

60
Gaz_Edge

できません。これを理解する人が増えるほど、理解が深まるほど、世界にとって良いことになります。

ユーザーの制御下にあるデバイスで実行されるコードは制御できません。スマートフォンは脱獄することができます。セットトップボックスは割れることがあります。通常のブラウザは、JavaScriptコードへのアクセスを阻止しようとさえしません。盗んだり悪用したりする価値のあるものがあれば、断固とした攻撃者がサーバーサイドを大事にするすべてを検証しない限り、それを実行できます

難読化はほとんど役に立ちません。離れたところにある金銭的なものが関与するとすぐにあなたが引き付ける種類の相手は、クラシファイド広告のようなアセンブリ言語を読みます。キーを保護するデバイスはクラックされていると想定する必要があるデバイスと同じであるため、暗号化は役に立ちません。同様の理由で、機能しない他の多くの、一見明白な対策があります。

残念ながら、これは非常に不便な真実です。世界は、リモート信頼の根本的な破綻をどうにかして回避できると考える小規模および大規模のオペレーターでいっぱいです。それは単にoh so Niceコードが想定どおりに実行されると想定できる場合。そして、はい、それはすべてをとても簡単にするので、面白くさえありません。しかし、願いはそうはいきません、そして、あなたがあなたとあなたのクライアントを焼くだけであるという不快を避けることができる一つの賢いクッキーであるという希望に逆らうことを望みます。したがって、インターネットは敵の領土であることを頭に入れ、その追加コストを見積もりに含めれば、大丈夫です。

とはいえ、もちろん、防御の深さといったものもあります。 JavaScriptを難読化しても、断固とした攻撃者を先送りにすることはできませんが、決定力の低い攻撃者を先送りする可能性があります。資産が保護するのに十分な価値があるが、費用はかからない場合、これらの手段のいずれかがシステムにビジネス価値を追加する可能性があります。完璧にはなりません。あなたがしているトレードオフを完全に認識している限り、それは合理的な戦略かもしれません。

200
Kilian Foth

ここでのルールは:

ユーザーが改ざんした場合に他のユーザーに影響を与えないクライアント側のすべてのことを行います。特に、それはグラフィック効果を意味します。

安全にする必要があるすべてのサーバー側を実行し、クライアントからUIイベントを送信するだけです(たとえば、サーバーが実際にトランザクションを実行している間、クライアントは「ユーザーが[購入]ボタンをタップしました」と言うだけです)。特に、それは金融取引を意味します。

69
jhocking

これは、完全にクライアント側のアプリケーションにすることがnotである場合に当てはまります。

フォームのロジックと基本的な検証をクライアント側にして(誰かがリクエストを偽造しようとする可能性があるため、サーバーで再検証する必要があります)、応答性を向上させることができます。ページ装飾などの再送信は避けてください。ただし、トランザクション自体を認証および承認する必要がある場合は、サーバー上で実行する必要があります。

28
Jan Hudec

あなたの真ん中の段落は問題の核心です:

クライアント側のアプリを実行するということは、これをユーザーのブラウザーで実行する必要があることを意味します。サードパーティAPIは、これを実現するために必要なjsファイルを提供します。

クライアント側のアプリでサーバー側の作業ができないのはなぜですか?クライアント側プログラミングへのプッシュは、サーバーを排除することではなく、ブラウザーが最終的にサポートする新しいテクノロジーを活用してユーザーインターフェイスを改善することです。

.js受け取ったファイルです。ブラウザ向けですか?それはnode.jsライブラリですか?

17
Brandon

これから一歩下がって、より高いレベルの調査をしてみましょう。EudoraまたはOutlook(クライアント側のアプリで、ブラウザーを必要としない)が、企業に経済的損失を引き起こしたことはありますか?いいえ、誰でもPOP/SMTP APIに書き込み、クライアントになることができます。しかし、サーバーへの損失はありません。サーバーは、クライアントのアクション、計算、ストレージ、温度、ディスクサイズ、RAMサイズを制限せず、クライアントのDPI、GPU、FPUを監視しましたが、それに対する応答を正確に指定しました。銀行への侵入にQuickenやMS-Moneyが使用されていることを聞いたことがありますか?

ブラウザー(クライアント側)アプリでも同じアーキテクチャを使用できます。

  1. APIを使用してサーバーを構築します(BTWは常にGET POST HEADなど)の派生物に要約されます)。
  2. サーバー上で、APIが、すべての呼び出しについて、認証され、IDが検証されたクライアントとのみ通信することを確認します。
  3. 次に、クライアントが誰であるかを気にしません。
  4. そして、それがブラウザ、ジェイルブレイクされたデバイス、Google Glass、DOS 3.1、または2014年に移動してすべてを逃してしまったテクノフォーブgreat-great-great-great-grandpaの手に渡った真新しいNexusであるかどうかは気にしません過去15年間に私たちの生活を氾濫させてきたテクノロジー。
  5. これで、他のすべてをクライアント側にオフロードできるようになりました。

SoapBoxBegin

@KilianFothは、主にいつも見出しを読んでいるものの、アプリ、コード、雇用主、クライアント、自分の銀行口座にそれが起こるとは決して考えていない、素朴で無謀な人々に対して重要な認識ポイントを上げます。さらに無謀なのは、彼らの雇用主(特にCTO)で、管理されていない/管理されていない公開にシステムを公開するアプリを取得することを許可します。しかし、私はそれが「私たちは決して学ばない」と思われることに常に困惑しています。

SoapBoxEnd

要約すると、堅固でタイトなサーバー側APIを作成します。クライアントが処理できるものに基づいて、その他すべてをクライアントにオフロードします。

11
LMSingh

私はあなたが本当にできないと主張します。データをクライアントに送信する意思がある場合は、データが悪用されることを予期する必要があります-可能です。 APIキーに関するあなたの例は要点を説明するものであり、クライアント側のJSには含まれません-盗まれて悪用されます。

物事を安全に保つためには、まだある程度のサーバーコードが必要です。ログインしたユーザーに関連するデータのみを取得するだけの簡単なものでも。この認証はすべてクライアント側で実行できるわけではありません。そうでなければ、再び利用され、データは安全ではありません。

私は常にJSクライアント側のエクスペリエンスをサーバーコードへの追加であると考えています。クライアントでの検証は素晴らしいユーザーエクスペリエンスを提供しますが、POST受信側サーバーのデータも同様に確認しないと、攻撃の可能性が開かれます。クライアントからのすべてが容疑者と見なされます。

6
Matt Klinker

とても簡単です。クライアントコンピューターとその上で実行されているすべてのソフトウェアが、巧妙な悪意のあるハッカーの完全な制御下にあると想定します。

つまり、サーバーからクライアントに送信する情報はすべて悪意のあるハッカーに知られるため、サーバーまたはビジネスを攻撃するために使用される可能性のある情報をクライアントに送信しないようにする必要があります。

また、クライアントからサーバーに送信されるものはすべて悪意のあるハッカーによって生成されたものであるため、サーバーコードは、クライアントが送信できるものがサーバーを攻撃できないことを確認する必要があります。

確かに、実装は問題ですが、重要なのは精神的な態度です。サーバーが話していると思われる「クライアント」は、クライアントではなくアクティブな攻撃者であるという想定です。

(また、ユーザーがビジネスメソッドを攻撃しようとする賢いconmanであると想定する必要がありますが、クライアント側のプログラミングとは何の関係もありません)。

4
gnasher729

私の意見では、クライアント側アプリケーションは主にUIに関するものです。たとえば、すべてのUIシステムは一度クライアントに送信され、クライアントはそれを使って何でも行います。

通常、アプリケーションはサーバーで実行します。サーバー上のコードからサードパーティのAPIを呼び出します。

クライアント側のアプリケーションを実行するということは、ユーザーのブラウザでこれを行う必要があるということです。サードパーティのAPIは、これを実現するために必要なJavaScriptファイルを提供します。

APIキーがある場合、それはクライアント側で動作することを意図していません。クライアント側でAPIキーを指定すると、誰でもそのAPIキーにアクセスできるようになり、それを独自の目的に使用できます。それを保存し、クライアントが必要なときにサーバー側で使用し、Ajax/WebSocketsを使用して結果を送信します。

それはあなたの銀行が言っているようなものです:「まあ、私はメインデータベースクライアント側のパスワードを入力して、クライアントが自分でそれを要求できるようにして、彼がもう私たちのサーバーを邪魔しないようにします。」

0
Depado