オンラインのリーダーボードphp/sqlの不正更新を回避

私はcordova(phonegap)を使用してアンドロイド用のオフラインWebアプリ(ゲーム)を開発しています。同じのリーダーボードは私のサーバーでオンラインで管理されています。

現在これがリーダーボードの更新方法です

ステップ1)ユーザーのスコアはオフラインアプリのローカルストレージに保存されます。

ステップ2)ユーザがインターネットに接続している「私のスコアを更新する」ボタンを押す。

Step 3) The button basically sends an ajax request to https://mywebsite.com/scoreupdate.php?userid=user_id&score=obtained_score

ステップ4)これに基づいてデータベースはscoreupdate.phpファイルによって私のサーバーで更新され、成功を返します。

これらは私が直面している問題です

1) Anyone can easily visit https://mywebsite.com/scoreupdate.php?userid=user_id&score=obtained_score if they know the user id (It can be easily obtained from the app's localstorage data) and he/she can update his/her score in the leaderboard simply by replacing obtained_score value with some high value to get a better position in leaderboard.

2)全体がJavascriptで構築されているので、アプリやlocalstorageに保存されている秘密の値は簡単に取得できます。アプリのリバースエンジニアリングも可能であるため、リクエストをサーバーに送信しているのが本人のアプリであることを効率的に認証する方法を見つけることができませんでした。

私の要件

1)アプリはscoreupdate.phpファイルが本物のアプリであり人ではないことを認証できる必要があります。アプリだけがリーダーボードを更新できるようになります。

2)認証のロジックは、単にアプリのソースコードを読むことによってユーザーによって解読されてはならない。 (例:ユーザーIDにいくつかの数字を掛けてサーバーで逆の処理をしてもうまくいきません)

これを達成するためのいくつかの方法はありますか?

Javascriptのスクランブルは、簡単にスクランブルを解除できるため、効果的ではありません。

編集

誰かがMITMまたはブルートフォースのような攻撃によってユーザーの資格情報を盗んでも、私は心配しません。プロファイルを所有している実際のユーザーでも、自分のスコアを更新することはできません。

5
いいえ、あなたははるかに少ないのために解決しなければならないでしょう。
追加された 著者 Neil Smithline,
たぶん@TTT。答えは質問よりも同じです。ありがとう!
追加された 著者 Neil Smithline,
GoogleはAndroidプラットフォームでいくつかのハイスコア機能を提供しています。あなたは彼らが持っているものを見ましたか?ルートを解除された電話では、OSを所有しているので、もっとうまくやれるかもしれません。彼らは根ざした電話には望みがないでしょう。しかし、それらを使用することで十分かもしれません。彼らは偽造などについて心配しましょう。
追加された 著者 Neil Smithline,
難読化を防ぐことはできませんが、難読化やデータへの署名など​​でそれを阻止することはできますが、物理的なセキュリティがなければセキュリティが確保されないことになります。あなたはモバイルデバイスの物理的な制御を持っていないので、あなたは運が悪いです。
追加された 著者 Neil Smithline,
@ニール - うん、同意した!
追加された 著者 rm-ass,
@NeilSmithline - この質問はあなたが提案した可能性のある重複とはかなり違うと思います。これは主にこの質問に対して2つの打撃があるためです。ここのクライアントはオフラインで、実質的にオープンソースです。しかし、その質問に対してあなたが与えた素晴らしい回答はなんでしょうか。誰もがそれを読みに行くべきです。
追加された 著者 rm-ass,
それは不可能です。ユーザーが誰かの代わりに スコアしか更新できないように認証を追加することもできます。 。
追加された 著者 André Borie,
@NeilSmithlineそれで不正行為を防ぐ方法はありますか?私もアーキテクチャを変更する準備ができています。
追加された 著者 mtv.vac,
@ NeilSmithlineその素晴らしい答えをありがとう。しかし、私の問題は少し異なります。私の場合、プロファイルを所有している実際のユーザーでさえ、自分のスコアを違法に更新することはできません。たとえば、自分のゲームにsandeepという名前のプロファイルがある場合、私のアプリは自分のスコアを更新できますが、自分自身が自分のスコアを変更することはできません。私はブルートフォースとMITMを気にしません。私はこの質問は棄権だと思います。ソースが開いているので誰でも私のアプリを複製して手動でローカルストレージに保存されているスコアを変更し、それが彼/彼女によって得点されたようにふりをすることができます
追加された 著者 mtv.vac,
@NeilSmithlineこれはベストプラクティスではないことを私は知っています。あなたは私に同じことを成し遂げるためのもっと良い方法をアドバイスできますか?リーダーボードを更新する必要があります。そしてだれもカンニングできないはずです。
追加された 著者 mtv.vac,
@NeilSmithlineこれは不可能ですか?
追加された 著者 mtv.vac,

5 答え

不可能だとは思わない。

ゲームの形態によっては、以下のスキームを適用することが可能かもしれません。

  1. ゲーム中に、RNGへのシードとユーザーからのすべての入力を含む開始状態を記録します。
  2. ゲームを送信するときは、セッションのこの「再生」を要求されたスコアと一緒にサーバーに送信してください。
  3. サーバーで、提供された入力を使用してゲームロジックを実行し、それが同じスコアになるかどうかを確認します。そうであれば、リプレイは有効であり、あなたはスコアを更新します。

このようにして、あなたは不正行為の問題をあなたのゲーム用のボットやソルバーを書く問題に効果的に変換しました。

基本的に、これは解を検証することが計算的に困難である一方で解を検証することがNP完全問題と見なすことができるどんなゲームにとっても非常に良い解決策です。その一例が倉庫番です。

7
追加された
あなたは本当に不正行為を防ぐのではなく、単にそれをより困難にします。だからあなたの最初の文は間違っています。
追加された 著者 Neil Smithline,
@TTTだからこそ、私は「あなたのゲームの形態に応じて」と書いた。それが書かれている言語はまったく問題ではありません。たとえば、SokobanをJavascriptで実装した場合、特定の一連の移動でレベルが解決されるかどうかを確認するのは簡単ですが、その一連の移動を見つけるのは計算上困難な問題です。
追加された 著者 deckoff,
これは不正行為を大幅に防止する有効な解決策だと思います。確かに、非常に決定的で熟練した詐欺師は、詐欺する説得力のある統計/ビデオを思い付くことができますが、これはおそらくほとんどすべての詐欺師を阻止するでしょう。ハイスコ​​アだけを誤って報告するよりも、明らかに不正行為をしたリプレイを作成することが非常に困難です。多くの場合、セキュリティでリスクを排除することはできませんが、リスクを大幅に減らすことができるため、これで問題ないと思います。私はまた、高得点と共にゲームのリプレイについて考えました(私はそれが前にやったのを見ました)、そしてここにそれを掲示するつもりでした。良いアイデア@Zeta Two。
追加された 著者 Jonathan,
あなたはすべての支持者をだました。ニールは正しいです。これはうまくいきません。サーバーが確認できる動きがゲームにあることをどのようにして知ることさえできますか?それはJavaScriptで書かれているので私はそれをしないと確信しています、それはあなたが勝ちを期待している動きを見るためにあなたがただコードを見ることができることを意味します。
追加された 著者 rm-ass,
@ ZetaTwo - わかりました。それは理にかなっている。私は実際に「あなたのゲームの形態に応じて」を見逃していました。ゲームがそのタイプのものであれば、これでうまくいくことに同意します。ランダムなゲームがその基準に合うことが起こるとは思いません。多分OPは私達にゲームが実際には何であるかを知らせることができます...
追加された 著者 rm-ass,
ちなみに、私は自分のDVを元に戻しました、そして、私は "みんなをだますこと"についての私のコメントを削除するつもりですが、私はコメントの継続のためにそれを残すつもりです。
追加された 著者 rm-ass,
それはいい方法です。しかし、ログ全体をサーバーに送信するのは面倒です。私は答えを高く評価し、私がよりよい解決策を見つけることができなかったならばこの方法を使うでしょう。どうもありがとう。
追加された 著者 mtv.vac,
とにかくログのためのパターンがあるでしょう、そして私は誰かがループかそのような何かを使用することによってそれを再生することができると思います。しかし、これは私のアプリにセキュリティを追加すると確信しています。
追加された 著者 mtv.vac,

いいえ、これは不可能です。

あなたは正確なデータを提供するためにクライアントに頼っています。しかし、あなたはそれをすることができません、クライアントがあなたのコントロールの外にいるので。これはユーザーのハードウェア上で実行されます。つまり、ユーザーは自分の好きなようにそれを変更することができます。クライアントが変更されていないことを認証しようとする試みは、クライアントマシンでも実行する必要があります。つまり、操作から保護されていません。

プレイヤーが不正行為をしないようにする唯一の方法は、すべてのゲームの仕組みを自分のサーバー上で実行することです。

6
追加された

オフラインアプリケーションでは、スコアを保存および更新するためにアプリケーションを変更することを強制するため、これを達成できません。オフラインのアプリケーションではこれを回避する方法はありません。

完全準同型暗号化を使用しても、オフラインアプリケーションは、元のデータが見えない場合でもデータを改ざんすることができます。

クライアントアプリケーションがスコア保持を担当している場合は、難読化による誠実さと欲求不満の不正行為の試みのみを期待できます。あなたは実際にそれらを防ぐことはできません。

不正行為の大部分に対処できる不完全な解決策は、調整されたベイジアンネットを使用して不正検出を実行することです。ゲームのプレイ状況の変化を評価し、変化を低、中、高のバケットにスコア付けしてから、ベイジアンネットを使用して結果を単一のリスクスコアに融合します。これはかなり洗練されており、絶対確実なものではありませんが、アプリをオフラインにする必要がある場合は選択肢になるかもしれません。

あなたがそれをオンラインアプリケーションにすることができれば代わりにあなたは不正行為を防ぐことができるあなたの管理下にあるサーバーにルール管理とスコアキーピングを移動することができます。それでも、クライアントがユーザー入力イベント以外のものを送信できる場合は、やはりややこしいプロセスです。

3
追加された
@TTT良い点です。その警告を明確にします。
追加された 著者 Jonathan Hartley,
それは動作することができます@TTT。職場では非常にうまく機能しますが、調整には数年かかります。
追加された 著者 Jonathan Hartley,
@TTTはネットが非常に洗練されていなければならない場所です。真に専門家や折衷的なゲーマーが偶然に捕らえられるような場合にも、誤検知を引き起こさないことは難しいでしょう。あなたはこれのために価値のあるネットを生成するために典型的なゲーマーデータをたくさん必要とします。オフラインでアプリをデプロイすることができなくなるため、ここでは絶対に「いいえ」と言っても気になりませんでした。
追加された 著者 Jonathan Hartley,
それは良い編集です。この場合、おそらくネットは「何もないよりはましだ」でしょう。
追加された 著者 rm-ass,
私が定義した「作業」は100%の精度です(この不正行為防止シナリオの場合)。もしあなたがあなたの詐欺検出アルゴリズムを時間をかけて(そしておそらくそれを越えて継続的に)調整する必要があるなら、私はそれがこの特定の問題に対する実行可能な解決策ではないと思います。
追加された 著者 rm-ass,
それで、言い換えれば、それは気にするのに十分にうまくいかないでしょう…あなたはただOPを簡単にさせたかったのですか?優しすぎ。 :D
追加された 著者 rm-ass,
あなたはベイジアンネットで私を失った。ネットの範囲内に収まるわずかに良いスコアを詐欺師が継続的に送信するのを止めるにはどうすればよいですか
追加された 著者 rm-ass,

