DEFENCE
DEF-SYN-001v1.0Public · synthetic
Illustrative demo — not a customer resultPublic · synthetic

Relayboard external web/API security review

A clean-room example of how Defence records a property break, the evidence behind it, remediation, and what a targeted retest does—and does not—close.

Report ID
DEF-SYN-001
Version
1.0
State
Final illustrative report
Assessment window
18–19 Aug 2026
Retest window
22 Aug 2026
Environment
Production-like synthetic environment
Current build
relayboard-web 2026.08.22.3
Generated
25 Aug 2026 · 11:40 UTC
Accountable author
Defence review team

Executive verdict

This report does not establish that Relayboard has no other vulnerabilities or that the changed build received a new full assessment.

Assessment state3 reproduced property breaks

Two authorization boundaries and one single-use workflow condition were confirmed with synthetic test data.

After remediation and retest1 closed · 1 partial · 1 awaiting retest

Only SYN-01 has closure evidence. SYN-02 retains a sibling-path break. SYN-03 has a reported fix but no replay evidence.

System and scope

The frozen surface contains one fictional multi-tenant field-work product and only test-team identities, workspaces, jobs, exports, and magic links.

Web application
app.relayboard.example
HTTP API
api.relayboard.example
Assessment build
relayboard-web 2026.08.18.5
Retest build
relayboard-web 2026.08.22.3
Workspacesws_amber · ws_cobalt
Rolesowner · dispatcher · observer
Objectsjob · export · magic link
Test materialSynthetic records and mail sink

In scope

  • Authenticated role and tenant boundaries on the named web/API surface.
  • Owned test identities and synthetic objects only.
  • Bounded read and reversible workflow-state effects.

Out of scope

  • Source code, cloud configuration, internal networks, availability testing, and third-party assets.
  • Real customer records, real payments, persistence, messaging, and destructive actions.
Effect ceiling
Synthetic object read and reversible state transition. No real-user or financial effect permitted.
Stop conditions
Unexpected customer data, live credentials, real-money paths, service instability, or an unapproved host stop the test and trigger redaction/escalation.
Methodology registry
Defence external review model 1.0 · OWASP WSTG 4.2 · OWASP API Security Top 10 2023 · HackTricks snapshot 2026-08-18

Findings register

Three reproduced conditions, ordered by decision urgency. Current state is independent from severity.

IDFindingExpected propertySeverityCurrent state
SYN-01Cross-workspace export downloadSession workspace, route workspace, and export owner must match before a download is issued.HighClosed under retest
SYN-02Observer closes jobs through a sibling operationOnly dispatcher or owner may move a job into closed state across every operation in the route family.MediumPartially remediated
SYN-03Magic link can be consumed twiceOne synthetic magic link creates at most one authenticated session, including concurrent consumption.MediumFixed — not retested
SYN-01HighClosed under retest

Cross-workspace export download

Closed for the named condition on build 2026.08.22.3. Reopen after material changes to export authorization or storage routing.

Expected propertySession workspace, route workspace, and export owner must match before a download is issued.
Affected route familyGET /v2/workspaces/{workspace_id}/exports/{export_id}/download
Actor and preconditionsobserver in ws_amber using an owned test session
  • Synthetic export exp_042 belongs to ws_cobalt.
  • The test actor has no membership in ws_cobalt.

Three ownership signals must agree.

The session, route, and export record define one workspace boundary. A file is returned only when all three resolve to the same owned workspace.

EvidenceEV-101

The route workspace did not constrain the export lookup.

Changing only the synthetic export identifier returned a file owned by ws_cobalt to the ws_amber observer.

EvidenceEV-101 · EV-102

The lookup and policy were bound to the workspace.

The remediation requires a composite lookup and authorization before response streaming—not a hidden link or changed client message.

EvidenceEV-103

Denied and allowed controls now separate correctly.

The foreign export returned 404 with no body; the same-workspace owner control still returned the synthetic file.

EvidenceEV-103

Evidence

EV-101 · EV-102 · EV-103

Synthetic request excerptSynthetic evidence
GET /v2/workspaces/ws_cobalt/exports/exp_042/download
Cookie: session=<REDACTED TEST SESSION>
X-Test-Workspace: ws_amber

