🛡️ CVE-2026-55177 — cloudtak

🟠 CVSS 8.0 — High ✅ No Known Exploit CWE-918 OSV
8.0
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

CloudTAK: Authenticated full-read SSRF in the /api/esri* routes — user-controlled URL fetched with no IP-classification guard

# Authenticated full-read SSRF in CloudTAK /api/esri* routes — user-controlled URL fetched with no IP-classification guard

Summary

Every route in the ESRI helper family (api/routes/esri.ts) takes a fully attacker-controlled URL from the request (POST /api/esri body url, and the portal / server / layer query parameters on the GET /api/esri/* routes) and passes it into EsriBase / EsriProxyPortal / EsriProxyServer / EsriProxyLayer in api/lib/esri.ts, which fetch it with the bare fetch from @tak-ps/etl. No IP / DNS / hostname classification is applied at any point, so the destination is never validated against private, loopback, or link-local ranges.

Any authenticated user (the routes only require Auth.is_auth(config, req, { anyResources: true }), i.e. any token, not an admin) can therefore make the CloudTAK server issue arbitrary outbound GET/POST requests to internal addresses such as the cloud instance-metadata service (169.254.169.254), loopback admin ports (127.0.0.1:<port>), and other hosts reachable only from inside the deployment VPC.

This is a full-read SSRF, not blind: on success the upstream JSON body is returned to the caller via res.json(...), and on failure the upstream error string is reflected verbatim as ESRI Server Error: <message>. An attacker can read cloud metadata (and the temporary IAM credentials the instance role exposes), enumerate internal services, and exfiltrate their response bodies.

The sniff() URL classifier provides no protection: it only pattern-matches the *pathname* (/rest, /arcgis/rest, /sharing/rest), so a URL like http://169.254.169.254/arcgis/rest or http://127.0.0.1:8500/rest passes sniff() and is fetched.

Affected versions

  • All versions up to and including 13.7.0 (latest at time of report).

The project already ships an SSRF guard helper — isSafeUrl from @tak-ps/node-safeurl — and wires it into the basemap, task, and video-service code paths, but the entire /api/esri* route family and the ESRI fetch library (api/lib/esri.ts) were never wired up, leaving the guard absent on this surface.

Vulnerable code

All permalinks are pinned to commit c7433679d2107fa0258e9005069bc5b4ca5773aa (release lineage of 13.7.0).

Routes — user input → ESRI fetch, no guard (api/routes/esri.ts):

  • POST /api/esri — body urlnew URL(req.body.url)EsriBase.from(url):

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/routes/esri.ts#L32-L64

  • GET /api/esri/portal — query portalnew EsriBase(req.query.portal)EsriProxyPortal.getPortal():

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/routes/esri.ts#L79-L98

  • GET /api/esri/portal/content — query portalEsriProxyPortal.getContent():

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/routes/esri.ts#L115-L139

  • GET /api/esri/portal/server — query portalEsriProxyPortal.getServers():

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/routes/esri.ts#L191-L212

  • GET /api/esri/server — query serverEsriProxyServer.getList():

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/routes/esri.ts#L225-L249

  • GET /api/esri/server/layer — query layerEsriProxyLayer.sample():

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/routes/esri.ts#L333-L356

Library — the fetch sinks (api/lib/esri.ts), all reached with the user URL and none preceded by a guard:

  • import { fetch } from '@tak-ps/etl';

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/lib/esri.ts#L6

  • EsriBase.fetchVersion()const res = await fetch(url);

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/lib/esri.ts#L162-L187

  • EsriBase.generateToken()fetch(url, { method: 'POST', ... })

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/lib/esri.ts#L107

  • EsriProxyPortal.getContent / getPortal / getSelf / getServers / createServicefetch at lines 283, 301, 330, 347, 371
  • EsriProxyServer.deleteLayer / createLayer / getListfetch at lines 407, 433, 455
  • EsriProxyLayer.tilejson / #sampleFeaturesfetch at lines 503, 552

sniff() only inspects the pathname (no host/IP check):

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/lib/esri.ts#L142-L156

The guard exists elsewhere but is missing here — for comparison, the basemap import path classifies the URL before fetching:

https://github.com/dfpc-coe/CloudTAK/blob/c7433679d2107fa0258e9005069bc5b4ca5773aa/api/routes/basemap.ts#L85-L90

Note also that

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. Rated impact: confidentiality high, integrity high, availability none.

Weakness class

CVE-2026-55177 is classified as CWE-918: Server-Side Request Forgery (SSRF). The server fetches a URL supplied by the caller, which can be pointed at internal systems it alone can reach.

Affected software

CVE-2026-55177 is recorded against 1 package.

  • @tak-ps/cloudtak

Timeline and source

Published on 17 July 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.

References

github.com (Web)
github.com (Package)
github.com (Web)

Details

Severity HIGH
CVSS Score 8.0
CVSS Vector CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
CWE CWE-918
Public Exploit ✅ No
Source OSV
Published 2026-07-17
Updated 2026-08-12
Modified 2026-07-17
Fix URL N/A

Affected Packages

Software From version Fixed in
@tak-ps/cloudtak

Similar Threats

Site Security Check

Is cloudtak part of your stack?

CVE-2026-55177 is rated CVSS 8.0 High. BotEraser scans your installation against known CVE records and tells you whether this vulnerability applies to the versions you actually run.

Scan My Site Free →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.