Universal Blacklist
Key RequiredUniversal

Universal Blacklist

Universal Scriptmcdaggittmcdaggitt 974 views 132 executesUpdated Dec 19, 2025
5.0/ 5(3 votes)
30100% Positive
Lua Script•162 lines (5315 chars)
--[[

information section ==

this script is meant to prevent people from using your script
Its basically roblox's own version of HWID by using roblox's built in features, no server is required to pull information like this.

how it works:
- when executed, the script grabs the device's HWID -- device specific for some odd reason.
- that hwid is tied to the player’s userid and username (If enabled) but in general is tied to their device.
- strikes are stored in the actual executor along with other files such as your userid, hwid, etc. nothing sensitive is stored.
- once the strike limit is reached, the device is permanently blacklisted.

username blacklist behavior:
- if a username listed in the blacklisted usernames section runs this script,
  their hwid is immediately blacklisted so switching accounts is useless.
- once blacklisted, any other account using the same script on the same device will also be blocked.
- this prevents blacklist evasion through alt accounts.

you are free to use this system in your own scripts.
you may modify anything you desire since it's opensourced.

important features:

- if you want to change what folder gets created in the executor,
  or mask it with common scripts, then change the basefolder
+ The default is infiniteyield since most people have used it atleast on the executer once by now, I used it as an example folder.

local basefolder = "infiniteyield" -- example

]]

-- I LOVE DEFINING TWIN
local players = game:GetService("Players")
local analytics = game:GetService("RbxAnalyticsService")
local httpservice = game:GetService("HttpService")
local localplayer = players.LocalPlayer

--[[
====================================
            CONFIGURATION           
====================================
]]

local config = {
    strikelimit = 3, -- customize limit until full blacklist
    kickonly = true, -- ignore
    antitamper = true, -- If files are edited will blacklist
    antireset = false, -- If device is switched will ban the other device -- not fully working yet
    antiuserid = true, -- Store userid
    antiexecutor = false, -- Block executers if they are bad e.g. Xeno/Solara.
    antiusernameblacklist = true -- Toggle to blacklist usernames
}

local blacklistedusernames = {
    "AddUsername"
}
local basefolder = "infiniteyield"
if not isfolder(basefolder) then
    makefolder(basefolder)
end

--[[
====================================
            Logic I dink         
====================================
]]
local hwidfile = basefolder .. "/information.txt"
local strikefile = basefolder .. "/strikes.txt"
local blacklistfile = basefolder .. "/blacklist.txt"
local userfile = basefolder .. "/users.txt"
local metafile = basefolder .. "/meta.txt"

local function readjson(path)
    if isfile(path) then
        return httpservice:JSONDecode(readfile(path))
    end
    return {}
end
local function writejson(path, data)
    writefile(path, httpservice:JSONEncode(data))
end
local function kick(reason)
    localplayer:Kick(reason)
    task.wait(2)
    while true do end
end
local function gethwid()
    if isfile(hwidfile) then
        return readfile(hwidfile)
    end
    local hwid = analytics:GetClientId()
    writefile(hwidfile, hwid)
    return hwid
end
local hwid = gethwid()
local userid = tostring(localplayer.UserId)
local username = localplayer.Name
local strikes = readjson(strikefile)
local blacklist = readjson(blacklistfile)
local users = readjson(userfile)
local meta = readjson(metafile)
if blacklist[hwid] then
    kick("you are blacklisted.")
end
for _, name in ipairs(blacklistedusernames) do
    if config.antiusernameblacklist and username == name then
        blacklist[hwid] = true
        writejson(blacklistfile, blacklist)
        kick("You have been blacklisted by the script creator")
    end
end
local function addstrike(reason)
    strikes[hwid] = (strikes[hwid] or 0) + 1
    writejson(strikefile, strikes)
    if strikes[hwid] >= config.strikelimit then
        blacklist[hwid] = true
        writejson(blacklistfile, blacklist)
        kick("blacklisted: " .. reason)
    end
    if config.kickonly then
        kick("strike " .. strikes[hwid] .. "/" .. config.strikelimit .. " | " .. reason)
    end
end
if config.antitamper then
    local integrity = hwid .. ":" .. userid
    if meta.integrity and meta.integrity ~= integrity then
        addstrike("tampering detected")
    else
        meta.integrity = integrity
        writejson(metafile, meta)
    end
end
if config.antireset then
    if meta.firstseenhwid and meta.firstseenhwid ~= hwid then
        addstrike("hwid reset detected")
    else
        meta.firstseenhwid = hwid
        writejson(metafile, meta)
    end
end
if config.antiuserid then
    if users[hwid] and users[hwid] ~= userid then
        if blacklist[hwid] then
            kick("blacklist evasion")
        else
            addstrike("userid mismatch")
        end
    else
        users[hwid] = userid
        writejson(userfile, users)
    end
end
if config.antiexecutor then
    local required = {"getgenv", "isfile", "readfile", "writefile", "makefolder"}
    for _, fn in ipairs(required) do
        if type(getgenv()[fn]) ~= "function" and type(_G[fn]) ~= "function" then
            addstrike("modified executor environment")
            break
        end
    end
end

Features & Information

() DISCLAIMER - This script doesn't transmit your account hwid/userid/executer/info to other people, it creates the information on your local device in your executers folder to prevent alt's and other stuff. Features I maybe add dk if its allowed - Different executer support -- will work across new/updated executers Features The image has all the config features () Note If you are willing to use the code, do not use it for webhook storing please.
#Universal

Community Comments (5)

ergrgegfgdfgergrgegfgdfgDec 19, 2025

This is byp*able in at least like 5 ways, I only looked at it for like a minute.

Replying to @ergrgegfgdfg

@grimcity Well i'm pretty sure this is supposed to be modified because the anti-tamper is quite literally the most sh*t anti-tamper I think i've ever seen

vxstyvxstyDec 19, 2025

chatgpt

PomPomSaturinPomPomSaturinDec 19, 2025

ai :(

HeroRealHeroRealDec 19, 2025(edited)

I mean its okay [20%], what I would use is gethwid() if the executors supports it or in basic terms Rbx*yticsService.GetClientId [check robloxapi website] edit: connect the gethwid() or GetClientId with an loadstring to easyable add more people, to get their HWID you need to log them first :pray:

More Scripts for Universal Scripts