Bounded excerpt · no public verification hash

Synthetic response excerptSynthetic evidence
HTTP/2 200
content-type: text/csv
content-length: 183
body: <SYNTHETIC EXPORT EXCERPT>

Bounded excerpt · no public verification hash

Control observationSynthetic evidence
ws_amber owner + exp_amber_017 → 200
ws_amber observer + exp_042 → 200 before fix
same session; only workspace/export pair changed

Bounded excerpt · no public verification hash

Consequence boundary

Expected
The foreign export is not returned and no object-existence detail crosses the workspace boundary.
Observed
The ws_amber observer received the invented ws_cobalt CSV export with HTTP 200.
Demonstrated
A user from one synthetic workspace read a file owned by another synthetic workspace.
Possible, not demonstrated
The same condition could expose other exports addressed by predictable or disclosed identifiers.
Not demonstrated
No real customer export was requested, observed, inferred, or retained. Identifier discovery breadth was not tested.
Observed contributing condition

The download lookup accepted export_id without binding it to the route workspace before file delivery.

Root cause not assessed

External behavior was assessed. Internal source, framework policy composition, and deployment configuration were not reviewed.

Remediation

Resolve the export by workspace_id + export_id, apply the authorization policy before streaming, and return one neutral not-found boundary.

Beforeobserver + foreign export → 200 + file
Afterobserver + foreign export → 404 + no body
Controlowner + own export → 200 + file

Retest matrix

PathExpectedObservedEvidenceRecorded result
observer · ws_amber → exp_042 · ws_cobalt404 · empty body404 · empty bodyEV-103Restored
owner · ws_amber → exp_amber_017200 · synthetic CSV200 · synthetic CSVEV-103Control held

Targeted retest closes the recorded condition; it is not a new full assessment of the changed build.

Finding history

  1. Property break reproduced twiceEV-101 · EV-102
    Confirmed
  2. Remediation reported on new buildBuild note
    Retest required
  3. Denied and allowed controls replayedEV-103
    Closed under retest
SYN-02MediumPartially remediated

Observer closes jobs through a sibling operation

Fix now. The property remains broken while bulk-close accepts observer; the finding cannot be marked closed.

Expected propertyOnly dispatcher or owner may move a job into closed state across every operation in the route family.
Affected route familyPOST /v2/workspaces/{workspace_id}/jobs/{job_id}/closePOST /v2/workspaces/{workspace_id}/jobs/bulk-close
Actor and preconditionsobserver in ws_amber with two owned synthetic jobs
  • Both jobs begin in in_progress state.
  • The UI does not show close actions to observer.

One role rule spans the complete operation family.

Hiding an action in the UI is not the control. Both single and bulk state transitions must enforce the same server-side permission.

EvidenceEV-201

Direct requests crossed the hidden UI boundary.

The observer changed synthetic job state on both handlers even though the client exposed neither action.

EvidenceEV-201 · EV-202

Only the single route received the policy.

The first remediation changed one handler. That is progress, but it does not restore a property defined across the route family.

EvidenceEV-203

The sibling route keeps the finding open.

Single close denied observer and allowed dispatcher. Bulk-close still accepted observer, so the current state is partially remediated.

EvidenceEV-203 · EV-204

Evidence

EV-201 · EV-202 · EV-203 · EV-204

Synthetic request excerptSynthetic evidence
POST /v2/workspaces/ws_amber/jobs/bulk-close
Cookie: session=<REDACTED TEST SESSION>
body: { job_ids: [job_amber_204] }

Bounded excerpt · no public verification hash

Synthetic response excerptSynthetic evidence
HTTP/2 202
body: { accepted: 1 }
observed state: job_amber_204 = closed

Bounded excerpt · no public verification hash

Control observationSynthetic evidence
observer + single close → 403 after fix
dispatcher + single close → 202
observer + bulk-close → 202 after fix

Bounded excerpt · no public verification hash

Consequence boundary

Expected
Observer receives a denial and both jobs remain in_progress on single and bulk operations.
Observed
Before remediation both routes accepted observer. Retest denied the single route, but bulk-close still returned 202 and closed the second synthetic job.
Demonstrated
An observer changed owned synthetic job state through a server operation reserved for dispatcher/owner.
Possible, not demonstrated
Other sibling workflow operations may enforce the same property inconsistently.
Not demonstrated
Only the named close family and owned synthetic jobs were tested. No customer job or external side effect was involved.
Observed contributing condition

Authorization was added to one handler rather than to the shared state-transition policy used by the route family.

Root cause not assessed

Handler behavior supports this contributing condition; source-level control placement was not independently verified.

Remediation

Apply one server-side transition policy to single and bulk operations, verify the current state atomically, then replay every actor × operation control.

Beforeobserver + single/bulk close → 202 + state change
Afterobserver + single close → 403 · bulk-close → 202
Requiredobserver + every close operation → 403 + unchanged

Retest matrix

PathExpectedObservedEvidenceRecorded result
observer → jobs/{id}/close403 · unchanged403 · unchangedEV-203Restored
dispatcher → jobs/{id}/close202 · closed202 · closedEV-203Control held
observer → jobs/bulk-close403 · unchanged202 · closedEV-204Still broken

Targeted retest closes the recorded condition; it is not a new full assessment of the changed build.

Finding history

  1. Single and bulk breaks reproducedEV-201 · EV-202
    Confirmed
  2. Single-route policy deployedBuild note
    Remediation reported
  3. Route-family retest found residual breakEV-203 · EV-204
    Partially remediated
SYN-03MediumFixed — not retested

Magic link can be consumed twice

Do not close. Replay sequential and concurrent matrices on the named build and retain one allowed-path control.

Expected propertyOne synthetic magic link creates at most one authenticated session, including concurrent consumption.
Affected route familyPOST /v2/auth/magic-links/{token}/consume
Actor and preconditionsowned test recipient using a synthetic mail sink
  • One synthetic link is issued for test_user_07.
  • No real mailbox, token, or session value is retained in this report.

One capability may create one session.

The token reference is a single-use capability. Consumption and session issuance must behave as one atomic decision.

EvidenceEV-301

The same link reference issued a second session.

Two sequential requests both succeeded. Only session references and response metadata were retained.

EvidenceEV-301 · EV-302

An atomic consume change was reported.

The team reports moving single-use state ahead of session issuance. This is remediation input, not observed closure evidence.

Evidence

The matrix is defined but has not run.

The report keeps the finding open until one allowed consume and sequential/concurrent denied replays produce evidence on the named build.

Evidence

Evidence

EV-301 · EV-302

Synthetic request excerptSynthetic evidence
POST /v2/auth/magic-links/<SYNTHETIC TOKEN REF>/consume
attempt 1 → 201 · session_ref_A
attempt 2 → 201 · session_ref_B

Bounded excerpt · no public verification hash

Synthetic response excerptSynthetic evidence
token value: not retained
session values: not retained
two distinct synthetic session references recorded

Bounded excerpt · no public verification hash

Control observationSynthetic evidence
fresh link + first consume → expected 201
same link + second consume → observed 201
concurrent replay → not tested

Bounded excerpt · no public verification hash

Consequence boundary

Expected
The first valid consume creates one session; every later consume fails without creating another session.
Observed
Two sequential consume requests against the same synthetic token reference each created a distinct test session.
Demonstrated
A single synthetic authentication capability was replayed to create two owned test sessions.
Possible, not demonstrated
A copied or delayed link could remain useful after its first successful use.
Not demonstrated
Only sequential replay on owned test material was demonstrated. Concurrent race behavior and real mail delivery were not tested.
Observed contributing condition

The consume behavior did not make single-use state visible before issuing the second session.

Root cause not assessed

Atomicity and transaction placement are remediation hypotheses; no source or datastore transaction was observed.

Remediation

Reported fix: mark the link consumed atomically before session issuance and reject every later or concurrent consume.

Observedsame link → session A + session B
Reported fixatomic consume before session issuance
Required evidence201 once · later/concurrent attempts denied

Retest matrix

PathExpectedObservedEvidenceRecorded result
fresh link → first consume201 · one sessionNot runPending
same link → sequential replaydenied · zero new sessionsNot runPending
same link → concurrent replayone success maximumNot runPending

Targeted retest closes the recorded condition; it is not a new full assessment of the changed build.