すみません、できません。

一般に、あなたの要求が以下の通りであるならば:

  1. オフラインクライアントがあります。
  2. クライアントコードをオープンソースにするか、簡単に逆コンパイルできるようにします。
  3. クライアントが不正をしないようにする。

次に、[それらのうち2つを選択]をクリックします。

注:#2を変更して、簡単には逆コンパイルできないコンパイル済みコードを使用することにしたとしても、あいまいさによるセキュリティの犠牲になっています。暗号化キーをハードコーディングして、だれにも解明されないようにすることができます。また、ゲームが面白すぎる場合は十分ですが、お金が含まれている場合は違います。

変更する3の最良の選択肢は、オフラインクライアントを持たないことです。

警告:上記の3つの要件をすべて満たすことができる特定の種類のゲームがあるため、「一般的に」と述べました(たとえば、解決が難しい難しいゲームなど)。解決策はまだ広く知られていません)。この種の質問の詳細については、Zeta Twoの回答を参照してください。

1
追加された
上記のコメントで述べたように、これは通常そうですが、一般的には正しくありません。完璧な例:倉庫番。
追加された 著者 deckoff,
同意した。私は自分の答えを更新しました。それを指摘してくれてありがとう!
追加された 著者 rm-ass,

これを解決するための唯一の現実的な方法は、暗号化キーとソースコードがデバイスに埋め込まれているカスタムハードウェアを使用することです。

たとえば、暗号化されたDVDからゲームを読み取るビデオゲームシステムがあります。ビデオゲームシステム(システム上の読み取り専用メモリに存在する秘密のソースコードを実行している)は、(デバイスに埋め込まれた秘密鍵を使用して)ビデオゲームを復号化し、それが正当なソースから来たもので変更されていないことを検証できる。ビデオゲームのソースコード(検証済みのシステムが変更されていないこと、漏洩していないこと)の中に、オンラインリーダーボードにスコアを送信するときにユーザー名とハイスコアの組み合わせにデジタル署名するための秘密キーを含めることができます。

ただし、ユーザーにソースコードの表示と変更を許可すると、スコアが通常送信される直前に、ユーザーがソースを変更してハイスコアを任意の値に変更することができます)ユーザーが自分の動きを送信し、それらの動きがスコアと一致することをサーバーに確認させる方法もあります。

例えば、ゲームがX回以下の移動でパズルを解くことを含み、あなたがN番目のパズルを解くことを提出したい場合、あなたはあなたのゲームにあなたがした一連の移動を提出させることができます。手の移動は、N回目のパズルをX回以下の移動で解決し、サーバーのクロックで指定された時間に送信されたという解決策で構成されています。

0
追加された
@TTT - まず、サーバー時間とクライアント時間について、私が書いたことをもう一度読みます - 私達は同意しています。私はクライアントが提出した時間を信頼することについては何も言いませんでした。私はあなたがそれが与えられたスコアを生成するために働くためにサーバーのクロックによって与えられるようにそれが提出された時間を信頼するだけであると言いました。私はクライアントの時間やクライアントが時間を提出するのを見ることについては何も言いませんでした。たとえば、パズルが正午にリリースされ、あなたのリーダーボードは、サーバーが受信した時刻に有効な解決策を送信した最初の人で構成されています。
追加された 著者 dr jimbob,
第二に、私はこれがあなたが信頼できないハードウェア上で走ることができる完全にオープンなソースコードでモバイルゲームのために働かないであろうことに同意する。しかし、難しいが、信頼できる未修正のソフトウェアだけを実行する信頼できるハードウェアでこの問題を解決できると言う価値があると思う(そしてこれは、オンラインハイスコアがxbox、プレイステーションなどで実行されるビデオゲームにどのように働くかである)。そしてこれを妨げるものは何もない - 署名されたjavascriptアプリケーションだけを実行し、提出されたスコアにデジタル署名をする修正されたandroidを実行するハードウェアデバイスを誰かが設計することができる。
追加された 著者 dr jimbob,
(1)に関して、オフラインでプレイされる多くのゲームでは、プレイする前に新しいレベルをダウンロードする必要があります。これに関連してオフラインとは、プレイ中にインターネットが不要なことを意味します。 (2)いいえに関しては、変更されていないデバイスからスコアを受け取る必要はありません。それはあなたの信頼されたサーバーがそれらの動きによって生み出されたスコアをチェックするために提出された解決策を受け取ることをただ必要とします。たとえば、無作為化(ゴーストアクションはあなたの動きにのみ依存する)と離散的な動きのタイマー(例えば、動きはビデオゲームクロックの10分の1秒ごとにのみ登録される)を持たないPacmanクローンを書いたとします。
追加された 著者 dr jimbob,
プレーヤーが高得点を生み出す一連の移動をサーバーに送信すると、サーバーは、ゲームが完全にオフラインで行われた場合でも、それらの移動がプレーヤーに適切な高得点を与えることを確認します。確かにこれは、人間が実際にそれらの動きを実際のデバイスでプレイすることを発見したことを証明するものではありませんが、実際に信頼できるものがなければ人間によって行われたことを証明することはできません。裁判官は人間がゲームをするのを見る。 (そして、解決策の一部としてあなたのRNGの種を処理することによってランダム化を追加することができます)。
追加された 著者 dr jimbob,
私のコメントから、あなたの考えを推測した他の誰かの答えにコピーします。コードを見て、勝利に期待する動きを確認してください。」人間対AIに関して:私は、ゲームをプレイしているAIを割り引くことができると思います。
追加された 著者 rm-ass,
ゼータツーは、あなたの考えがうまくいくであろうNP-完了ゲームの例を示しました。投票を元に戻したいのですが、質問を編集するまではできません。あなたが考えている質問の種類を明確にしておくと役に立つでしょう。
追加された 著者 rm-ass,
私は2番目のコメントであなたとほとんど一緒です。しかし、それはスコアがデジタル署名された変更不可能なデバイスからのみ受け入れられることを必要とするでしょう。これらの特別なデバイスからのデジタル署名されたスコアと、ハッキングされたデバイスからのデジタル署名されたスコアとの違いは、サーバーによって異なりますか。ハードウェアの製造元が、サーバーから問い合わせ可能な検証システムを提供する必要があるかもしれません。
追加された 著者 rm-ass,
あなたの最初のコメントについて - あなたの考えは、ユーザーがゲームを始めたときにクライアントがパズルを得るためにサーバーと通信すると仮定しています。たぶんそれはそれが機能することができる方法ですが、それから私はそのことを「オフライン」とは呼ばないでしょう。高得点を提出する以外は、クライアントは常にオフラインであると想定していました。
追加された 著者 rm-ass,
あなたが「ソースコードを保護する」ことを試みるならば、あなたの真ん中の2段落が面白い考えであるように思われるのであなたの答えは救済可能であるかもしれないと思います。 (私の答えの中のメモを見てください。)
追加された 著者 rm-ass,
DVについては申し訳ありませんが、あなたの答えの大部分は間違っていると私は思います:OPはクライアントがJavaScriptで書かれていると述べています。それでは、「これを解決するための唯一の現実的な方法」とは、キーを隠すことができるものでコードを書き換えることです。しかし、これを解決するための他の方法(そしておそらくもっと良い方法)はオフラインのクライアントを持たないことです。また、最後の段落ではある種の検証としてサーバーの時計を使用することを提案していますが、後で回答が送信されるオフラインクライアントでは、これらの時刻は何にでも操作できます。
追加された 著者 rm-ass,
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript