Back to Intelligence

CVE-2026-70558: Dinky Arbitrary File Write via Hardcoded Token — Detection and Remediation Guide

SA
Security Arsenal Team
August 7, 2026
10 min read

NVD has published CVE-2026-70558, a CVSS 9.8 CRITICAL vulnerability in Dinky, the open-source real-time data integration and development platform built around Apache Flink. Dinky is deployed in data engineering environments worldwide — frequently inside Kubernetes clusters, frequently containerized via Docker images, and frequently reachable from broad internal network segments because data platforms tend to sit at the center of everything.

The mechanics are about as bad as it gets for a defenders' worst-case matrix:

  • A path-traversal-prone file upload endpoint (POST /download/uploadFromRsByLocal) writes caller-controlled content to a caller-controlled path.
  • The endpoint is explicitly excluded from authentication via @SaIgnore and a /download/** exclusion in the Sa-Token interceptor.
  • The only access control is a header equality check against dinkyToken — whose default value (efda1551-7958-4e0f-80a8-dfd107df3e38) is hardcoded in source and ships with every deployment.

Any remote, unauthenticated attacker who can reach Dinky's HTTP port (8888 by default) can write arbitrary files as the Dinky service account. That means web shell deployment, cron/SSH key planting, JAR drops, and — given Dinky's role orchestrating Flink jobs — a direct pivot into your data platform and everything it touches. If you run Dinky anywhere, treat this as an emergency change.

Technical Analysis

Affected Component

AttributeDetail
CVECVE-2026-70558
CVSS v3.x9.8 (CRITICAL) — Network vector
ProductDinky (real-time data development platform, commonly deployed with/around Apache Flink)
EndpointPOST /download/uploadFromRsByLocal
Default Port8888 (HTTP)
Auth MechanismHeader equality check against dinkyToken; route annotated @SaIgnore, /download/** excluded from Sa-Token interceptor
Default Tokenefda1551-7958-4e0f-80a8-dfd107df3e38 (hardcoded in source)

How the Vulnerability Works

The uploadFromRsByLocal handler takes the caller-supplied path parameter and passes it directly into new File(path) and file.transferTo(dest) with no path validation, no canonicalization, and no sandboxing to an upload directory. That is a textbook CWE-22 (Path Traversal) compounded by CWE-798 (Use of Hard-coded Credentials).

The authentication story makes it worse. The developers annotated the route with @SaIgnore and excluded /download/** from the Sa-Token interceptor chain — meaning the framework's session/auth machinery never touches the request. The bespoke fallback is a simple string comparison of an incoming header against the configured dinkyToken. Because the default token is a fixed UUID committed to the public source tree, every deployment that did not explicitly override it is effectively unauthenticated.

Exploitation requirements from the defender's perspective:

  1. Network reachability to the Dinky HTTP listener (default TCP/8888). No session, no credential, no user interaction.
  2. Knowledge of the token — which is public unless the operator changed it.
  3. A crafted POST to /download/uploadFromRsByLocal with an absolute or traversed relative path (e.g., ../../root/.ssh/authorized_keys, webroot JSP, systemd unit, cron entry) and attacker-controlled file content.

Result: arbitrary file write with the privileges of the Dinky service account. In containerized deployments this is frequently root inside the container; on bare-metal/VM installs it is whatever service account runs the JVM. Either way, arbitrary file write is one reliable step from code execution (web shells, overwriting jars, dropping scripts invoked by schedulers, Flink job submission abuse).

Exploitation Status

At time of writing, NVD has published the CVE with a 9.8 CRITICAL rating. Given that (a) the vulnerable route and the hardcoded default token are visible in the public source repository, (b) exploitation requires a single HTTP request, and (c) Dinky instances are routinely indexed by internet-scanning services, defenders should assume weaponization is trivial and imminent and operate as if exploitation is likely against internet-exposed instances. Do not wait for a CISA KEV listing to act — the bar for exploitation here is one curl command. Verify your exposure today.

Detection & Response

The highest-fidelity signals for this vulnerability are:

  1. HTTP requests to /download/uploadFromRsByLocal — this endpoint has essentially no legitimate high-volume use from unknown sources; any hit from outside your automation accounts is suspect.
  2. Requests carrying the hardcoded default token value — proof the attacker is using the shipped credential.
  3. The Dinky JVM process writing files outside its expected directories (webroots, /etc/cron.d, ~/.ssh, /tmp executables).
  4. The Dinky process spawning shells or unexpected child processes post-write (follow-on execution).

SIGMA Rules

YAML
---
title: Dinky CVE-2026-70558 Exploitation Attempt - uploadFromRsByLocal Access
description: Detects HTTP requests to the vulnerable Dinky /download/uploadFromRsByLocal endpoint, particularly with the hardcoded default dinkyToken. Exploitation allows unauthenticated arbitrary file write.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-70558
author: Security Arsenal
date: 2026/04/06
status: experimental
id: 3f9c2a71-5b84-4d1e-9a6c-7e2f8b1d4a55
tags:
  - attack.initial_access
  - attack.t1190
logsource:
  category: webserver
detection:
  selection_uri:
    cs-uri-stem|contains: '/download/uploadFromRsByLocal'
  selection_token:
    cs-headers|contains: 'efda1551-7958-4e0f-80a8-dfd107df3e38'
  condition: selection_uri or selection_token
falsepositives:
  - Legitimate Dinky administrative uploads from known automation accounts (tune by source IP)
level: critical
---
title: Dinky Service Process Writing Files Outside Application Directories
description: Detects the Dinky JVM process writing files to sensitive locations such as webroots, SSH authorized_keys, cron directories, or systemd paths - consistent with post-exploitation of CVE-2026-70558 arbitrary file write.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-70558
author: Security Arsenal
date: 2026/04/06
status: experimental
id: 8b1d4e62-2c7a-4f93-b5e1-9a3c6d7f2e88
tags:
  - attack.persistence
  - attack.t1505.003
  - attack.t1053.003
logsource:
  category: file_event
  product: linux
detection:
  selection_process:
    Image|contains:
      - 'java'
    CommandLine|contains:
      - 'dinky'
  selection_target:
    TargetFilename|contains:
      - '/.ssh/authorized_keys'
      - '/etc/cron'
      - '/etc/systemd/system/'
      - '/webapps/'
      - '.jsp'
      - '.war'
  condition: selection_process and selection_target
falsepositives:
  - Dinky upgrades or plugin deployments performed by administrators (correlate with change windows)
level: high
---
title: Dinky Java Process Spawning Shell or Interpreter
description: Detects the Dinky JVM spawning shells or scripting interpreters, a common follow-on behavior after arbitrary file write leads to code execution via web shell or dropped payload.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-70558
author: Security Arsenal
date: 2026/04/06
status: experimental
id: c4a7f1d9-6e3b-48d2-a1c5-5f9b2e7d3c11
tags:
  - attack.execution
  - attack.t1059
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentCommandLine|contains: 'dinky'
  selection_child:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/dash'
      - '/python'
      - '/python3'
      - '/perl'
      - '/curl'
      - '/wget'
  condition: selection_parent and selection_child
falsepositives:
  - Dinky job wrappers invoking shell scripts as part of legitimately configured tasks (baseline your environment)
level: high

KQL (Microsoft Sentinel / Defender)

This hunts two ways: first, web/proxy telemetry (ingested via CEF/Syslog from your reverse proxy, WAF, or Dinky's own access logs) for hits against the vulnerable endpoint or the hardcoded token; second, endpoint process lineage for the Dinky JVM spawning shells.

KQL — Microsoft Sentinel / Defender
// Hunt 1: Requests to the vulnerable endpoint or use of the hardcoded default token
let BadToken = "efda1551-7958-4e0f-80a8-dfd107df3e38";
union isfuzzy=true
    (CommonSecurityLog
    | where RequestURL has "uploadFromRsByLocal"
       or AdditionalExtensions has BadToken
       or RequestURL has BadToken
    | project TimeGenerated, SourceIP, DestinationIP, DestinationPort, RequestMethod, RequestURL, AdditionalExtensions),
    (Syslog
    | where SyslogMessage has "uploadFromRsByLocal" or SyslogMessage has BadToken
    | project TimeGenerated, Computer, HostIP, ProcessName, SyslogMessage)
| sort by TimeGenerated desc;

// Hunt 2: Dinky JVM spawning shells/interpreters (Linux hosts reporting to Defender for Endpoint)
DeviceProcessEvents
| where InitiatingProcessCommandLine has "dinky"
   and (FileName in~ ("sh", "bash", "dash", "python", "python3", "perl", "curl", "wget")
        or ProcessCommandLine has_any ("/etc/cron", "authorized_keys", ".jsp", ".war"))
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, RemoteIP
| sort by TimeGenerated desc;

Velociraptor VQL

Use this artifact across your Linux fleet to (a) identify running Dinky instances, (b) enumerate their listening ports, and (c) surface recently modified files in high-risk write locations that a Dinky-owned process may have created.

VQL — Velociraptor
-- Identify Dinky processes, their listeners, and suspicious recent file drops
LET procs = SELECT Pid, Name, CommandLine, Username, Exe
  FROM pslist()
  WHERE CommandLine =~ 'dinky'

LET listeners = SELECT Pid, Name, Status, Laddr, Raddr
  FROM netstat()
  WHERE Laddr.Port = 8888 AND Status = 'LISTEN'

LET suspicious_files = SELECT FullPath, Mtime, Size
  FROM glob(globs=['/root/.ssh/authorized_keys',
                   '/home/*/.ssh/authorized_keys',
                   '/etc/cron.d/*',
                   '/etc/systemd/system/*.service',
                   '/tmp/*.jar',
                   '/tmp/*.sh',
                   '/**/webapps/**.jsp'])
  WHERE Mtime > now() - 86400 * 7

SELECT * FROM procs
UNION ALL
SELECT * FROM listeners
UNION ALL
SELECT * FROM suspicious_files

Remediation / Exposure Verification Script (Bash)

Run this on or against every suspected Dinky host to confirm exposure: listening port, reachable vulnerable endpoint, hardcoded token still in effect, and the configured dinkyToken value.

Bash / Shell
#!/bin/bash
# CVE-2026-70558 - Dinky exposure verification and rapid triage
set -euo pipefail

HOST="${1:-127.0.0.1}"
PORT="${2:-8888}"
DEFAULT_TOKEN="efda1551-7958-4e0f-80a8-dfd107df3e38"

echo "[*] Checking for local Dinky listener on :${PORT}"
ss -tlnp 2>/dev/null | grep ":${PORT}" || echo "    No local listener on ${PORT}"

echo "[*] Identifying Dinky processes"
ps aux | grep -i '[d]inky' || echo "    No Dinky process found locally"

echo "[*] Searching for hardcoded default token in deployed artifacts/configs"
grep -rIl "${DEFAULT_TOKEN}" /opt /usr/local /etc /home 2>/dev/null | head -20 || echo "    Default token string not found in searched paths"

echo "[*] Probing vulnerable endpoint with default token (write test to /tmp)"
RESP=$(curl -sk -o /dev/null -w "%{http_code}" \
  -X POST "http://${HOST}:${PORT}/download/uploadFromRsByLocal" \
  -H "token: ${DEFAULT_TOKEN}" \
  -F "path=/tmp/cve-2026-70558-canary.txt" \
  -F "file=@/dev/null;filename=canary.txt" || echo "000")
echo "    HTTP status: ${RESP}"
if [ "${RESP}" != "000" ] && [ "${RESP}" -lt 400 ]; then
  echo "[!!] ENDPOINT REACHABLE AND ACCEPTING REQUESTS - INSTANCE IS VULNERABLE"
  echo "[!!] Remove canary file: rm -f /tmp/cve-2026-70558-canary.txt"
else
  echo "[OK] Endpoint rejected the request or is unreachable (verify network path)"
fi

echo "[*] Checking for unexpected recent writes in high-risk locations"
find /etc/cron.d /etc/systemd/system /tmp /root/.ssh -type f -mtime -7 2>/dev/null | head -30

echo "[*] Done. If vulnerable: upgrade Dinky, rotate dinkyToken, restrict port ${PORT} access, and review logs for prior /download/uploadFromRsByLocal hits."

Remediation

Treat this as an emergency change for any Dinky deployment. In priority order:

  1. Upgrade Dinky to the fixed release. Track the vendor fix via the NVD entry for CVE-2026-70558 and the Dinky project's security advisories/release notes. The correct fix includes server-side path canonicalization confined to a designated upload directory and removal of the hardcoded credential pattern — do not accept a release that only does one.
  2. Rotate dinkyToken immediately — everywhere. Any instance still on the default efda1551-7958-4e0f-80a8-dfd107df3e38 is unauthenticated in practice. Set a strong, unique, randomly generated token per environment. Treat the old default as compromised credential material and hunt for its use in your logs (detections above).
  3. Restrict network reachability. Dinky's HTTP port (8888) must not be internet-exposed. Place it behind an authenticated reverse proxy or VPN, enforce security-group/firewall allowlists limited to operators and automation, and verify with external scanning. If you found port 8888 open to the internet during triage, assume compromise and move to IR.
  4. If you cannot patch today (workarounds):
    • Block /download/** (or at minimum /download/uploadFromRsByLocal) at your reverse proxy/WAF for all sources except a tightly scoped allowlist.
    • Override the default token via configuration before any network exposure.
    • Run the Dinky service as a dedicated low-privilege, non-root account with a read-only root filesystem (containers) and no write access to webroots, cron, or SSH directories.
  5. Hunt for historical exploitation. Search proxy, WAF, and Dinky access logs for uploadFromRsByLocal requests and the default token going back as far as retention allows. Any hit from an unrecognized source IP = incident. Check for unauthorized files in webroots, ~/.ssh/authorized_keys, /etc/cron.*, /tmp, and unexpected Flink job submissions.
  6. If compromise is suspected: isolate the host/pod, capture volatile data and disk images before rebuilding, rotate all credentials reachable from the Dinky environment (data source credentials in Dinky's config are a prime target), and rebuild from known-good images on the patched version.

This vulnerability is a reminder that "internal-only" data tooling is routinely one misconfigured security group away from the internet — and that a hardcoded default credential is not an authentication control, it's a speed bump. Verify, patch, and hunt.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.