Finding history

  1. Sequential replay reproduced twiceEV-301 · EV-302
    Confirmed
  2. Atomic consume change reportedBuild note
    Fixed — not retested

Coverage ledger

15 recorded directions · 12 applicable. Every row keeps its applicability rationale, exact test, evidence, disposition, and limit.

5Finding-linked direction
5Held under test
1Blocked
1Out of scope
1Unknown
2Not applicable
DirectionExpected propertyApplicabilityExact testRecorded resultDispositionLimit
IDENT-01Identity and sessionsSession termination invalidates the owned test session.ApplicableSession endpoints are present.TC-011Logout then replay the same session reference.Replay denied.Held under testOther devices and long-lived sessions were not assessed.
IDENT-04Identity and sessionsMagic link is single use.ApplicableMagic-link authentication is present.TC-301Consume one owned synthetic link twice.Two sessions created.EV-301 · EV-302Finding-linked directionConcurrent replay remains untested.
IDENT-06Identity and sessionsRepeated authentication attempts are bounded.ApplicablePublic authentication route exists.TC-061Bounded throttling window.Permission window not granted.BlockedResume after an approved request-rate ceiling.
AUTHZ-02Authorization and tenant isolationWorkspace ownership constrains export downloads.ApplicableMulti-workspace export route is present.TC-101Cross-workspace identifier substitution with owned actors.Break reproduced; closed on targeted retest.EV-101 · EV-102 · EV-103Finding-linked directionClosure applies to the named route/build only.
AUTHZ-03Authorization and tenant isolationRole gates apply to every close operation.ApplicableObserver, dispatcher and owner roles are present.TC-201Actor × single/bulk operation matrix.Bulk sibling remains broken.EV-201 · EV-202 · EV-203 · EV-204Finding-linked directionOther workflow families were sampled separately.
FLOW-02Workflows and stateClosed transition requires an allowed role and current state.ApplicableJob state workflow is present.TC-204Denied/allowed actors across sibling operations.Partially remediated.EV-203 · EV-204Finding-linked directionNo destructive or external job effects were triggered.
FLOW-04Workflows and stateSingle-use state is atomic.ApplicableMagic-link consume changes authentication state.TC-302Sequential replay; concurrent replay planned.Sequential break reproduced; fix not retested.EV-301 · EV-302Finding-linked directionConcurrency remains unknown.
INPUT-03Input and server behaviorUpload type is validated from content and bounded size.ApplicableSynthetic attachment upload is present.TC-403Mismatched extension/content and bounded oversized fixture.Rejected before storage.EV-401Held under testMalware processing and downstream previewers were out of scope.
API-02APIs and integrationsUnsigned webhook cannot change a job.ApplicableSynthetic inbound webhook is present.TC-502Unsigned and expired synthetic events.Rejected before state change.EV-501Held under testProvider delivery and replay behavior were not assessed.
SERVER-01Input and server behaviorUnhandled identifiers do not disclose stack details.ApplicableParameterized public routes are present.TC-601Malformed and unknown synthetic identifiers.Neutral 404/400 responses.Held under testNon-HTTP service errors were not assessed.
EXPOSURE-01External exposureNamed surface does not expose backup or debug artifacts.ApplicablePublic web/API hosts are in scope.TC-701Known artifact paths and discovered public references.No artifact reproduced.Held under testObserved adjacent hosts remained passive inventory.
API-06APIs and integrationsGraph query authorization is enforced.Not applicableNo graph endpoint or client reference was discovered.Applicability discovery only.Not present in frozen surface.Not applicableReassess if a graph endpoint is added.
PAY-01PaymentsPayment state transitions enforce amount and actor rules.Not applicableRelayboard synthetic system contains no payment feature.Applicability discovery only.No payment surface present.Not applicableNo conclusion about external billing systems.
THIRD-01Third-party effectsExternal messaging does not accept unauthorized triggers.ApplicableA production messaging integration is referenced.TC-801Passive configuration and route review only.Active delivery excluded by effect ceiling.Out of scopeRequires separate authority and a synthetic provider sink.
SESSION-09Identity and sessionsSession behavior after credential rotation is bounded.UnresolvedCredential-rotation behavior was not observable externally.External observation with owned accounts.No reliable disposition.UnknownNeeds a controlled rotation event or source/config evidence.

