Skip to content

fix(activation-service): remove unauthenticated /create-entity route (crash + wallet-drain)#1103

Merged
sameh-farouk merged 2 commits into
developmentfrom
fix/activation-service-remove-create-entity
Jun 2, 2026
Merged

fix(activation-service): remove unauthenticated /create-entity route (crash + wallet-drain)#1103
sameh-farouk merged 2 commits into
developmentfrom
fix/activation-service-remove-create-entity

Conversation

@sameh-farouk

@sameh-farouk sameh-farouk commented Jun 2, 2026

Copy link
Copy Markdown
Member

Removes the POST /activation/create-entity route and its now-unused import.

Why

The endpoint is an unauthenticated relayer that signs and submits a fee-paying createEntity extrinsic from the service's funded wallet on every request. Two issues:

  1. Already broken → any call is a DoS. On the current runtime the client's getEntityIDByName/getEntityIDByPubkey query renamed/removed storage (entitiesByNameID/entitiesByPubkeyID) and throw is not a function. The route has no .catch(next) and the lookups run outside the controller's try/catch, so the unhandled rejection crashes the whole service. Reproduced live: a single request → process exit. So with the currently-deployed client this endpoint is 100% broken and crash-on-call.
  2. Wallet drain. Even with a fixed client, every call makes the service sign + submit an extrinsic whose fee is paid by the funding wallet (charged even on failure — observed paysFee: "Yes"). Unauthenticated, no rate limit → spamming it drains the activation wallet.

Why remove, not fix

  • It serves no current flow: the UI calls only /activate, there is no in-repo caller, it's not in spec.md, and entities are a legacy concept. Untouched since 2023 (feat: move activation service here #652).
  • Fixing the crash wouldn't remove the wallet-drain — the endpoint inherently spends the wallet's funds on unauthenticated input. Removing the route eliminates both vectors at zero functional cost.

Change

  • Deleted the router.post('/create-entity', …) block and dropped createEntity from the controller import. Added a comment explaining the removal.
  • Verified: routes module loads, /activate intact, standard lint clean.

Notes

  • Dead code removed in this PR too: the createEntity controller fn (+ its now-unused first/SUBSTRATE_ERRORS imports), lib/schemas/create-entity.js, and lib/errors.js (only createEntity used it). Verified: controller exports only activate, routes load, standard lint clean.
  • Deployment matters: production is currently running the old code with this endpoint exposed, so this should be deployed, not just merged.
  • Related (separate): /activate is also a wallet-spending endpoint; worth confirming KYC-signature enforcement is actually wired (the spec requires it; the controller I read just checks balance + transfers).

🤖 Generated with Claude Code

The POST /create-entity endpoint was an unauthenticated relayer that signed and
submitted a fee-paying `createEntity` extrinsic from the service wallet on every
request. It had two problems:

- It was already broken on the current runtime: the client's entity lookups
  query renamed/removed storage (entitiesByNameID/entitiesByPubkeyID), so every
  call threw `is not a function`. The route has no .catch and the lookups run
  outside the controller's try/catch, so an unhandled rejection crashed the whole
  service — i.e. any single call is a DoS.
- Even once the client is fixed, every call makes the service sign and submit an
  extrinsic whose fee is paid by the funding wallet (charged even on failure),
  so spamming it drains the wallet — an unauthenticated financial DoS.

It serves no current flow: the UI calls only /activate, there is no in-repo
caller, it is not in the service spec, and entities are a legacy concept. Remove
the route (and its now-unused import) rather than fix it, to eliminate the crash
and wallet-drain attack surface. The createEntity controller fn and create-entity
schema are now orphaned and can be removed in a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sameh-farouk sameh-farouk requested a review from LeeSmet as a code owner June 2, 2026 14:29
Follow-up to removing the /create-entity route: delete the now-unreferenced
code it was the only user of.

- controllers/substrate.js: remove the createEntity function, drop it from
  exports, and remove the now-unused `first` (lodash) and `SUBSTRATE_ERRORS`
  imports. `httpError` and `client` are kept (still used by activate).
- lib/schemas/create-entity.js: deleted (no longer validated against).
- lib/errors.js: deleted (SUBSTRATE_ERRORS was only used by createEntity).

Verified: controller exports only `activate`, routes load, `standard` lint clean,
no dangling references.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sameh-farouk sameh-farouk merged commit a08dd29 into development Jun 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant