All Docs
FeaturesMaking Tax DigitalUpdated February 24, 2026

Security Advisory: NI Number Transmitted via URL Query Parameter

Security Advisory: NI Number Transmitted via URL Query Parameter

Severity: High
Version affected: ≤ 1.0.39
Affected file: src/app/api/hmrc/authorise/route.ts
Status: Remediation required


Summary

The HMRC OAuth authorisation flow exposes the landlord's National Insurance (NI) number as a plain-text URL query parameter. This constitutes a serious data exposure risk under GDPR and is incompatible with HMRC's data-handling requirements for the Making Tax Digital API.


Background

To authenticate with the HMRC Making Tax Digital API, the application must initiate an OAuth 2.0 authorisation flow on behalf of the landlord. As part of this flow, the landlord's NI number is required by HMRC to identify the individual taxpayer.

In the current implementation, this NI number is passed to the authorisation endpoint as a URL query parameter:

GET /api/hmrc/authorise?ni_number=AB123456C

The NI number is also embedded within the redirect URL constructed by the HMRC tRPC getAuthoriseUrl procedure, meaning the value appears in the URL passed to HMRC's own authorisation server.


Risk Analysis

Data Classification

The National Insurance number is:

  • Highly sensitive PII under UK GDPR and the Data Protection Act 2018
  • A mandatory credential required by HMRC for Making Tax Digital submissions
  • Sufficient, in combination with basic personal details, to enable identity fraud

Exposure Surfaces

URL query parameters are exposed across numerous surfaces by default, many of which are outside the application's control:

SurfaceExposure mechanism
Server access logsFull request URL logged on every request
Browser historyURL persisted locally on the user's device
CDN / reverse-proxy logsEdge infrastructure logs full upstream URLs
HTTP Referer headerAppended automatically on navigation to third-party pages
Analytics & monitoring toolsURL parameters captured by APM, error tracking, and analytics platforms

Affected Code

File: src/app/api/hmrc/authorise/route.ts

The NI number is read from the incoming request's query string and subsequently embedded into the HMRC OAuth redirect URL via the getAuthoriseUrl tRPC call.


Recommended Remediation

NI numbers must never appear in URLs. Replace the query-parameter approach with a server-side session nonce pattern:

Step 1 — Store the NI number server-side before the redirect

Before redirecting the user to HMRC's authorisation endpoint, persist the NI number in a short-lived server-side session (e.g. Redis, an encrypted database record, or an in-memory store with a TTL of ~10 minutes). Key the record by a cryptographically random nonce:

import { randomBytes } from 'crypto';

const nonce = randomBytes(32).toString('hex');
await sessionStore.set(nonce, { niNumber }, { ttl: 600 }); // 10-minute TTL

Step 2 — Pass only the nonce in the OAuth state parameter

Set the nonce as an HTTP-only, Secure, SameSite cookie and include it in the OAuth state parameter. Do not include the NI number anywhere in the URL:

response.cookies.set('oauth_state', nonce, {
  httpOnly: true,
  secure: true,
  sameSite: 'lax',
  maxAge: 600,
  path: '/',
});

// Build the HMRC redirect URL using only the nonce as state
const authoriseUrl = buildHmrcAuthoriseUrl({ state: nonce });
return Response.redirect(authoriseUrl);

Step 3 — Retrieve the NI number during the callback

In the OAuth callback handler, read the nonce from the state cookie, look up the NI number from the session store, and immediately delete the session record:

const nonce = request.cookies.get('oauth_state')?.value;
if (!nonce) return unauthorised();

const session = await sessionStore.get(nonce);
if (!session) return unauthorised(); // expired or tampered

await sessionStore.delete(nonce); // single-use — delete immediately
const { niNumber } = session;

Additional hardening

  • Validate that the state parameter returned by HMRC in the callback matches the cookie value before proceeding.
  • Ensure the session store TTL is as short as practically possible.
  • Audit server, CDN, and proxy log retention policies to determine whether NI numbers from previous requests need to be purged from existing logs.

Compliance Notes

RequirementStatus
UK GDPR — data minimisation (Art. 5(1)(c))❌ NI number unnecessarily exposed in URL
UK GDPR — integrity and confidentiality (Art. 5(1)(f))❌ PII transmitted in a form not protected against inadvertent disclosure
HMRC MTD data-handling requirements❌ Sensitive identifier present in loggable request URLs

References