Güvenlik taktikleri ve hile azaltma

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Roblox, müşterilerin kontrollerindeki nesnelerin fiziksel simülasyonuna sahip olduğu dağıtılmış bir fizik sistemi kullanır, genellikle oyuncunun karakteri ve bu karakterin yakınındaki sabit olmayan nesneler.Ayrıca, üçüncü taraf yazılımın kullanılmasıyla, saldırganlar, müşterilerinin veri modelini manipüle etmek ve üzerinde çalışan kodu dekompile etmek ve görüntülemek için müşterilerinin kodunu istismar edebilirler.

Topluca, bu, yetenekli bir saldırganın potansiyel olarak oyununuza hile yapmak için kod yürütebileceği anlamına gelir, şunlar dahil:

  • Yer etrafında kendi karakterlerini ışınlıyor.
  • Güvenli olmayan RemoteEvents ateş etmek veya kazanmadan kendilerine ödül vermek gibi, kendilerine ödül vermeden öğeler vermek gibi RemoteFunctions .
  • Karakterlerinin WalkSpeed'sini ayarlayarak gerçekten hızlı hareket etmesini sağlama

Sınırlı tasarım savunmaları uygulayarak yaygın saldırıları yakalayabilirsiniz, ancak sunucu herhangi bir çalıştırma deneyiminin son noktasıdır, bu nedenle daha güvenilir sunucu tarafı mitigasyon taktiği uygulamanız önerilir, çünkü sunucu herhangi bir çalıştırma deneyiminin son noktasıdır.

Savunma tasarım taktikleri

Temel tasarım kararları, saldırıları azaltmak için "ilk adım" güvenlik önlemleri olarak hizmet edebilir.Örneğin, oyuncuların diğer oyuncuları öldürmek için puan aldığı bir atış oyununda, bir saldırgan aynı yere ışınlanan bir grup bot oluşturabilir, böylece puan için hızlı bir şekilde öldürülebilir.Bu potansiyel saldırı göz önüne alındığında, iki yaklaşım ve öngörülebilir sonuçlarını düşünün:

YaklaşımTahmin edilebilir sonuç
Onları tespit etmeye çalışan kod yazarak botları kovalayın.
Yeni oluşturulan oyunculara yönelik öldürme puanlarını azaltın veya kaldırın.

Savunma tasarımı elbette mükemmel veya kapsamlı bir çözüm değildir, ancak sunucu tarafından azaltma ile daha geniş bir güvenlik yaklaşımına katkıda bulunabilir.

Sunucu tarafından azaltma

Mümkün olduğunca, sunucu nihai kararı vermelidir ne "doğru" ve dünyanın mevcut durumunun ne olduğu.Tabii ki, müşteriler sunucudan değişiklik yapmasını veya bir aksiyongerçekleştirmesini isteyebilirler, ancak sunucu bu değişikliklerin/eylemlerin her birini onaylamalı ve sonuçlar diğer oyunculara yansımadan önce onaylamalıdır. Doğrulayıp onaylamalı .

Bazı fiziksel işlemler dışında, müşterideki veri modelindeki değişiklikler sunucuya yansımaz, bu nedenle ana saldırı yolu genellikle RemoteEvents ve RemoteFunctions ile ilan ettiğiniz ağ olayları aracılığıyla gerçekleşir.Klientinizde kendi kodunu çalıştıran bir saldırganın, istediği herhangi bir veriyle bunları çağırabileceğini unutmayın.

Uzak çalışma türü doğrulaması

Bir saldırı yolu, bir saldırganın yanlış yazargümanlarla RemoteEvents ve RemoteFunctions çağırması içindir.Bazı senaryolarda, bu, uzaktaki kodları dinleyen sunucudaki kodun hacker için avantajlı bir şekilde hata yapmasına neden olabilir.

Uzak olayları/fonksiyonları kullanırken, sunucuda geçen türlerin geçerli olması sayesinde bu tür bir saldırı engelleyebilirsiniz.Modül "t" , burada mevcut , bu şekilde tip kontrolü için yararlıdır.Örneğin, modülün kodunun bir ModuleScript adında olduğunu varsayalım t içinde ReplicatedStorage :

