Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-47630 — Technical vulnerability analysis and proof-of-concept for CVE-2026-47630, an arbitrary dlopen via TRITON_BATCH_STRATEGY_PATH in NVIDIA Triton Inference Server enabling native code execution, with detection and mitigation guidance. | Kitploit
Tools/GitHubGitHub/s1ko/cve-2026-47630
Vulnerability AnalysisExploitationAI Security
GitHubs1ko/cve-2026-47630

CVE-2026-47630

Technical vulnerability analysis and proof-of-concept for CVE-2026-47630, an arbitrary dlopen via TRITON_BATCH_STRATEGY_PATH in NVIDIA Triton Inference Server enabling native code execution, with detection and mitigation guidance.

View Repository
1 day agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-47630 — NVIDIA Triton Inference Server: arbitrary dlopen via TRITON_BATCH_STRATEGY_PATH

Absolute path traversal in the custom batching-strategy loader of triton-inference-server/core. A model configuration parameter is passed unvalidated to dlopen(RTLD_NOW | RTLD_LOCAL), so anyone able to influence a model's config.pbtxt obtains native code execution inside the Triton server process at model-load time.

NVIDIA's acknowledgement in bulletin 5865 reads verbatim: CVE-2026-47630: s1ko.

Summary

Triton accepts a per-model TRITON_BATCH_STRATEGY_PATH parameter from the model's config.pbtxt. Through 26.05 the value was treated as an arbitrary filesystem path and handed unmodified to dlopen. There was no containment check, no allowlist, and no signature or hash verification. Absolute paths, traversal sequences and symlinks were all accepted.

RTLD_NOW resolves every symbol immediately and runs the object's __attribute__((constructor)) / .init_array routines before dlopen returns. Execution is therefore unconditional on a successful load — none of the TRITONBACKEND_ModelBatch* entry points need to exist for the payload to run, and it runs with the privileges of the Triton process (frequently root in NGC containers).

Execution

Code path (as of 26.05)

src/backend_model.cc — attacker input reaches batch_libpath, validated only for existence:

root@kitploit:~
if (model_config.parameters().contains("TRITON_BATCH_STRATEGY_PATH")) {
  batch_libpath = model_config.parameters()
                      .at("TRITON_BATCH_STRATEGY_PATH")
                      .string_value();
  bool exists = false;
  RETURN_IF_ERROR(FileExists(batch_libpath, &exists));
  if (!exists) {
    return Status(
        triton::common::Error::Code::NOT_FOUND,
        ("Batching library path not found: " + batch_libpath).c_str());
  }
}

Notably absent is any call to IsChildPathEscapingParentPath, which Triton already applied to label paths and backend library paths elsewhere in the same file.

src/backend_model.cc — SetBatchingStrategy forwards it:

root@kitploit:~
Status TritonModel::SetBatchingStrategy(const std::string& batch_libpath)
{
  std::unique_ptr<SharedLibrary> slib;
  RETURN_IF_ERROR(SharedLibrary::Acquire(&slib));
  RETURN_IF_ERROR(slib->OpenLibraryHandle(batch_libpath, &batch_dlhandle_));

src/shared_library.cc — the sink:

root@kitploit:~
*handle = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);

Reachability

Three practical routes to controlling model_config.parameters():

  1. Multi-tenant model repository. A tenant who owns their model's config.pbtxt plants a .so in their own directory and points the parameter at it. The payload runs with the server's privileges, giving access to every other tenant's weights, secrets and GPU.
  2. File-override API. TRITONSERVER_ServerLoadModelWithParameters combined with the documented file:<rel-path> parameter prefix lets a caller with model-load rights submit config.pbtxt and the .so in a single request and trigger the load immediately. No filesystem access outside the API is required.
  3. Compromised model-store mirror. S3, GCS, Azure Blob or NGC mirrors treated as authoritative for model artifacts. Whoever controls the mirror delivers both files; Triton fetches and dlopens on demand.

Proof of concept

poc/ contains the primitive, reduced to what OpenLibraryHandle does. Sources only — build them yourself:

root@kitploit:~
$ cd poc && ./build.sh
$ gcc -O0 -o test_dlopen test_dlopen.c -ldl
$ ./test_dlopen ./evil.so
dlopen OK, handle=0x55d1779652c0
$ cat /tmp/triton_dlopen_rce_proof.log
[triton-dlopen-rce] constructor fired @ Fri May  1 09:56:56 2026
  pid=240157  uid=1000  euid=1000  cwd=/opt/poc

The payload is inert: it appends one line recording pid, uid, euid and cwd. Verified on Debian 13, GCC 14.2, x86_64.

For the Triton-side trigger, place the built evil.so next to poc/config.pbtxt in the model repository and load the model — auto-load, --load-model, or POST /v2/repository/models/evil_model/load. On an affected version the constructor fires during SetBatchingStrategy, before any backend symbol lookup.

Detection

The load is logged by Triton itself at INFO:

root@kitploit:~
Loading custom batching strategy library <path> for model <name>

On a fixed build, a rejected attempt surfaces as Batching library path escapes model repository.

Any TRITON_BATCH_STRATEGY_PATH value that is absolute, contains .., or resolves outside the model directory is worth alerting on regardless of version. A Sigma rule covering both the log line and the config parameter is in detection/.

Complementary signals:

  • config.pbtxt files carrying a TRITON_BATCH_STRATEGY_PATH parameter at all — the feature is rare in practice, so presence alone is a useful filter.
  • Shared objects appearing inside a model repository that are not backend artifacts.
  • openat/mmap of a .so outside the model root by the tritonserver process (auditd, eBPF, or Falco).

Mitigation

Upgrade to Triton Inference Server 26.06 or later. The fix adds the containment check the loader was missing:

root@kitploit:~
bool escapes{true};
RETURN_IF_ERROR(IsChildPathEscapingParentPath(
    batch_libpath, localized_model_dir->Path(), &escapes));
if (escapes) {
  return Status(
      Status::Code::INVALID_ARG,
      "Batching library path escapes model repository.");
}

Where upgrading is not immediately possible, compensating controls:

  • Reject or strip TRITON_BATCH_STRATEGY_PATH from every config.pbtxt before it reaches the model repository.
  • Treat the model repository as a trust boundary: no untrusted party writes to it, and remote mirrors are integrity-verified before sync.
  • Disable the file-override load path (--model-control-mode other than explicit, or authorization on the repository endpoints) unless it is required.
  • Run tritonserver as an unprivileged user with a read-only model repository mount, so a successful load has the smallest possible blast radius.
  • Verify a hash or signature over model artifacts prior to load.

Mapping: MITRE ATT&CK T1574.006 Hijack Execution Flow: Dynamic Linker Hijacking and T1129 Shared Modules; NIST SP 800-53r5 SI-7, CM-5, SC-18; CIS Controls v8 §2, §4.

Timeline

References

  • NVIDIA security bulletin 5865 — https://github.com/NVIDIA/product-security/blob/main/2026/5865/5865.md
  • CVE record — https://github.com/NVIDIA/product-security/blob/main/2026/5865/CVE-2026-47630.json
  • triton-inference-server/core — https://github.com/triton-inference-server/core
  • NVIDIA Product Security — https://www.nvidia.com/security/

License

MIT — see LICENSE.

Download Tool
CVECVE-2026-47630
NVIDIA bulletin5865 (2026-08-18)
CWECWE-36 (Absolute Path Traversal); reported as CWE-114 / CWE-829
CVSS v3.1 (NVIDIA)5.5 MEDIUM — AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
AffectedTriton Inference Server 0.0 – 26.05 (Linux)
Fixed in26.06
Reported bys1ko (github.com/s1ko, [email protected])
Vendor trackingNVIDIA PSIRT ticket 6139742
DateEvent
2026-04-25Primary Triton path-handling finding reported; NVIDIA PSIRT opens ticket 6128799
2026-05-01This secondary finding confirmed and reported; PSIRT opens ticket 6139742
2026-05-28Coordinated-disclosure cadence agreed with PSIRT
2026-06Fix ships in Triton Inference Server 26.06
2026-08-18NVIDIA publishes bulletin 5865, assigning CVE-2026-47630 and crediting s1ko
2026-08-22This write-up published