WhereiamL
betterxSound

Security

How betterxSound stops players from spamming sounds at the server.

Stock xSound exposes server events that any client can trigger to play a sound — including events that fan a sound out to every player. With no validation, a single exploiter can blast an arbitrary or deafening sound across the whole server. betterxSound closes that without breaking legitimate callers.

What is protected

The checks wrap the client-triggerable events:

  • The interact-sound emulator: InteractSound_SV:PlayOnOne, :PlayOnSource, :PlayOnAll, :PlayWithinDistance.
  • The crewphone addon: muzik-cal, muzik-durdur, muzik-duraklat, muzik-devamet.

The core xSound exports (exports.xsound:PlayUrl, etc.) are called server-to-server by other resources and are not a client attack surface, so they are left untouched.

What is enforced

Every gated event passes through one check (configured in config.security):

  1. Rate limit — per player, rate.count events per rate.windowMs. The counter is cleared when the player disconnects.
  2. Volume clamp — clamped into [0, maxVolume].
  3. File sanitize (emulator) — rejects path traversal (.., leading dot segments) and anything outside a safe character set, and requires an extension in allowedExt.
  4. URL validate (crewphone remote links) — only hosts in allowedDomains (YouTube by default) are accepted.
  5. Type checks — every field is type-checked; distance is clamped to a sane maximum.

A rejected event is dropped silently. When log is on, the server prints one line, for example:

[xsound] blocked sound event from 7: rate-limit

Broadcast permission (optional)

Events that play to everyone (PlayOnAll, PlayWithinDistance, crewphone muzik-cal) can require an ACE permission. It is off by default so existing setups keep working.

To require permission, set the ACE name in config.lua:

config.security.broadcastAce = "xsound.broadcast"

Then grant it in your server.cfg to whoever may broadcast (an admin group, a job, etc.):

add_ace group.admin xsound.broadcast allow

Leave broadcastAce empty if other resources legitimately play sounds to all players and you do not want to manage ACEs. Rate limiting and validation still apply.

On this page