Başlangıç ​​Oyun Senaryolarındaki Yerel Kodların StarterPlayerScripts

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:WaitForChild("RemoteFunctionTest")
-- İşlev çağrıldığında parça rengi ve konumu geçirin Pass part color and position when invoking the function
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(200, 0, 50), Vector3.new(0, 25, 0))
if newPart then
print("The server created the requested part:", newPart)
elseif newPart == false then
print("The server denied the request. No part was created.")
end
ServerScriptService'teki senaryo

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteFunction = ReplicatedStorage:WaitForChild("RemoteFunctionTest")
local t = require(ReplicatedStorage:WaitForChild("t"))
-- Gereksiz yükü önlemek için önceden tip doğrulayıcı oluşturun
local createPartTypeValidator = t.tuple(t.instanceIsA("Player"), t.Color3, t.Vector3)
-- Geçen özelliklerle yeni parça oluştur
local function createPart(player, partColor, partPosition)
-- Geçen argümanların kontrolünü yapın
if not createPartTypeValidator(player, partColor, partPosition) then
-- Tür kontrolü burada başarısız olursa sessizce "false" döndürün
-- Bekleme süresi olmadan bir hata yükseltmek, sunucuyu yavaşlatmak için kötüye kullanılabilir
-- Bunun yerine müşteri geri bildirimi sağlayın!
return false
end
print(player.Name .. " requested a new part")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- Uzaktaki işlevin geri çağrısına "createPart()" bağlama
remoteFunction.OnServerInvoke = createPart

Veri doğrulaması

Kötü niyetli saldırganların başlatabileceği bir başka saldırı, teknik olarak geçerli türleri göndermek ancak onları son derece büyük, uzun veya başka şekilde bozuk hale getirmektir.Örneğin, sunucunun uzunluğa göre ölçeklenen bir dize üzerinde pahalı bir işlem yapması gerekiyorsa, bir saldırgan, sunucuyu yavaşlatmak için inanılmaz büyük veya bozuk bir dize gönderebilir.

Benzer şekilde, her ikisi de ve , ancak her ikisi de bir saldırgan onlara gönderirse ve takip edilengibi işlevler aracılığıyla doğru bir şekilde ele alınmazsa büyük sorunlara neden olabilir:


local function isNaN(n: number): boolean
-- NaN asla kendisiyle eşit olmaz
return n ~= n
end
local function isInf(n: number): boolean
-- Sayı -inf veya inf olabilir
return math.abs(n) == math.huge
end

Saldırganların kullanabileceği başka yaygın saldırı, bir Instance yerine tables göndermekle ilgilidir.Karmaşık yükler, başka bir sıradan nesne referansı olacak şeyi taklit edebilir.

Örneğin, fiyat gibi öğe verilerinin depolandığı deneyim içi mağaza sistemiyle birlikte, bir saldırgan takip edilenyaparak diğer tüm kontrolleri atlayabilir:

Başlangıç ​​Oyun Senaryolarındaki Yerel Kodların StarterPlayerScripts

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local itemDataFolder = ReplicatedStorage:WaitForChild("ItemData")
local buyItemEvent = ReplicatedStorage:WaitForChild("BuyItemEvent")
local payload = {
Name = "Ultra Blade",
ClassName = "Folder",
Parent = itemDataFolder,
Price = {
Name = "Price",
ClassName = "NumberValue",
Value = 0, -- Negatif değerler de kullanılabilir, böylece para yerine almak yerine verilir!
},
}
-- Sunucuya zararlı yük gönder (bu reddedilecek)
print(buyItemEvent:InvokeServer(payload)) -- Çıktı "yanlış Geçersiz öğe sağlandı"
-- Sunucuya gerçek bir öğe gönderin (bu geçecek!)
print(buyItemEvent:InvokeServer(itemDatafolder["Real Blade"])) -- Outputs "true" and remaining currency if purchase succeeds
ServerScriptService'teki senaryo

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local itemDataFolder = ReplicatedStorage:WaitForChild("ItemData")
local buyItemEvent = ReplicatedStorage:WaitForChild("BuyItemEvent")
local function buyItem(player, item)
-- Geçirilen öğe sahte olmadığını ve ItemData klasöründe olduğunu kontrol edin
if typeof(item) ~= "Instance" or not item:IsDescendantOf(itemDataFolder) then
return false, "Invalid item provided"
end
-- Sunucu daha sonra aşağıdaki örnek akışa dayanarak satın alma işlemini işleyebilir
end
-- Uzaktaki işlevin geri çağrısına "buyItem()" bağlama
buyItemEvent.OnServerInvoke = buyItem

Değer doğrulaması

türlerinin ve verilerinin doğrulanmasına ek olarak, talep edilen bağlamda geçerli ve mantıklı olduklarından emin olmak için değerlerinin ve geçmesini sağlamalısınız, istenen bağlamda geçerli ve mantıklı olduklarından emin olmak için.İki yaygın örnek deneyim içinde bir mağaza ve bir silah hedefleme sistemidir.

Deneyim içi alışveriş yap

Deneyim içinde bir mağaza sistemi ile kullanıcı arayüzü düşünün, örneğin bir "Satın Al" düğmesi ile bir ürün seçim menüsü.Buton basıldığında, satın alma isteği için istemci ve sunucu arasında bir RemoteFunction çağırabilirsiniz.Ancak, deneyimin en güvenilir yöneticisi olan sunucu , kullanıcının öğesatın almak için yeterli paraya sahip olduğunu onaylaması önemlidir.

Example purchase flow from client to server through a RemoteEvent

Müşteriden sunucuya bir RemoteFunction
aracılığıyla örnek satın alma akışı

Silah hedeflemesi

Savaş senaryoları değerlerin doğrulanması konusunda özel dikkat gerektirir, özellikle hedef ve vuruş doğrulaması yoluyla.

Bir oyuncunun başka bir oyuncuya lazer ışını ateşleyebileceği bir oyun hayal edin.Müşterinin sunucuya kimin zarar vereceğini söylemesi yerine, sunucuya atışın kaynağı konumunu ve vurduğunu düşündüğü parçayı/pozisyonu söylemelidir.Sunucu daha sonra takip edilendoğrulayabilir:

  • Müşterinin bildirdiği pozisyon silah atışı sunucudaki oyuncunun karakterine yakındır.Sunucu ve istemcinin gecikme nedeniyle biraz farklı olacağını unutmayın, bu nedenle ekstra tolerans gerekecektir.

  • Müşterinin bildirdiği pozisyon vuruşu makul bir şekilde, müşterinin vurduğu parçanın konumuna yakındır, sunucuda.

  • Müşterinin atış yaptığı pozisyon ile müşterinin atış yaptığı pozisyon arasında statik engeller yoktur.Bu kontrol, bir müşterinin duvarlardan ateş etmeye çalışmadığını garanti eder.Bunun sadece gecikme nedeniyle geçersiz atışların reddedilmesini önlemek için statik geometriyi kontrol etmesi gerektiğini unutmayın. Ek olarak , daha fazla sunucu tarafı doğrulama uygulamak isteyebilirsiniz:

  • Oyuncu silahını son kez ne zaman ateş ettiğini izleyin ve çok hızlı ateş etmediğinden emin olmak için doğrulayın.

  • Sunucuda her oyuncunun cephane miktarını izleyin ve bir atış oyuncusunun silah saldırısını uygulayacak yeterli cephaneye sahip olduğunu doğrulayın.

  • Eğer takımları veya "botlara karşı oyuncu" savaş sistemini uyguladıysanız, vuruş karakterinin bir düşman olduğundan emin olun, takım arkadaşı değil.

  • Vuruş oyuncusunun hayatta olduğundan emin olun.

  • Silah ve oyuncu durumunu sunucuda saklayın ve atış yapan bir oyuncunun yeniden yükleme veya sprint gibi mevcut bir eylem tarafından engellenmediğini onaylayın.

Veri depolama manipülasyonu

Oyuncu verilerini kaydetmek için DataStoreService 'yi kullanan deneyimlerde, saldırganlar geçersiz verileri 'den yararlanabilir ve daha karanlık yöntemler, bir DataStore 'un doğru bir şekilde kaydetmesini engelleyebilir.Bu, özellikle eşya takası, pazaryerleri ve eşyaların veya para birimlerinin bir oyuncunun envanterinden ayrıldığı benzer sistemlerde kötüye kullanılabilir.

Oyuncu verilerini istemci girişiyle etkileyen herhangi bir eylemin RemoteEvent veya RemoteFunction yoluyla yapıldığından emin olun, takip edilendayanarak dezenfekte edilir:

  • Instance değerleri bir DataStore içine serilemez ve başarısız olur. Bunu önlemek için tür doğrulama kullanın.
  • DataStores 'nin veri sınırları vardır.Sınırsız rastgele anahtarların istemci tarafından masalara eklenememesini önlemek için rastgele uzunlukta dize kontrol edilmeli ve/veya sınırlandırılmalıdır, sınırsız rastgele anahtarların tablolara eklenmesini engellemek için.
  • Tablo indeksleri NaN veya nil olamaz. Müşteri tarafından geçen tüm tablolarda dolaşın ve tüm indekslerin geçerli olduğunu doğrulayın.
  • DataStores sadece geçerli UTF-8 karakterlerini kabul edebilir, bu nedenle tüm dizeyi müşteri tarafından sağlanan utf8.len() aracılığıyla temizlemelisiniz, böylece geçerli olmalarını sağlayın.utf8.len() bir dize uzunluğunu döndürecek ve UTF-8 karakterlerini tek bir karakter olarak ele alacaktır; eğer geçersiz bir UTF-8 karakteri bulunursa, nil ve geçersiz karakterin konumu geri dönecektir.Geçersiz UTF-8 dizeelerinin tablolarda anahtar ve değer olarak da bulunabileceğini unutmayın.

Uzaktan sınırlama

Bir istemci, sunucunuzun hesapsal olarak pahalı bir işlemi tamamlamasını veya üzerinden oran sınırlı bir hizmete erişmesini sağlayabiliyorsa, operasyonun çok sık çağrılmadığından emin olmak için oran sınırlamasını uygulamanız çok önemlidir.Oran sınırlaması, istemcinin son olarak uzaktaki bir olayı çağırdığını izleyerek ve çok erken çağrıldığında bir sonraki isteği reddederek uygulanabilir.

Hareket doğrulaması

Rekabetçi deneyimler için, oyuncu karakter hareketlerinin sunucuda doğrulanmasını isteyebilirsiniz, böylece harita etrafında ışınlanmıyorlar veya kabul edilebilir hızdan daha hızlı hareket etmiyorlar.

  1. 1 saniye artışlarıyla, karakterin yeni konumunu önceden kaydedilmiş bir konuma karşı kontrol edin.

    Image showing moving character's position on a straight path in increments of 1 second
  2. Karakterin WalkSpeed (saniye başına studlar) üzerine çarptığı maksimum "toler edilebilir" değişikliği mesafeye göre belirleyin ve sunucu gecikmesine karşı biraz esneklik sağlamak için ~1.4 ile çarptırın.Örneğin, varsayılan WalkSpeed 16'da, kabul edilebilir bir delta ~22 dir.

    Image showing tolerable change in distance based on character's walk speed
  3. Gerçek mesafe deltasını tolere edilebilir deltaya karşı karşılaştırın ve aşağıdaki gibi devam edin:

    • Tahammül edilebilir bir delta için, karakterin bir sonraki artırılmış kontrol etiçin hazırlık yapılırken yeni konumunu önbelleğe alın.
    • Beklenmedik veya dayanılmaz bir delta için (potansiyel hız/ışınlanma saldırısı):
      1. oyuncuiçin ayrı bir "saldırı sayısı" değeri artır, aşırı sunucu gecikmesi veya diğer kullanılmayan faktörlerden kaynaklanan "yanlış pozitif" sonucu cezalandırmak için.
      2. Büyük bir sayıda ihlal 30-60 saniye süreyle gerçekleşirse, Kick() deneyimden oyuncuyu tamamen sıfırla; aksi takdirde, "suç sayısı" sayısını sıfırla.Bir oyuncuyu hile yaptığı için kovarken, olayı kaydetmek en iyi uygulamadır, böylece kaç oyuncunun etkilendiğini takip edebilirsiniz.