Skip to content

Validation invariants can be bypassed via direct deserialisation #308

@coderabbitai

Description

@coderabbitai

Problem

Several "validated" domain entities derive Deserialize and expose public fields, allowing validation invariants to be bypassed when instances are created outside their new(...) constructors.

Affected Types

  • RouteSummary and CommunityPick in the catalogue domain
  • Tag, Badge, and SafetyToggle in the descriptors domain (generated via macro)

References

  • backend/src/domain/catalogue/route_summary.rs:34
  • backend/src/domain/catalogue/route_summary.rs:55
  • backend/src/domain/catalogue/community_pick.rs:29
  • backend/src/domain/catalogue/community_pick.rs:47
  • backend/src/domain/descriptors/mod.rs:72
  • backend/src/domain/descriptors/mod.rs:85

Impact

Invalid slugs, negative numeric values, or other constraint violations can exist in memory if these types are instantiated via:

  • Direct struct construction (public fields)
  • JSON/CBOR deserialisation bypassing the constructor

This weakens the "validated domain type" contract and could allow invalid data to propagate through the system.

Possible Solutions

  1. Remove Deserialize derives and implement custom deserialisation that delegates to the validating constructor
  2. Use #[serde(try_from = "Draft")] pattern (as done for SafetyPreset) to enforce validation during deserialisation
  3. Make struct fields private and provide only getter methods
  4. Combine approaches: private fields + custom TryFrom deserialisation

Related

This issue was flagged during PR #307 code review (catalogue and descriptor domain types).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions