クライアントに表示される情報と資産を理解することは、あなたの体験のセキュリティと機密性を維持する上で重要です。開発者は、悪用者にどれだけの情報が見えているかを過小評価することがよくあります。悪用者は、単一の場所に参加できれば、あなたのユニバース内の「制限された」場所にアクセスする能力を持っています。彼らは、自分のクライアントに複製されたコンテンツを表示することができ、可視性や現在使用中かどうかには関係ありません。さらに、悪用者は、クライアント上で実行されなくても、複製されたローカルスクリプトやModuleScriptを逆コンパイルすることができます。
ユニバース内のクライアント側テレポーテーション
ユニバース内に入ると、クライアントはそのユニバース内のどの場所にもテレポートすることができ、意図したアクセス制限や進行ゲートをバイパスする可能性があります。これは、開発中またはステージングの体験からリリースされていないコンテンツが意図せず漏洩することにもつながります。以下のことを理解することが重要です:
- 「直接アクセス」を無効にすることは、ウェブサイト上のサブプレイスから参加ボタンを削除するだけであり、クライアントがイニシエイトしたテレポートを防ぐものではありません。
- 悪用者は、あなたのユニバース内のすべてのサブプレイスの存在を発見するでしょう。
- クライアントは、単一の場所(ルートプレイスなど)にアクセスできれば、意図したデザインフローに関係なく、サブプレイスにテレポートできます。
多くの開発者は、不正なユーザーをサブプレイスからキックすることでアクセスを防ごうとします。これはゲームプレイのブロックには効果がありますが、プレイヤーが参加する前に複製が始まるため、クライアントにコンテンツが複製されないようにすることはできません。
セキュアなテレポートを使用する
不正アクセスを防ぐ最も効果的な方法は、クリエイターダッシュボードで場所のアクセス制御をユニバース内のみセキュアに設定することです。これにより、すべての非スタート場所がサーバーによってイニシエイトされたテレポートに制限され、プレイヤーがサブプレイスに参加する前にプラットフォームレベルでクライアントによるテレポートがブロックされます。プレイヤーが参加しないため、コンテンツは彼らに複製されません。
既存のクライアントイニシエイトテレポートを使用している体験の設定手順および移行ガイダンスについては、場所間のテレポートを参照してください。
制限された場所のための多層防御
セキュアなテレポートを使用できないユニバースや、追加の保護層として、以下の措置を組み合わせてください:
- 開発およびテスト用の場所を別個のプライベートユニバースに保つ - これは未発表のコンテンツの機密性を確保する唯一の信頼できる方法です。機密のイベント資産、スクリプト、またはUI要素を本番環境に出荷する前に、使用開始の日ではないとき、または意図されていない時までを含めないでください。
- 可能であれば、ストリーミングを使用して新しいプレイヤーに複製される世界の量を制限します。
- サーバーサイドのグループ役割やバッジの検証を追加し、プレイヤーの状態や進行要求を確認します。
- デフォルトで、着信プレイヤーを拒否します。これにより、エンジンからの例外が発生するなど、検証プロセスが不確定な場合でも、プレイヤーは許可されません。
- 実行可能であれば、検証に失敗したプレイヤーに対してBan APIを使用します。これにより、プレイヤーは同じアカウントで継続的に参加しようとすることが防止されます。
複製
複製とは、エンジンのインスタンス間でネットワークを介して状態が転送される方法を指します。Robloxの複製モデルは、一般的にいくつかの重要な方法で簡略化されています:
- インスタンスはサーバー権限であり、サーバー間で複製されるには、サーバー上で作成される必要があります。
- インスタンスのプロパティもサーバー権限であるため、変更はサーバーで行う必要があります。そうでないと、変更はすべてのクライアントに表示されません。
- 一般的に、インスタンスはすべての接続クライアントに複製されるか、そうでないかです。ストリーミングのような例外があります。
複製コンテナは、クライアントに複製されるデータモデルの上位インスタンスです。インスタンスがその生涯の間に複製コンテナの子孫になると、状態の多くがすべてのクライアントに複製されることを期待してください。一般的な複製コンテナについては、データモデルガイドで詳しく読むことができます。疑問がある場合は、Play Soloなどのテスト環境でインスタンスまたはプロパティがどのように複製されるかを確認できます。テストモードについての詳細は、スタジオテストモードを参照してください。
複製のセキュリティへの影響
クライアントに複製されるコンテンツは、悪用者に抽出され、データマイニングされる可能性があります。一般的なルールとして、ユーザーにすぐに見られることを準備していない限り、機密コンテンツをライブ本番環境に公開または出荷することは避けてください。コンテンツのリリースまたはアクセスを遅延させるロジックがある場合でも(または他の条件)、悪用者はコンテンツが公開されるとすぐにそれを発見して漏洩する方法を見つけると仮定してください。
スクリプト、リモート、モデルなどの敏感なインスタンスの説明的すぎる名前や予測可能な名前を避けてください。予測可能なデータモデルの階層を持つことは、悪用を開発することを容易にします。
スクリプトの逆コンパイル
LocalScript、Script(RunContext::Clientあり)、またはModuleScriptは、クライアントに複製されると悪用者によって逆コンパイルされる可能性があります。これらのスクリプトが無効または必要とされない、あるいはクライアント上で実行されない場合でも同様です。ServerStorageまたはServerScriptServiceに格納されるサーバー専用スクリプトやModuleScriptは、クライアントに複製されないため、逆コンパイルされることはありません。
サーバー専用のロジックを含むModuleScriptを作成することは避けるべきです。なぜなら、サーバー側のロジックが逆コンパイルされて露出し、悪用可能なバグを分析することが容易になるからです。
元のModuleScript in ReplicatedStorage
local module = {}
local Remote = script:WaitForChild("RemoteEvent")
-- 避けるべきパラダイムの例です
-- サーバーコードはスクリプトインスタンスまたはServerStorage/ServerScriptStorageに保ってください!
if game:GetService("RunService"):IsServer() then
function module:DoServerThing(password)
if password == "SecretPassword" then
print("機密サーバーコード")
end
end
Remote.OnServerEvent:Connect(function(player, password)
module:DoServerThing(password)
end)
else
function module:DoServerThing(password)
Remote:FireServer(password)
end
end
return module
逆コンパイル結果
local table1 = {};
local RemoteEvent = script:WaitForChild("RemoteEvent");
if game:GetService("RunService"):IsServer() then
function table1.DoServerThing(_, p2) -- 行: 9
if p2 == "SecretPassword" then
print("機密サーバーコード");
end
end
RemoteEvent.OnServerEvent:Connect(function(player: Player, p3) -- 行: 15
--[[
Upvalues:
[1] = table1
--]]
table1:DoServerThing(p3);
end);
return table1;
end
function table1.DoServerThing(_, p1) -- 行: 19
--[[
Upvalues:
[1] = RemoteEvent
--]]
RemoteEvent:FireServer(p1);
end
return table1;
上記のように、逆コンパイルすると、ハードコーディングされたパスワードやビジネスルール、実装の詳細など、サーバー側のロジックが明らかになり、悪用者が脆弱性を分析できるようになります。
機密性の侵害の影響
機密性の侵害は、重大な結果を引き起こす可能性があります:
- コンテンツの漏洩:未公開のアイテム、マップ、または機能が公式発表前に発見され、公開される可能性があります。
- 競争上の不利:メカニクス、アルゴリズム、または今後の機能が競合他社によってリバースエンジニアリングされる可能性があります。
- 脆弱性の開発:露出したサーバーロジックは、悪用者が脆弱性を特定し、標的を絞った攻撃を展開するのを迅速かつ容易にします。