Why RespectFilteringEnabled should stay on

Turning it off lets any client play sounds for the whole server. How to play shared sounds from the server with checks instead.

warningLuaudit check: client-replicated-sounds

What it looks like

SoundService.RespectFilteringEnabled is turned off, usually so a boombox, emote or instrument played from a LocalScript is heard by other players without a remote. With it off, every client can play sounds for the whole server.

Luau
SoundService.RespectFilteringEnabled = false

How to detect it

  • Search scripts for RespectFilteringEnabled, and check the project file or place settings for SoundService if they're available.
  • Roblox's reference for the property says that when it's false, Sound:Play() called from a LocalScript is heard by other clients too. The default is true.
  • If it's off, any client can play any sound it can reach, as loud and as often as it likes, for everyone. The game's own boombox rules, volume limits and cooldowns run on the client and can be skipped.
  • If the setting isn't visible to the audit, look for signs the game depends on it: LocalScripts that play sounds meant for everyone with no remote to the server. Say it needs checking rather than reporting it.

What an exploiter could do

They play loud or offensive audio for every player in the server, over and over, and the game has no server-side point where it can stop them. Players leave, and reports about the audio can put the game at risk of moderation.

How to fix it

  • Leave RespectFilteringEnabled on.
  • Play shared sounds from the server. Have the client ask with a remote, and check the sound id against a list, the volume and a per-player cooldown on the server before playing it.
  • Sounds only the player should hear, such as interface clicks, can stay on the client.

Vulnerable example

Vulnerable
local SoundService = game:GetService("SoundService")

SoundService.RespectFilteringEnabled = false

Fixed example

Fixed
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local songs: { [string]: string } = {
	Sunny = "rbxassetid://9100601",
	Chill = "rbxassetid://9100602",
}
local cooldown = 10
local lastPlay: { [Player]: number } = {}

ReplicatedStorage.Remotes.PlaySong.OnServerEvent:Connect(function(player: Player, name: unknown)
	local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
	if typeof(name) ~= "string" or not songs[name] or not root then
		return
	end
	local now = os.clock()
	if now - (lastPlay[player] or 0) < cooldown then
		return
	end
	lastPlay[player] = now
	local sound = Instance.new("Sound")
	sound.SoundId = songs[name]
	sound.Volume = 0.5
	sound.RollOffMaxDistance = 60
	sound.Parent = root
	sound.Ended:Once(function()
		sound:Destroy()
	end)
	sound:Play()
end)

Players.PlayerRemoving:Connect(function(player)
	lastPlay[player] = nil
end)

Common false positives

  • RespectFilteringEnabled left at its default of true is the fix.
  • Sounds played from LocalScripts for the local player only are fine with filtering on.
  • Sounds the server plays, even ones a client asked for, are judged by the server's checks, such as Remote with no rate limit.