Zrozumienie, jakie informacje i zasoby są widoczne dla klientów, jest kluczowe dla utrzymania zarówno bezpieczeństwa, jak i poufności Twojej gry. Deweloperzy często niedoceniają, ile jest widoczne dla oszustów i replikowane dla klientów. Oszuści mają możliwość dostępu do "ograniczonych" miejsc w Twoim uniwersum, jeśli mogą dołączyć do jednego miejsca. Mogą przeglądać wszelkie treści replikowane do ich klienta, niezależnie od tego, czy są widoczne, czy aktualnie używane. Dodatkowo, oszuści mogą dekompilować wszelkie replikowane lokalne skrypty i ModuleScripts, nawet jeśli nigdy nie są wykonywane na kliencie.
Teleportacja po stronie klienta w uniwersach
Gdy klienci znajdują się w uniwersum, mogą teleportować się do dowolnego miejsca w tym uniwersum, potencjalnie omijając wszelkie zamierzone ograniczenia dostępu lub bramy postępu. Może to również prowadzić do niezamierzonego wycieku nieopublikowanych treści, na przykład z gry deweloperskiej lub stagingowej. Ważne jest, aby zrozumieć, że:
- Wyłączenie "Bezpośredniego dostępu" usuwa tylko przycisk Dołącz z podmiejsc na stronie internetowej — nie zapobiega to teleportacjom inicjowanym przez klienta
- Zakładaj, że oszuści odkryją istnienie wszystkich podmiejsc w Twoim uniwersum
- Klient może teleportować się do dowolnego podmiejsca, jeśli ma dostęp do jednego miejsca, takiego jak miejsce główne, niezależnie od zamierzonego przepływu projektowania
Wielu deweloperów próbuje zapobiegać dostępowi, wyrzucając nieautoryzowanych użytkowników z podmiejsca. Może to działać w przypadku blokowania rozgrywki, ale nie zapobiega to replikacji treści do klienta, ponieważ replikacja zaczyna się, gdy gracz dołącza, zanim logika wyrzucania po stronie serwera może zostać wykonana.
Używaj bezpiecznych teleportacji
Najskuteczniejszym sposobem zapobiegania nieautoryzowanemu dostępowi za pomocą teleportacji jest ustawienie Kontroli dostępu dla miejsc na Bezpieczne tylko w uniwersum w Panelu twórcy. Ogranicza to wszystkie miejsca, które nie są miejscami startowymi, do teleportacji inicjowanych przez serwer, blokując teleportacje inicjowane przez klienta na poziomie platformy, zanim gracz kiedykolwiek dołączy do podmiejsca. Ponieważ gracz nigdy nie dołącza, żadne treści nie są replikowane do niego.
Aby uzyskać kroki konfiguracyjne i wskazówki dotyczące migracji dla istniejących gier, które używają teleportacji inicjowanej przez klienta, zobacz Teleportacja między miejscami.
Ochrona w głębokości dla ograniczonych miejsc
Dla uniwersów, które nie mogą używać bezpiecznych teleportacji, lub jako dodatkowe warstwy ochrony obok nich, połącz następujące środki:
- Trzymaj miejsca deweloperskie i testowe w oddzielnych, prywatnych uniwersach — to jedyny niezawodny sposób na zapewnienie poufności dla nieopublikowanych treści. Nigdy nie wysyłaj poufnych zasobów wydarzeń, skryptów ani elementów UI do środowiska produkcyjnego, zanim nie będą miały być aktywne.
- Jeśli to możliwe, użyj strumieniowania, aby ograniczyć, ile świata replikowane jest do nowego gracza.
- Dodaj weryfikację ról grupowych po stronie serwera lub weryfikację odznak i zweryfikuj stan gracza lub wymagania postępu.
- Domyślnie zabroń przychodzącym graczom. Zapewnia to, że żaden gracz nie będzie mógł wejść, nawet jeśli proces weryfikacji jest niejednoznaczny, na przykład w przypadku wyjątku zgłoszonego przez silnik.
- Jeśli to praktyczne, użyj Ban API dla graczy, którzy nie przeszli walidacji. Zapobiega to ciągłym próbom dołączenia przez graczy na tym samym koncie.
Replikacja
Replikacja opisuje, jak stan jest przesyłany przez sieć między instancjami silnika. Model replikacji Roblox jest ogólnie uproszczony w kilku kluczowych aspektach:
- Instancje są autorytatywne po stronie serwera, co oznacza, że aby instancja mogła replikować się między wszystkimi uczestnikami (serwerem i wszystkimi podłączonymi klientami), musi być utworzona na serwerze.
- Właściwości instancji są również autorytatywne po stronie serwera, co oznacza, że większość właściwości musi być zmieniana na serwerze, aby zmiany były widoczne dla wszystkich klientów.
- Ogólnie rzecz biorąc, instancja albo replikowana jest do wszystkich podłączonych klientów, albo nie. Istnieją pewne wyjątki, takie jak strumieniowanie.
Kontenery replikacji to instancje najwyższego poziomu (parented under the DataModel), które replikują się do klientów. Jeśli instancja kiedykolwiek stanie się potomkiem kontenera replikacji w swoim życiu, powinieneś oczekiwać, że wiele jej stanu zostanie zreplikowane do wszystkich klientów. Możesz przeczytać więcej o wspólnych kontenerach replikacji w Przewodniku po modelu danych. W razie wątpliwości zawsze możesz sprawdzić, jak instancja lub właściwość replikują się w środowisku testowym, takim jak Play Solo. Możesz przeczytać więcej o trybach testowania w Trybach testowania Studio.
Implikacje bezpieczeństwa replikacji
Wszelkie treści, które replikują się do klienta, mogą być wydobywane i analizowane przez oszusta. Jako ogólna zasada, unikaj publikowania lub wysyłania jakichkolwiek poufnych treści do środowiska produkcyjnego, chyba że jesteś natychmiast gotowy na ich zobaczenie przez użytkowników. Nawet jeśli istnieje logika, która blokuje wydanie lub dostęp do treści w grze do późniejszej daty (lub innego warunku), zakładaj, że oszuści znajdą sposób, aby odkryć i wyciekować Twoje treści, gdy tylko zostaną opublikowane.
Unikaj zbyt opisowych lub przewidywalnych nazw dla wrażliwych instancji, w tym, ale nie ograniczając się do: skryptów, zdalnych i modeli. Posiadanie przewidywalnej hierarchii DataModel ułatwia rozwijanie exploitów.
Dekompilacja skryptów
Każdy LocalScript, Script z RunContext::Client lub ModuleScript może być dekompilowany przez oszusta, gdy zostanie zreplikowany do ich klienta, nawet jeśli takie skrypty są wyłączone, nigdy nie są wymagane lub nigdy nie są uruchamiane na kliencie. Skrypty i ModuleScripts tylko po stronie serwera przechowywane w ServerStorage lub ServerScriptService nie mogą być dekompilowane, ponieważ nigdy nie replikują się do klientów.
Pisanie ModuleScript, który zawiera kod tylko po stronie serwera i tylko po stronie klienta w tym samym skrypcie, jest niewskazane, ponieważ logika po stronie serwera będzie ujawniona w dekompilacji i może być łatwiej analizowana pod kątem błędów, które mogą być wykorzystane.
local module = {}
local Remote = script:WaitForChild("RemoteEvent")
-- Oto przykład paradygmatu, którego należy unikać
-- Trzymaj kod serwera w instancjach Script lub w ServerStorage/ServerScriptStorage!
if game:GetService("RunService"):IsServer() then
function module:DoServerThing(password)
if password == "SecretPassword" then
print("wrażliwy kod serwera")
end
end
Remote.OnServerEvent:Connect(function(player, password)
module:DoServerThing(password)
end)
else
function module:DoServerThing(password)
Remote:FireServer(password)
end
end
return modulelocal table1 = {};
local RemoteEvent = script:WaitForChild("RemoteEvent");
if game:GetService("RunService"):IsServer() then
function table1.DoServerThing(_, p2) -- Linia: 9
if p2 == "SecretPassword" then
print("wrażliwy kod serwera");
end
end
RemoteEvent.OnServerEvent:Connect(function(player: Player, p3) -- Linia: 15
--[[
Upvalues:
[1] = table1
--]]
table1:DoServerThing(p3);
end);
return table1;
end
function table1.DoServerThing(_, p1) -- Linia: 19
--[[
Upvalues:
[1] = RemoteEvent
--]]
RemoteEvent:FireServer(p1);
end
return table1;Jak pokazano powyżej, dekompilacja ujawnia logikę po stronie serwera, w tym twardo zakodowane hasła, zasady biznesowe i szczegóły implementacji, które oszuści mogą analizować w poszukiwaniu luk.
Skutki naruszenia poufności
Naruszenia poufności mogą mieć poważne konsekwencje, takie jak:
- Wycieki treści: Nieopublikowane przedmioty, mapy lub funkcje mogą zostać odkryte i udostępnione publicznie przed oficjalnymi ogłoszeniami
- Nieuczciwa przewaga konkurencyjna: Mechaniki, algorytmy lub nadchodzące funkcje mogą być odwrócone przez konkurentów
- Rozwój exploitów: Ujawniona logika serwera sprawia, że oszuści szybciej i łatwiej identyfikują luki i opracowują ukierunkowane ataki