Held controls

HELD-01Unsigned webhook events cannot change synthetic job state.Held under test
Condition
Unsigned and expired events sent to the owned synthetic workspace.
Observed
Both were rejected before the synthetic job changed.
Evidence
EV-501
Limit
Provider-origin delivery, retry, and replay were not assessed.
HELD-02Mismatched upload content is rejected before storage.Held under test
Condition
Owned text fixture declared as image plus bounded oversized fixture.
Observed
Both returned a validation response and no stored object reference.
Evidence
EV-401
Limit
Malware scanning and downstream rendering were outside scope.

Limits and appendices

All systems, names, routes, identifiers, records, timestamps, responses, and outcomes in this public report were created for this clean-room illustration. The sample demonstrates Defence report structure and reasoning, not a customer outcome, certification, or independent validation of Defence.

Limitations and unknowns

External behavior only

No source code, infrastructure-as-code, cloud policy, internal service, or employee workflow was reviewed.

Add a separately scoped internal review if those conclusions are required.

Named builds only

Assessment and retest observations apply to the exact builds and conditions recorded in each finding.

Material authorization, routing, identity, or workflow changes reopen affected directions.

Rate-limit blocker

The approved effect ceiling did not include the request rate needed for a meaningful throttling test.

Approve a bounded window, maximum rate, stop threshold, and contact.

No absolute assurance

Complete applicable coverage records a disposition for every applicable direction in the frozen scope. It does not prove that every vulnerability is absent.

Reassess after material product change or when new authority/evidence changes applicability.

Evidence index

IDType / relationCurrent buildTimestampHandling / lineage
EV-101Request/response excerptSYN-01 · TC-101relayboard-web 2026.08.18.52026-08-18 10:14 UTCSession value and body minimizedSynthetic evidence
EV-102Reproduction controlSYN-01 · TC-102relayboard-web 2026.08.18.52026-08-18 10:22 UTCSynthetic identifiers onlyDerived from EV-101
EV-103Retest matrixSYN-01 · TC-103relayboard-web 2026.08.22.32026-08-22 09:18 UTCResponse bodies minimizedDerived from EV-101
EV-201Single-route reproductionSYN-02 · TC-201relayboard-web 2026.08.18.52026-08-18 13:06 UTCOwned job onlySynthetic evidence
EV-202Sibling-route reproductionSYN-02 · TC-202relayboard-web 2026.08.18.52026-08-18 13:19 UTCOwned job onlyDerived from EV-201
EV-203Single-route retestSYN-02 · TC-203relayboard-web 2026.08.22.32026-08-22 10:02 UTCOwned roles and jobsDerived from EV-201
EV-204Sibling-route retestSYN-02 · TC-204relayboard-web 2026.08.22.32026-08-22 10:11 UTCOwned roles and jobsDerived from EV-202
EV-301Sequential replay excerptSYN-03 · TC-301relayboard-web 2026.08.18.52026-08-19 08:44 UTCToken and sessions not retainedSynthetic evidence
EV-302Reproduction controlSYN-03 · TC-302relayboard-web 2026.08.18.52026-08-19 08:51 UTCReferences onlyDerived from EV-301
EV-401Upload controlINPUT-03 · TC-403relayboard-web 2026.08.18.52026-08-19 11:05 UTCSynthetic fixtures onlySynthetic evidence
EV-501Webhook controlAPI-02 · TC-502relayboard-web 2026.08.18.52026-08-19 12:27 UTCSynthetic event IDsSynthetic evidence

Bounded excerpt · no public verification hash

Methodology registry

Defence external review model1.0
Scope, property graph, evidence, dispositions, and terminal honesty.
OWASP Web Security Testing Guide4.2
Web testing direction and method reference.
OWASP API Security Top 102023
API authorization, resource, flow, and inventory lenses.
HackTrickssnapshot 2026-08-18
Technique prompts; never evidence by itself.

Revision history

  1. v0.9Assessment draft

    Initial findings and coverage ledger.

  2. v1.0Final illustrative report

    Remediation inputs, targeted retest, and current-state projection added without overwriting initial evidence.