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şım | Tahmin 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 functionlocal newPart = remoteFunction:InvokeServer(Color3.fromRGB(200, 0, 50), Vector3.new(0, 25, 0))if newPart thenprint("The server created the requested part:", newPart)elseif newPart == false thenprint("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.

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 saniye artışlarıyla, karakterin yeni konumunu önceden kaydedilmiş bir konuma karşı kontrol edin.
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ı):
- 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.
- 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.