Skip to content

fix: add input validation to YAML templates, RCON gateway, and match DTOs#7

Open
Flegma wants to merge 5 commits intomainfrom
audit/404-input-validation
Open

fix: add input validation to YAML templates, RCON gateway, and match DTOs#7
Flegma wants to merge 5 commits intomainfrom
audit/404-input-validation

Conversation

@Flegma
Copy link
Copy Markdown
Contributor

@Flegma Flegma commented Apr 2, 2026

Summary

Three input validation improvements:

  1. YAML template sanitizationreplacePlaceholders() now strips newlines from replacement values to prevent YAML structure injection. Uses split/join instead of RegExp for safer string replacement.

  2. RCON command validation — New validateCommand() method rejects commands that are empty, exceed 512 chars, or contain command-chaining characters (;, \n, \r). All commands are logged for audit trail.

  3. Match data DTO validation — Converted MatchData from interface to class with class-validator decorators. Controller now uses @Body() with ValidationPipe({ whitelist: true }) instead of raw req.body cast.

Test plan

  • Create offline match via web UI — YAML generated correctly
  • RCON commands from admin panel work normally
  • Overly long RCON commands (>512 chars) are rejected
  • Invalid match data (missing required fields) returns validation error

Closes 5stackgg/5stack-panel#404
Closes 5stackgg/5stack-panel#405
Closes 5stackgg/5stack-panel#406

…DTOs

- YAML template: sanitize replacement values (strip newlines) and use
  split/join instead of RegExp to prevent injection via special chars
- RCON gateway: validate command length (max 512), reject command
  chaining (semicolons, newlines), log all commands for audit trail
- Offline matches: convert MatchData to class with class-validator
  decorators, use @Body() with ValidationPipe instead of raw req.body cast

Closes 5stackgg/5stack-panel#404
Closes 5stackgg/5stack-panel#405
Closes 5stackgg/5stack-panel#406
Flegma added 2 commits April 2, 2026 16:59
These were imported for future nested object validation but are not
currently used. Will be re-added when nested DTOs are converted.
Without @ValidateNested and @type, nested objects bypass validation
entirely. Convert MatchOptions, Lineup, MatchMap from interfaces to
classes with class-validator decorators so nested field validation
is enforced by the ValidationPipe.
private static readonly MAX_COMMAND_LENGTH = 512;

private validateCommand(command: string): string | null {
if (!command || typeof command !== "string") {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont see how this can be anything but a stirng

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the redundant typeof check -- you're right, command will always be a string given the typed parameter.

@Flegma
Copy link
Copy Markdown
Contributor Author

Flegma commented Apr 10, 2026

Addressed review feedback:

  • Removed the redundant typeof command !== "string" check from rcon.gateway.ts -- you're right, command will always be a string given the typed parameter.
  • The bot-flagged imports (ValidateNested, Type in MatchData.ts) are actually used by the @ValidateNested() and @Type() decorators on nested properties. The IsOptional import in MatchMap.ts was already removed in a previous commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants