Audit Finding: Gov-Vendor-Public-IP Header May Be Absent in Production
Audit Finding: Gov-Vendor-Public-IP Header May Be Absent in Production
Release: v1.0.230
Severity: MEDIUM
Component: HMRC Fraud-Prevention Headers (src/lib/hmrc/fraud-prevention-headers.ts)
Background
HMRC's Making Tax Digital (MTD) API requires every request to carry a set of fraud-prevention headers. These headers allow HMRC to detect unusual or fraudulent submission patterns. One of the mandatory headers for the WEB_APP_VIA_SERVER connection method is:
Gov-Vendor-Public-IP: <public IP of the originating server>
Failure to include this header causes HMRC to return:
HTTP 403 INVALID_FRAUD_PREVENTION_HEADERS
…which blocks the submission entirely.
What Was Found
A routine depth-audit of the fraud-prevention header builder (src/lib/hmrc/fraud-prevention-headers.ts, line 101) revealed that when the VENDOR_PUBLIC_IP environment variable is not set, the code falls back to an empty string ("") rather than raising an error or omitting the build step gracefully.
The practical effect is that the Gov-Vendor-Public-IP header is sent with no value — or not sent at all — depending on how the HTTP client handles empty header values. Either outcome violates the HMRC fraud-prevention specification.
Affected Code Path
src/lib/hmrc/fraud-prevention-headers.ts (line 101)
└─ Gov-Vendor-Public-IP ← falls back to "" when VENDOR_PUBLIC_IP is unset
Risk Assessment
| Factor | Detail |
|---|---|
| Severity | Medium |
| Likelihood | High in environments where VENDOR_PUBLIC_IP was never explicitly configured |
| Impact | HMRC rejects MTD submissions with 403 INVALID_FRAUD_PREVENTION_HEADERS |
| Connection method | WEB_APP_VIA_SERVER (the method used by this application) |
| Data loss | None — submissions are rejected, not corrupted |
Immediate Actions for Operators
1. Verify your environment variables
Check that VENDOR_PUBLIC_IP is present in every environment that makes HMRC API calls:
# On your server / in your deployment pipeline
printenv VENDOR_PUBLIC_IP
If the command returns nothing, the variable is missing and submissions will fail.
2. Set the variable
Set VENDOR_PUBLIC_IP to the public-facing IP address of your application server — i.e. the IP that HMRC will see as the originating address.
# Example — replace with your actual public IP
VENDOR_PUBLIC_IP=203.0.113.42
For deployments with multiple egress IPs or a NAT gateway, use the static egress IP that HMRC will observe.
IPv6: HMRC accepts both IPv4 and IPv6 addresses. If your server has a static IPv6 egress address you may use that instead.
3. Confirm the header is being sent
After deploying, you can validate your fraud-prevention headers against HMRC's test endpoint:
GET https://test-api.service.hmrc.gov.uk/test/fraud-prevention-headers/validate
Authorization: Bearer <access_token>
A successful response will list all headers as VALID. Look specifically for Gov-Vendor-Public-IP in the validation report.
Frequently Asked Questions
Q: Will existing submitted returns be affected?
No. This issue only affects new submission attempts. Previously accepted submissions are unaffected.
Q: What if we're behind a load balancer or reverse proxy?
Use the public egress IP of your infrastructure — the IP that external services (including HMRC) see — not the internal/private IP of an individual server instance.
Q: Is this only a problem in production?
HMRC's sandbox (test) environment also validates fraud-prevention headers. Setting VENDOR_PUBLIC_IP in staging/test environments is equally important to catch this class of error before it reaches production.