特定の戦術に入る前に、安全に開発し、チートを防ぐための基本的な原則を理解することが重要です。安全なゲームは、敵対的な行動を予測するマインドセットに基づいて構築されています。コードの1行を書く前に、これらの基本原則を内面化する必要があります。これらは、あなたが行うすべてのアーキテクチャおよび設計の決定に影響を与えるべきです。
クライアントを決して信頼しない
これが基本的な原則です。決意の固いエクスプロイターは、自分のローカル状態とネットワークトラフィックを完全に制御しています。エクスプロイターがこのレベルの制御を持っているため、クライアント側の強制に依存するセキュリティ対策は最終的に回避されます。これはRobloxの制限ではなく、クライアント-サーバーアーキテクチャの基本的な現実です。クライアントから送信されるすべてのデータが操作され、偽造され、または悪意のある意図で送信されたと仮定してください。これには以下の権限が含まれます:
- クライアントで実行されない場合でも、任意の複製されたLocalScriptまたはModuleScriptを逆コンパイルする
- 自分のキャラクターとアンカーされていないパーツのネットワーク所有権を取得する
- TouchedイベントやProximityPromptのアクティベーションなど、クライアントが開始したイベントを任意の範囲や頻度でトリガーする
- プレイヤーの位置、物理、または世界との相互作用を変更する
- RemoteEventsやRemoteFunctionsを任意の頻度で任意の引数(最初のPlayer引数を除く)で発火または呼び出す
- 期待されるイベントを発火させることなく、ローカルDataModel内の何でも変更する
- ローカルで実行されているコードの動作を任意に変更する
このため、すべての重要なロジックはサーバー側で検証されるか、サーバー専用で実行される必要があります。この制御の結果については、ネットワーク所有権、移動検証、および物理エクスプロイトおよびアクセス制御と機密性で詳述されています。
サーバーの権限
サーバーは、すべてのシミュレーション状態、ルール、プレイヤーの進行状況、および重要な決定の最終的な真実の源である必要があります。クライアントの役割は、世界をレンダリングし、ユーザー入力をサーバーに送信することです。
サーバーの役割は以下の通りです:
- クライアントからの入力を受け取る
- 要求されたアクションが可能で許可されているかを検証する
- アクションを実行し、その権威ある状態を更新する
- 結果をすべての関連クライアントに複製する
たとえば、プレイヤーが「Bloxy Colaを買いたい」と言った場合、サーバーはアイテムの真の価格、プレイヤーの所持金、およびプレイヤーキャラクターのショップからの物理的距離を知っている必要があります。できるだけ多くの状態をサーバーが独占的に維持し、クライアントによって維持されないようにするべきです。例として、Bloxy Colaの取引が承認された場合、サーバーはプレイヤーの所持金からBloxy Colaの価格を差し引く必要がありますが、サーバーは必ずしもプレイヤーキャラクターを常に制御できるわけではありません。
設計によるセキュリティ
ゲームの設計の最初からセキュリティの考慮を統合し、後から後付けで追加しようとしないでください。
- 新しい機能ごとに脅威モデルを作成します。新しい機能ごとに次のことを尋ねます:
- 攻撃者がクライアントを完全に制御している場合、どのようにこれを悪用できるか?
- クライアントが機能で使用される任意のパラメータに対して任意の値を送信できる場合、最悪の結果は何か?
- この機能が1秒間に1,000回以上使用された場合、どうなるか?最大使用頻度はどのくらいか?
- エクスプロイターがこれを使用して他のプレイヤーの体験を台無しにすることができるか?
- 最悪のケースで、この機能が実際に使用するリソースはどのくらいか?
- この機能のために公開する必要がある最小限の内部情報または状態は何か?
- 責任を早期に分割します。最初の日からServerScriptServiceにロジックとデータを保持します。決してReplicatedStorageやWorkspaceのような複製されたコンテナに置かないでください。