Roblox menggunakan sistem fisik distribusi di mana klien memiliki kekuasaan atas simulasi fisik objek di kontrol mereka, biasanya karakter pemain dan objek yang tidak terancam di dekat karakter itu. Selain itu, melalui penggunaan perangkat lunak pihak ketiga, pengecuali dapat mengeksekuskan kode Lua acak di klien untuk menipu model data klien dan mengeksekuskan dan
Secara kolektif, ini berarti bahwa seorang pengeksploiter berpengetahuan dapat potensialmente mengeksekusan kode untuk menipu dalam gameAnda, termasuk:
- Mengirim karakter mereka sendiri di sekitar tempat.
- Menembak tanpa aman RemoteEvents atau mengundang RemoteFunctions, seperti untuk memberikan hadiah diri mereka sendiri tanpa mendapatkan item.
- Menyesuaikan kecepatan karakter mereka WalkSpeed sehingga bergerak sangat cepat.
Sementara Anda dapat menerapkan pertahanan desain terbatas untuk menangkap serangan umum, sangat disarankan agar Anda menerapkan lebih banyak taktik mitigasi pihak server yang dapat diandalkan, karena server adalah otoritas terakhir untuk setiap pengalaman yang berjalan.
Taktik Desain Pertahanan
Keputusan desain dasar dapat melayani sebagai "langkah pertama" tindakan keamanan untuk menghalangi eksploitasi. Misalnya, dalam permainan penembak di mana pemain mendapatkan poin untuk membunuh pemain lain, seorang pengeksploiter dapat menciptakan banyak bot yang teleport ke tempat yang sama sehingga mereka dapat dengan cepat dibunuh untuk mendapatkan poin. Mengingat potensi eksploit in
Pendekatan | Kemungkinan Hasil |
---|---|
Kalahkan bot dengan menulis kode yang mencoba untuk mendeteksi mereka. | |
Kurangi atau bahkan hapus keuntungan poin untuk membunuh pemain baru. |
Sementara desain pertahanan jelas bukan solusi sempurna atau lengkap, itu dapat berkontribusi pada pendekatan keamanan yang lebih luas, bersama dengan mitigasi server.
Mitigasi Sisi Server
Sebanyak mungkin, server harus menghasilkan putusan terakhir tentang apa yang "benar" dan apa status saat ini dari dunia. Klien dapat, tentu saja, meminta server untuk melakukan perubahan atau melakukan action, tetapi server harus 验证 setiap perubahan/tindakan ini sebelum hasilnya di replik ke pemain lain.
Dengan beberapa operasi fisik tertentu, perubahan pada model data pada klien tidak mencerminkan ke server, jadi jalan serangan utama sering melalui jaringan acara yang Anda telah menyatakan dengan RemoteEvents dan RemoteFunctions . Ingat bahwa seorang pengeksploiter yang mengeksekuskan kode mereka sendiri di klien d
Validasi Type Remote Runtime
Satu jalan serangan digunakan oleh seorang pengeksploiter untuk mengekspploitasi RemoteEvents dan RemoteFunctions dengan argumen ketikyang salah. Dalam beberapa skenario, ini dapat menyebabkan kode di server mendengarkan remotes ini untuk kesalahan dengan cara yang menguntungkan bagi pengeksploiter.
Ketika menggunakan acara/fungsi remote, Anda dapat mencegah jenis serangan ini dengan validating the jenis dari argument yang dilewati di server. Modul t, yang tersedia di sini, berguna untuk memeriksa jenis pada saat ini. Misalnya
Skrip Lokal di StarterPlayerScripts
local ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteFunction = ReplicatedStorage:WaitForChild("RemoteFunctionTest")-- Mengubah warna dan posisi bagian saat memanggil fungsilocal 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
Skrip di ServerScriptService
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:WaitForChild("RemoteFunctionTest")
local t = require(ReplicatedStorage:WaitForChild("t"))
-- Buat validator jenis sebelumnya untuk menghindari over头 yang tidak perlu
local createPartTypeValidator = t.tuple(t.instanceIsA("Player"), t.Color3, t.Vector3)
-- Buat bagian baru dengan propinsi yang dilewati
local function createPart(player, partColor, partPosition)
-- Ketik memeriksa argumen yang dilewati
if not createPartTypeValidator(player, partColor, partPosition) then
-- Kembalikan "false" jika tipe check gagal di sini
-- Mengangkat kesalahan tanpa cooldown dapat dimanfaatkan untuk menyuruh server
-- Berikan umpan balik klien sebagai gantinya!
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
-- Ikat "createPart()" ke panggilan fungsi remote
remoteFunction.OnServerInvoke = createPart
Validasi Data
Serangan lain yang para pengeksploiter mungkin meluncurkan adalah mengirim jenis-jenis yang benar secara teknis tetapi membuatnya sangat besar, panjang, atau sebaliknya tidak terbentuk dengan benar. Misalnya, jika server harus melakukan operasi mahal di string yang berukuran panjang, seorang pengeksploiter dapat mengirim string yang sangat besar atau tidak terbentuk dengan benar.
Demikian pula, kedua inf dan NaN akan type() sebagai 1> number1> , tetapi kedua dapat menyebabkan masalah besar jika seorang pengecer mengirim mereka dan mereka tidak ditangani dengan benar melalui fungsi seperti mengikuti:
local function isNaN(n: number): boolean
-- NaN tidak pernah sama dengan dirinya sendiri
return n ~= n
end
local function isInf(n: number): boolean
-- Nomor bisa -inf atau inf
return math.abs(n) == math.huge
end
Serangan umum lain yang digunakan oleh pengeksploiter melibatkan mengirim tables di tempat Class.Instance . Referensi objek biasa lainnya dapat meniru apa yang akan menjadi referensi objek biasa lainnya.
Misalnya, diberikan dengan sistem dalam-toko pengalaman di mana data item seperti harga disimpan dalam NumberValue objek, seorang penipu dapat mengelakkan semua periksa lain dengan melakukan berbagai tindakan mengikuti:
Skrip Lokal di 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, -- Nilai negatif juga dapat digunakan, yang menyebabkan memberikan mata uang daripada mengambilnya!},}-- Kirim malware ke server (ini akan ditolak)print(buyItemEvent:InvokeServer(payload)) -- Outputs "false Item yang diberikan tidak valid"-- Kirim item nyata ke server (ini akan pergi melalui!)print(buyItemEvent:InvokeServer(itemDatafolder["Real Blade"])) -- Outputs "true" and remaining currency if purchase succeeds
Skrip di ServerScriptService
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local itemDataFolder = ReplicatedStorage:WaitForChild("ItemData")
local buyItemEvent = ReplicatedStorage:WaitForChild("BuyItemEvent")
local function buyItem(player, item)
-- Periksa apakah item yang dilewati tidak dimanfaatkan dan berada di item data
if typeof(item) ~= "Instance" or not item:IsDescendantOf(itemDataFolder) then
return false, "Invalid item provided"
end
-- Server kemudian dapat pergi ke proses pembelian berdasarkan contoh alir di bawah ini
end
-- Ikat "beliItem()" ke konsumen fungsiRemote
buyItemEvent.OnServerInvoke = buyItem
ValidasiNilai
Selain mengaktifkan jenis dan data, Anda harus mengaktifkan nilai yang dilewati melalui 1> Class.RemoteEvent|RemoteEvents1> dan 4> Class.RemoteFunction|RemoteFunctions4>, memastikan bahwa mereka valid dan logikal dalam konteks y
Toko dalam Pengalaman
Pertimbangkan sistem toko dalam pengalaman dengan antarmuka pengguna, misalnya menu pemilihan produk dengan tombol "Beli". Saat tombol ditekan, Anda dapat memanggil RemoteFunction antara klien dan server untuk meminta pembelian. Namun, penting bahwa server, manajer paling dapat diandalkan dari pengalaman,
Targeting Senjata
Skenario tempur mengharuskan perhatian khusus dalam validasi nilai, khususnya melalui pemantauan bidikan dan validasi hit.
Bayangkan sebuah permainan di mana seorang pemain dapat menembak laser ke pemain lain. Alih-alih klien memberitahu server siapa untuk menghancurkan, itu seharusnya memberitahu server posisi asal tembakan dan bagian/posisi yang di pikirnya telah dihancurkan. Server kemudian dapat mengaktifkan mengikuti:
Posisi yang dikirim oleh klien menembak dari dekat karakter pemain di server. Catat bahwa server dan klien akan berbeda sedikit karena kelambatan, jadi toleransi ekstra akan perlu diterapkan.
Posisi yang dikatakan klien menghantam adalah posisi yang layaknya dekat dengan posisi bagian yang dikatakan klien menghantam, di server.
Tidak ada penghalang statis di antara posisi yang dikirim oleh klien dan posisi yang dikirim oleh klien. Pemeriksaan ini memastikan bahwa klien tidak mencoba untuk menembak melalui dinding. Catat bahwa ini hanya memeriksa geometri statis untuk menghindari tembakan yang ditolak karena kelambatan. Selain itu , Anda mungkin ingin menerapkan validasi server-side lainnya sebagai berikut:
Melacak kapan pemain terakhir menembak senjata mereka dan validasi untuk memastikan mereka tidak menembak terlalu cepat.
Ikuti jumlah amunisi setiap pemain di server dan konfirmasi bahwa pemain penembak memiliki cukup amunisi untuk mengeksekusi serangan senjata.
Jika Anda telah menerapkan tim atau sistem pertarungan "pemain melawan bot", konfirmasi bahwa karakter pukul adalah musuh, bukan rekan satu tim.
Konfirmasi bahwa pemain hit masih hidup.
Simpan status senjata dan pemain di server dan konfirmasi bahwa pemain yang menembak tidak diblokir oleh tindakan saat ini seperti reloading atau kondisi seperti sprinting.
Manipulasi Toko Data
Dalam pengalaman menggunakan DataStoreService untuk menyimpan data pemain, pengejar mungkin mengambil keuntungan dari data yang tidak valid, dan metode yang lebih tua, untuk mencegah DataStore menyimpan dengan benar. Ini dapat digunakan secara terutama dalam pengalaman dengan perdagangan item
Pastikan bahwa setiap tindakan yang dilakukan melalui RemoteEvent atau RemoteFunction yang meng影响 data pemain dengan masukan klien adalah disanitized berdasarkan mengikuti:
- Instance nilai tidak dapat diserIALkan ke dalam DataStore dan akan gagal. Gunakan validasi jenis untuk mencegah ini.
- DataStores memiliki batas data . Strings panjang acak harus diperiksa dan/atau dibatasi untuk menghindari ini, sementara memastikan kunci acak panjang tidak dapat ditambahkan ke tabel oleh klien.
- Indeks tabel tidak boleh menjadi NaN atau nil . Iterate over semua tabel yang dilewati klien dan memeriksa semua indeks valid.
- DataStores hanya dapat menerima karakter UTF-8 yang valid, jadi Anda harus menyanifikasi semua string yang disediakan oleh klien melalui Library.utf8|utf8.
Throttling Jarak Jauh
Jika klien dapat membuat server Anda menyelesaikan operasi yang mahal secara kalkulatoris, atau mengakses layanan berbasis tingkat seperti DataStoreService melalui akses RemoteEvent , penting untuk menerapkan batasan tingkat untuk memastikan bahwa operasi tidak dipanggil ter
Validasi Gerakan
Untuk pengalaman kompetitif, Anda mungkin ingin memverifikasi gerakan karakter pemain di server untuk memastikan mereka tidak mengirim teleportasi di sekitar peta atau bergerak lebih cepat dari yang dianggap.
Dalam peningkatan 1 detik, periksa lokasi baru karakter terhadap lokasi yang sebelumnya disimpan.
Bandingkan jarak aktual melawan tolerable dan lanjutkan sebagai berikut:
- Untuk Delta yang dapat diterima, simpan lokasi karakter baru dalam persiapan untuk pemeriksaan berikutnya yang periksa.
- Untuk Delta yang tak terduga atau tidak dapat diterima (potensi kecepatan / teleportasi eksploit):
- Tingkatkan nilai "jumlah pelanggaran" terpisah untuk pemain, daripada menghukum mereka karena "positif palsu" yang timbul dari kelambatan server ekstrim atau faktor non-exploit lainnya.
- Jika terjadi banyak pelanggaran selama periode 30-60 detik, Kick() pemain dari pengalaman sepenuhnya; jika tidak, reset "jumlah pelanggaran" count. Catat bahwa ketika mengeluarkan pemain untuk cheating, itu best practice untuk merekam acara sehingga Anda dapat melacak berapa banyak pemain yang terpengaruh.