Security Advisory: Batch Job Privilege Escalation (v1.0.5)
Security Advisory: Batch Job Privilege Escalation
Advisory ID: SA-2025-001
Fixed in: v1.0.5
Severity: Critical
Affected versions: All versions prior to v1.0.5
Affected file: src/platform/batches/router.ts
Summary
A privilege escalation vulnerability was identified in the batch job router. All five batch procedures — batches.list, batches.runs, batches.trigger, batches.setStatus, and batches.sync — were protected only by protectedProcedure, which checks authentication but does not enforce organisation membership, role requirements, or tenant isolation.
Any authenticated user could exploit this to interact with batch jobs belonging to any organisation in the system, including triggering destructive system-level cron jobs.
Vulnerability Details
Root Cause
The batch router used protectedProcedure as the sole authorization gate across all endpoints. This procedure confirms that a valid session exists, but it does not:
- Verify the user belongs to the organisation that owns the batch job
- Check whether the user holds an
adminorownerrole - Distinguish between tenant-scoped and system-level operations
Impact
An attacker with any valid user account could:
- Enumerate batch jobs across all tenants via
batches.list - Inspect run histories for any organisation via
batches.runs - Trigger any batch job via
batches.trigger, including:- The audit-log cleanup cron (resulting in deletion of all audit logs across the platform)
- The subscription-sync job (disrupting billing state for other tenants)
- Pause, resume, or cancel any batch job via
batches.setStatus - Force a sync of any batch job via
batches.sync
This constitutes both a data integrity risk (batch jobs can be triggered or cancelled outside of their normal schedule) and a data loss risk (destructive cron jobs can be executed by unauthorised users).
Affected Procedures
batches.list
batches.runs
batches.trigger
batches.setStatus
batches.sync
All located in: src/platform/batches/router.ts
Remediation
v1.0.5 upgrades the authorization guards on all affected procedures:
batches.list,batches.runs,batches.trigger,batches.setStatusare now gated byadminProcedureorownerProcedure, which enforce that the requesting user holds the appropriate role within the correct organisation.batches.syncand other system-level job procedures are now gated by a newsystemAdminProcedure, which additionally checks a superadmin flag on the user record. This ensures platform-wide operations cannot be invoked by any regular or org-level admin.
Before (vulnerable)
// src/platform/batches/router.ts
export const batchesRouter = router({
list: protectedProcedure.query(...),
runs: protectedProcedure.query(...),
trigger: protectedProcedure.mutation(...),
setStatus: protectedProcedure.mutation(...),
sync: protectedProcedure.mutation(...),
});
After (fixed)
// src/platform/batches/router.ts
export const batchesRouter = router({
list: adminProcedure.query(...),
runs: adminProcedure.query(...),
trigger: adminProcedure.mutation(...),
setStatus: ownerProcedure.mutation(...),
sync: systemAdminProcedure.mutation(...),
});
Recommended Actions
For all deployments
- Upgrade to v1.0.5 immediately.
- Review your audit logs for unexpected calls to the affected procedures from non-admin users. Focus on:
batches.trigger— look for executions outside of normal scheduled windowsbatches.setStatus— look for unexpected pause, resume, or cancel eventsbatches.sync— look for manual sync invocations from non-system accounts
- Verify audit log integrity. If the audit-cleanup cron was triggered by an unauthorised user, audit log data may have been deleted. Cross-reference with any external log aggregation (e.g. your HMRC MTD submission records) to detect gaps.
- Check subscription state. If
batches.syncwas invoked unexpectedly, review your AgentOS and HMRC MTD subscription sync records for any discrepancies.
For self-hosted deployments
- Ensure your
userstable includes asuperadminboolean column, as the newsystemAdminProcedurereads this field. The v1.0.5 migration handles this automatically for managed deployments. - Review any custom role assignments to ensure no regular members have been incorrectly granted
adminorownerroles that would now give them batch job access.
Timeline
| Date | Event |
|---|---|
| Identified | Vulnerability discovered during internal security review |
| Fixed | Patch implemented in src/platform/batches/router.ts |
| Released | v1.0.5 published |
References
- Changelog — v1.0.5
- HMRC Making Tax Digital API: https://developer.service.hmrc.gov.uk/api-documentation
- AgentOS API integration documentation: see AgentOS Integration