We are making some changes to InsertService and wanted to give everyone some time to prepare and adjust their game if needed. We are making a change so that clients cannot by default use several InsertService functions. Specifically, this means that attempting to call LoadAsset or LoadAssetVersion from a LocalScript will create a error and will not load the specified model. Allowing the client to insert arbitrary assets is a huge security risk that is really not worth the convenience. We are planning on enabling this change on November 17.
You can opt-out of this feature by setting InsertService.AllowClientInsertModels to true, but it is highly recommended that you only enable this to buy yourself some time while you migrate your code to the server. If you leave this setting on true, you are exposing your game to unnecessary risk. This setting can only be changed in Studio (although you can always read the value in a script).
If you are using InsertService in a LocalScript, you can change your code so that instead of calling LoadAsset on the client, you can have the client fire a RemoteEvent so that the server can load in the model. One very important point though, you should never just pass in the ID of the asset you want to load. Exploiters can call RemoteEvents with whatever arguments they like, so passing the id nullifies any security you get from running LoadAsset on the server.
#Example
In most cases you can simply use a RemoteEvent when you want to load a model from a player’s input. In the following example we have a game with a pizza button. When the button is pressed, the player gets a slice of pizza added to their backpack. Here is how the code would look with client-side insertion:
local button = script.Parent
local player = game.Players.LocalPlayer
local InsertService = game:GetService("InsertService")
local pizzaId = 175696937
local function onButtonClicked()
local pizzaModel
local success, message = pcall(function()
pizzaModel = InsertService:LoadAsset(pizzaId)
end)
if success then
local pizzaTool = pizzaModel:GetChildren()[1]
pizzaTool.Parent = player.Backpack
else
warn("Error loading pizza model: " .. message)
end
end
button.MouseButton1Click:Connect(onButtonClicked)
To make this work on the server, we will need a LocalScript to listen for the button input, a RemoteEvent for the LocalScript to fire, and a Script on the server listening to the remote that will be responsible for fetching the asset and giving it to the player. Here is what the LocalScript will look like:
local button = script.Parent
local requestEvent = game.ReplicatedStorage.RequestItem
local function onButtonClicked()
requestEvent:FireServer("Pizza")
end
button.MouseButton1Click:Connect(onButtonClicked)
Super simple - just fire the RemoteEvent when the player clicks on the button. In general, the client should just deal with the interface, and should send messages to the server when the player wants to do something. Now let’s look at the Script on the server:
local requestEvent = game.ReplicatedStorage.RequestItem
local InsertService = game:GetService("InsertService")
local items = {
Pizza = 175696937,
Sword = 47433,
Slingshot = 47620
}
local function onRequestEvent(player, itemName)
local itemId = items[itemName]
local model
local success, message = pcall(function()
model = InsertService:LoadAsset(itemId)
end)
if model then
local tool = model:GetChildren()[1]
tool.Parent = player.Backpack
else
warn("Error loading " .. itemName .. " : " .. message)
end
end
requestEvent.OnServerEvent:Connect(onRequestEvent)
The server makes a table of all of the assets the game wants the player to be allowed access to. Again, this is so that the client isn’t passing an id to the server. Instead, it passes a string. The server then uses this string to look up the id in a table. After that, things are fairly straightforward. The server gets the model through LoadAsset and then puts the contents into the calling player’s backpack.
#More Resources
For more on RemoteEvents and RemoteFunctions, see
You should also check out FilteringEnabled as it is another great security feature