{"uuid": "ca5b6755-e81a-4a8c-9405-6a34f6dd9e84", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-43284", "type": "seen", "source": "https://gist.github.com/ManiAm-AI/1dfe88d8d616dfa3dda5c6a74a8e4968", "content": "\n## Group 1\n\n### UPSW-9340 \u2014 Remove Docker/Redis Groups from Admin User\n\n&gt; **TL;DR:** Docker group membership gave any admin user trivial container-escape-to-root access. Removed docker/redis groups from admin role.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 container escape to host root |\n| **PRs** | SkyOS [#1882](https://github.com/upscale-ai-network/SkyOS/pull/1882) + ucli [#1722](https://github.com/upscale-ai-network/ucli/pull/1722) |\n| **Risk** | Medium \u2014 changes group membership for admin users; `sudo docker` still works as fallback |\n\n**What it is:**\nDocker group membership allows mounting the host filesystem into a container and executing commands as root \u2014 trivial privilege escalation. The admin user was in the `docker` group by default.\n\n**The fix:**\n- **SkyOS:** `build_debian.sh` no longer adds admin to `docker` or `redis` groups. High-privilege RADIUS/TACACS+ defaults updated similarly.\n- **ucli:** Added `_docker()` helper to `sonic-login-shell` and `ucli-host-wrapper` that falls back to `sudo docker` for users not in the docker group.\n\n**Example:**\n\n```\n# BEFORE \u2014 admin in docker group\nadmin@switch:~$ id\nuid=1000(admin) gid=1000(admin) groups=999(docker),998(redis),27(sudo)\n\nadmin@switch:~$ docker run -v /:/host -it debian chroot /host\nroot@container:/#                          \u2190 full host root access\n\n# AFTER \u2014 docker group removed\nadmin@switch:~$ id\nuid=1000(admin) gid=1000(admin) groups=27(sudo)\n\nadmin@switch:~$ docker run -v /:/host -it debian chroot /host\nGot permission denied                      \u2190 blocked without sudo\n```\n\n**Verified:** Confirmed `id admin` shows no docker/redis groups; uCLI still works via `sudo docker` fallback.\n\n---\n\n### UPSW-9047 \u2014 KLISH Metacharacter Escaping Breaks Password Authentication\n\n&gt; **TL;DR:** Passwords with `!`, `$`, or `\\` were silently stored with stray escape characters, causing SSH login to fail.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 authentication broken for passwords with special characters |\n| **PR** | ucli [#1596](https://github.com/upscale-ai-network/ucli/pull/1596) |\n| **Risk** | None \u2014 only affects the Rust handler path; Python handler already had the fix |\n\n**What it is:**\nKLISH bash ACTION blocks wrap arguments in double-quotes, so bash escapes metacharacters (`!` \u2192 `\\!`, `$` \u2192 `\\$`). The Python password handler had `_unescape_klish()` to reverse this, but the Rust handler was ported without it.\n\n**The bug:**\nSetting `YourPaSsWoRd123!` via uCLI actually hashed `YourPaSsWoRd123\\!`. SSH login with the real password never matched the stored hash.\n\n**The fix:**\nThree-line `unescape_klish()` function in the Rust handler, applied before validation and hashing.\n\n**Example:**\n\n```\n# BEFORE\nadmin@switch(config)# username testuser role admin secret YourPaSsWoRd123!\n                                          \u2190 stored hash of \"YourPaSsWoRd123\\!\" (wrong)\n\n$ ssh testuser@switch\nPassword: YourPaSsWoRd123!\nPermission denied                          \u2190 doesn't match escaped hash\n\n# AFTER\nadmin@switch(config)# username testuser role admin secret YourPaSsWoRd123!\n                                          \u2190 stored hash of \"YourPaSsWoRd123!\" (correct)\n\n$ ssh testuser@switch\nPassword: YourPaSsWoRd123!\ntestuser@switch:~$                         \u2190 login succeeds\n```\n\n**Verified:** Set password with `!`, `$`, and `\\` characters; confirmed SSH login succeeds.\n\n---\n\n### UPSW-9042 \u2014 SSH Host Keys Lost on Every Image Upgrade\n\n&gt; **TL;DR:** Every SONiC upgrade regenerated SSH host keys, breaking all existing client connections with a \"REMOTE HOST IDENTIFICATION HAS CHANGED\" warning.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 operational disruption + confusing security warning on every upgrade |\n| **PR** | SkyOS [#1815](https://github.com/upscale-ai-network/SkyOS/pull/1815) |\n| **Risk** | Low \u2014 only changes where keys are stored; no change to key generation logic |\n\n**What it is:**\nEach SONiC image has its own squashfs rootfs, so `/etc/ssh/` is empty on first boot of a new image. `sshd` regenerates host keys, breaking every SSH client that had the old fingerprint cached.\n\n**The fix:**\nUses `/host/ssh/` as persistent backing store:\n- **Same image reboot:** keys exist in `/etc/ssh/` \u2192 do nothing\n- **Upgrade (new image):** keys missing from `/etc/ssh/` but present in `/host/ssh/` \u2192 restore them\n- **First-ever boot:** no keys anywhere \u2192 generate and persist to `/host/ssh/`\n\n**Example:**\n\n```\n# BEFORE \u2014 every upgrade\n$ ssh admin@switch\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\u2190 operator must manually clear known_hosts\n\n# AFTER \u2014 keys persist\n$ ssh admin@switch\nadmin@switch:~$                            \u2190 seamless reconnect after upgrade\n```\n\n**Verified:** Simulated image upgrade; confirmed SSH fingerprint unchanged; no `known_hosts` warning.\n\n---\n\n### UPSW-9818 \u2014 Stranded CLI Sessions Cause OOM Kills\n\n&gt; **TL;DR:** When the host-side CLI wrapper is OOM-killed, container-side clish processes are orphaned and leak ~80 MB each. Added a watchdog and reaper to detect and terminate them.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 35 orphaned sessions consumed 2.7 GiB of the 4.6 GiB container budget |\n| **PR** | ucli [#1830](https://github.com/upscale-ai-network/ucli/pull/1830) |\n| **Risk** | Low \u2014 watchdog uses a NUL byte (terminal no-op) for detection; no visible impact |\n\n**What it is:**\nWhen `ucli-host-wrapper` is killed by OOM/SIGKILL, no EXIT trap fires and no signal reaches the container-side processes. They block indefinitely on stdin, each holding ~80 MB.\n\n**The fix:**\n- **Primary (watchdog):** Writes a NUL byte to stdout every 10s. When the PTY master closes, `write()` returns EIO. After 3 failures \u2192 terminate the orphaned session.\n- **Safety net (reaper):** Supervisord runs a cleanup script every 5 min that kills clish processes with no controlling terminal (tty==?) older than 10 minutes.\n\n**Example:**\n\n```\n# BEFORE \u2014 host wrapper OOM-killed\nadmin@switch:~$ docker exec gnmi ps aux | grep clish\nroot  1234  0.0  1.6  clish   \u2190 orphaned, no TTY, blocking on stdin\nroot  1235  0.0  1.6  clish   \u2190 another orphan\n... 35 orphans \u00d7 80 MB = 2.7 GiB leaked\n\n# AFTER \u2014 watchdog detects and terminates\nSep 01 14:32:07 switch ucli-watchdog: Client connection lost (3 consecutive EIO).\n    Terminating orphaned clish pid 1234.\n```\n\n**Verified:** Killed host wrapper with SIGKILL; confirmed watchdog terminated orphaned session within 30 seconds.\n\n---\n\n### UPSW-9817 \u2014 Cap Concurrent CLI Sessions to Prevent OOM\n\n&gt; **TL;DR:** No limit on concurrent CLI sessions \u2014 93 sessions triggered 80 OOM kills. Added admission gate based on container memory budget.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 OOM kills crash the management framework |\n| **PR** | ucli [#1829](https://github.com/upscale-ai-network/ucli/pull/1829) |\n| **Risk** | Low \u2014 rejects only when at capacity; configurable override via CONFIG_DB |\n\n**What it is:**\nEach CLI session costs ~64 MiB. On a 5 GB container, 93 concurrent sessions triggered 80 OOM kills \u2014 including the mgmt-framework `python3` process itself.\n\n**The fix:**\nAdmission gate in `ucli_start` that derives a session cap from the container's cgroup memory limit: `floor(memory.max \u00d7 0.6 / 64 MiB)`, reserving 40% for framework services. On a 5 GB container, this caps at ~44 sessions.\n\n**Example:**\n\n```\n# BEFORE \u2014 93rd session triggers OOM\n$ ssh admin@switch      \u2190 session 93\n[mgmt-framework OOM-killed]\n\n# AFTER \u2014 admission gate rejects at capacity\n$ ssh admin@switch\n% Maximum concurrent CLI sessions reached (44 of 44).\n  Please try again later or contact the administrator.\nConnection closed.\n```\n\n**Verified:** Set `max_sessions` to 1 via CONFIG_DB; confirmed second session rejected cleanly; `UCLI_SKIP_ADMISSION=1` bypasses the gate.\n\n---\n\n### UPSW-9816 \u2014 Kernel Printk (OOM, Panic, Oops) Not Persisted to Syslog\n\n&gt; **TL;DR:** Kernel messages (OOM-killer, panics) were silently dropped on Debian Trixie because rsyslog couldn't access `/dev/kmsg`. Fixed rsyslog config and added kernel log capture to tech-support.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 critical diagnostic events lost |\n| **PRs** | SkyOS [#1994](https://github.com/upscale-ai-network/SkyOS/pull/1994) + sonic-utilities [#100](https://github.com/upscale-ai-network/sonic-utilities/pull/100) |\n| **Risk** | Low \u2014 rsyslog config change only; no auth or data-path changes |\n\n**What it is:**\nDebian Trixie's `rsyslog.service` includes `PrivateDevices=yes`, which blocks `imklog` from reading `/dev/kmsg`. Kernel messages never entered the syslog pipeline \u2014 OOM kills, panics, and oops were invisible.\n\n**The fix:**\n- **SkyOS:** Systemd drop-in sets `PrivateDevices=no`; adds explicit `kern.* -/var/log/kern.log` rule\n- **sonic-utilities:** Tech-support now captures `dmesg -T` (human-readable timestamps) and `journalctl -k` (current + previous boot)\n\n**Example:**\n\n```\n# BEFORE \u2014 kernel messages missing\nadmin@switch:~$ grep -c \"Out of memory\" /var/log/kern.log\n0                                          \u2190 OOM events lost\n\n# AFTER \u2014 kernel messages persisted\nadmin@switch:~$ grep \"Out of memory\" /var/log/kern.log\nSep 01 14:32:07 switch kernel: Out of memory: Killed process 1234 (python3)\n```\n\n**Verified:** Injected kernel message via `/dev/kmsg`; confirmed it appeared in syslog and kern.log.\n\n\n\n\n\n\n\n\n---\n\n## Group 2 \u2014 Tech-Support Credential Scrubbing\n\nFive PRs that systematically close credential leaks in tech-support archives. Each addresses a different file or format that was leaking secrets.\n\n---\n\n### UPSW-9447 \u2014 JSON-Aware Credential Redaction in config_db Scrub\n\n&gt; **TL;DR:** Replaced fragile `sed` scrubbing with a recursive JSON tree walker that catches all credential-bearing keys at any nesting depth.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 credentials exposed in shareable archives |\n| **PR** | sonic-utilities [#97](https://github.com/upscale-ai-network/sonic-utilities/pull/97) |\n| **Risk** | Low \u2014 BGP community values explicitly preserved; falls back to pass-through on invalid JSON |\n\n**What it is:**\n`generate_dump` used line-oriented `sed` to scrub `config_db.json`, but only covered TACACS `passkey` and SNMP community. Other credential keys (`password`, `secret`, `auth_key`, `priv_key`, `bind_password`) at arbitrary nesting depth remained in plaintext.\n\n**The fix:**\nInline Python JSON walker that recursively masks any value whose key contains a sensitive substring. Skips `ROUTE_MAP`, `BGP_COMMUNITY`, and `COMMUNITY_LIST` tables to avoid false positives. 19 unit tests added.\n\n**Example:**\n\n```json\n// BEFORE \u2014 credentials in plaintext\n\"TACACS|10.0.0.1\": { \"passkey\": \"s3cret!\", \"auth_key\": \"mykey123\" }\n\"RADIUS|10.0.0.2\": { \"secret\": \"r4dius!\" }\n\n// AFTER \u2014 all sensitive values masked\n\"TACACS|10.0.0.1\": { \"passkey\": \"****\", \"auth_key\": \"****\" }\n\"RADIUS|10.0.0.2\": { \"secret\": \"****\" }\n```\n\n**Verified:** Generated tech-support dump; confirmed no plaintext credentials in `config_db.json`.\n\n---\n\n### UPSW-9449 \u2014 Scrub FRR BGP Neighbor Passwords\n\n&gt; **TL;DR:** BGP neighbor MD5/TCP-AO session secrets were exposed in tech-support FRR config files. Added a scrub regex for `neighbor  password` lines.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 BGP session secrets in shareable archives |\n| **PR** | sonic-utilities [#94](https://github.com/upscale-ai-network/sonic-utilities/pull/94) |\n| **Risk** | None \u2014 only adds a new sed regex; existing scrubs unchanged |\n\n**The fix:**\nNew regex `s/(neighbor\\s+\\S+\\s+password\\s+).*/\\1****/g` applied to both live and captured FRR config files, including multi-ASIC per-namespace files.\n\n**Verified:** Generated tech-support with BGP MD5 auth enabled; confirmed passwords show `****`.\n\n---\n\n### UPSW-9448 \u2014 Omit old_config/ from Techsupport Archives\n\n&gt; **TL;DR:** Prior-config directory had unsanitized credentials (`default_users.json`, `constants.yml`). Removed the entire tree rather than playing whack-a-mole.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 unsanitized credentials in prior-config tree |\n| **PR** | sonic-utilities [#95](https://github.com/upscale-ai-network/sonic-utilities/pull/95) |\n| **Risk** | Low \u2014 TAC workflows don't require prior-config for diagnosis |\n\n**Verified:** Generated tech-support after an upgrade; confirmed `tar tzf | grep old_config` returns empty.\n\n---\n\n### UPSW-9446 \u2014 Scrub Password Hashes from default_users.json\n\n&gt; **TL;DR:** Yescrypt password hashes from `/etc/shadow` were included in tech-support dumps, enabling offline brute-force attacks.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 password hashes in shareable archives |\n| **PR** | sonic-utilities [#96](https://github.com/upscale-ai-network/sonic-utilities/pull/96) |\n| **Risk** | None \u2014 only masks hash values; usernames and metadata preserved |\n\n**Verified:** Confirmed `default_users.json` in archive shows `\"password\": \"****\"` instead of hash material.\n\n---\n\n### UPSW-9445 \u2014 Scrub SNMP Community from snmp.yml and DHCP Hook\n\n&gt; **TL;DR:** SNMP community string was masked in `config_db.json` but exposed in two other files. Added scrub passes for both.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 SNMP community string in two unscrubbed files |\n| **PR** | sonic-utilities [#98](https://github.com/upscale-ai-network/sonic-utilities/pull/98) |\n| **Risk** | None \u2014 adds existence guards; no-op when files are absent |\n\n**Verified:** Confirmed `snmp.yml` and DHCP hook file both show `snmp_rocommunity: ****` in archive.\n\n---\n\n\n\n\n\n\n\n## Group 3 \u2014 CLI Features (Day-0 Operational Commands)\n\n---\n\n### UPSW-9232 \u2014 Add `default interface` Command\n\n&gt; **TL;DR:** Resets all user-applied configuration on an interface to factory defaults in a single operation \u2014 industry-standard command (Cisco/NX-OS equivalent).\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 missing industry-standard command |\n| **PR** | ucli [#1627](https://github.com/upscale-ai-network/ucli/pull/1627) |\n| **Risk** | Medium \u2014 resets all attributes on the interface; management interface is explicitly refused |\n\n**What it is:**\nOperators who need to reset an interface currently must manually remove each attribute individually with `no `. The `default interface` command does it in one step.\n\nSupports single interface, in-interface-mode, and range form. Covers Ethernet, PortChannel, Vlan, Loopback, and Tunnel. Management interface is **refused** to prevent lockout.\n\n**Example:**\n\n```\n# Reset a single interface\nadmin@switch(config)# default interface Ethernet 1/1\n\n# Reset a range\nadmin@switch(config)# default interface range Ethernet 1/1-2/1\n\n# Management interface protected\nadmin@switch(config)# default interface Management 0\n% Error: Cannot reset management interface \u2014 risk of connectivity loss.\n```\n\n**Verified:** Applied multiple attributes to Ethernet1/1; ran `default interface`; confirmed all reset to platform defaults.\n\n---\n\n### UPSW-9267 \u2014 Add `write erase factory-reset` Command\n\n&gt; **TL;DR:** Added CLI-accessible factory reset (config, logs, users, containers) without requiring bash shell access.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 missing operational command |\n| **PR** | ucli [#1694](https://github.com/upscale-ai-network/ucli/pull/1694) |\n| **Risk** | Low \u2014 requires confirmation prompt; `force` variant for automation |\n\n**Example:**\n\n```\nadmin@switch:~$ write erase factory-reset\nWARNING: This will erase all configuration, logs, and user data.\nContinue? [no]: yes\nInitiating factory reset...\n```\n\n**Verified:** Confirmed device boots with factory defaults after reset; no residual config.\n\n---\n\n### UPSW-9323 \u2014 Add Boot Image Selection Commands\n\n&gt; **TL;DR:** Added `show boot`, `boot system `, and `boot image ` \u2014 industry-standard commands for selecting which image boots next.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 missing industry-standard commands |\n| **PR** | ucli [#1706](https://github.com/upscale-ai-network/ucli/pull/1706) |\n| **Risk** | None \u2014 delegates to existing `install_image.py` backend; no new logic |\n\n**Example:**\n\n```\nadmin@switch:~$ show boot\nCurrent: SONiC-OS-4.2.0-202608\nNext:    SONiC-OS-4.2.0-202608\nAvailable:\n  SONiC-OS-4.2.0-202608\n  SONiC-OS-4.1.0-202607\n\nadmin@switch:~$ boot system SONiC-OS-4.1.0-202607\nBoot image set to SONiC-OS-4.1.0-202607. Reboot to activate.\n```\n\n**Verified:** Set boot image, rebooted, confirmed switch came up on the selected image.\n\n---\n\n### UPSW-9256 \u2014 Named Management Profile for Access Control\n\n&gt; **TL;DR:** Declarative management profile that bundles permitted services + allowed source prefixes, reducing friction for management-plane hardening.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Medium** \u2014 reduces day-0 hardening friction |\n| **PR** | ucli [#1695](https://github.com/upscale-ai-network/ucli/pull/1695) |\n| **Risk** | Low \u2014 auto-generates CTRLPLANE ACL rules via existing `caclmgrd` path |\n\n**What it is:**\nManagement-plane hardening today requires the full ACL authoring path, which is complex enough that it's routinely skipped. The management profile provides a declarative abstraction.\n\n**Example:**\n\n```\nadmin@switch(config)# management profile SECURE\nadmin@switch(config-mgmt-profile)# service ssh\nadmin@switch(config-mgmt-profile)# service https\nadmin@switch(config-mgmt-profile)# permitted-ip 10.0.0.0/8\nadmin@switch(config-mgmt-profile)# exit\nadmin@switch(config)# interface Management 0\nadmin@switch(config-if)# management-profile SECURE\n\nadmin@switch:~$ show management-profile\nProfile: SECURE (bound to Management0)\n  Services: ssh, https\n  Permitted: 10.0.0.0/8\n```\n\n**Verified:** Bound profile; confirmed iptables rules match the profile definition.\n\n---\n\n### UPSW-9387 \u2014 Map SONiC Port Names to Front-Panel Aliases in Logging\n\n&gt; **TL;DR:** `show logging` now translates `Ethernet384` to `Et49/1` so operators can search logs using faceplate names.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Low** \u2014 usability improvement |\n| **PR** | ucli [#1741](https://github.com/upscale-ai-network/ucli/pull/1741) |\n| **Risk** | None \u2014 falls back gracefully when PortMapper unavailable |\n\n**Example:**\n\n```\n# BEFORE\nadmin@switch:~$ show logging | include Et49/1\n                                           \u2190 no matches (logs use Ethernet384)\n\n# AFTER\nadmin@switch:~$ show logging | include Et49/1\nSep 01 14:32:07 switch bgpd: neighbor Et49/1 Up   \u2190 translated and matched\n```\n\n**Verified:** Confirmed `show logging | include Et49/1` matches entries that were previously `Ethernet384`.\n\n---\n\n### UPSW-9444 \u2014 Improve Techsupport Discoverability\n\n&gt; **TL;DR:** Operators using `dir tech-support:/` or `copy tech-support://...` now get helpful redirects to the correct SkyOS commands instead of opaque errors.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Low** \u2014 usability improvement |\n| **PR** | ucli [#1751](https://github.com/upscale-ai-network/ucli/pull/1751) |\n| **Risk** | None \u2014 only adds hint messages on error paths |\n\n**Example:**\n\n```\n# BEFORE\nadmin@switch:~$ dir tech-support:/\n% Error: Invalid path\n\n# AFTER\nadmin@switch:~$ dir tech-support:/\n% Did you mean:\n    show techsupport history     \u2014 list available bundles\n    techsupport export   \u2014 export to remote server\n```\n\n**Verified:** Confirmed hint messages appear for `dir`, `copy`, and `scp` with tech-support paths.\n\n---\n\n### UPSW-9244 \u2014 Packet-Filter Framework for Dataplane Fault Isolation\n\n&gt; **TL;DR:** Added `debug packet-filter` CLI framework for defining match criteria and scoping counter output to matched traffic. Hardware counter backend is a follow-up.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Low** \u2014 foundational framework; hardware counters pending |\n| **PR** | ucli [#1696](https://github.com/upscale-ai-network/ucli/pull/1696) |\n| **Risk** | None \u2014 CLI-only; no ASIC programming in this PR |\n\n**Example:**\n\n```\nadmin@switch:~$ debug packet-filter match source 10.0.0.1 destination 10.0.0.2 protocol 6\nadmin@switch:~$ debug packet-filter on\nadmin@switch:~$ show debugging packet-filter\nFilter 1: src=10.0.0.1 dst=10.0.0.2 proto=TCP  [active]\n```\n\n**Verified:** Filter state stored in STATE_DB; show command displays active filters.\n\n---\n\n### UPSW-9054 \u2014 Real-Time FRR Log Streaming\n\n&gt; **TL;DR:** Added `show logging frr follow` for real-time FRR log streaming \u2014 no more dropping into bash for `tail -f`.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Low** \u2014 usability / removes bash dependency for FRR debugging |\n| **PR** | ucli [#1600](https://github.com/upscale-ai-network/ucli/pull/1600) |\n| **Risk** | None \u2014 streaming command with clean Ctrl-C termination |\n\n**Example:**\n\n```\nadmin@switch:~$ show logging frr follow | include bgpd\nSep 01 14:32:07 switch bgpd[1234]: neighbor 10.0.0.1 Up\nSep 01 14:32:08 switch bgpd[1234]: rcvd UPDATE w/ attr: nexthop 10.0.0.1\n^C\nadmin@switch:~$                            \u2190 clean exit\n```\n\n**Verified:** Confirmed real-time streaming; Ctrl-C terminates cleanly; `| include` filters work.\n\n---\n\n### UPSW-9046 \u2014 Add `find command keyword` for Command Search\n\n&gt; **TL;DR:** Deterministic command search across the entire CLI tree \u2014 modeled after PAN-OS `find command keyword`.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Low** \u2014 discoverability improvement |\n| **PR** | ucli [#1597](https://github.com/upscale-ai-network/ucli/pull/1597) |\n| **Risk** | None \u2014 read-only search; no state changes |\n\n**Example:**\n\n```\nadmin@switch:~$ find command keyword logging\nclear logging\nlogging frr daemon\nlogging frr facility\nlogging host\nshow logging\nshow logging follow\nshow logging frr\nshow logging last\n...\n33 command(s) matched 'logging'\n```\n\n**Verified:** Confirmed search spans all modes; non-matching keywords produce clear \"No commands found\" message.\n\n\n\n\n\n\n\n\n\n\n\n\n## Group 4\n\n### UPSW-9337 \u2014 Interim Kernel CVE Mitigations\n\n&gt; **TL;DR:** Kernel 6.12.41 is vulnerable to 8 privilege escalation CVEs \u2014 added interim mitigations (ptrace lockdown + xfrm module blacklist) until the full kernel upgrade.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Critical** \u2014 active CVEs with known exploitation paths |\n| **PR** | SkyOS [#1885](https://github.com/upscale-ai-network/SkyOS/pull/1885) |\n| **Risk** | Low \u2014 ptrace restriction and module blacklisting are standard hardening; GDB/strace still work under sudo |\n\n**What it is:**\nKernel 6.12.41 (deployed in SkyOS) is vulnerable to 8 privilege escalation CVEs. Two are confirmed exploitable:\n\n- **CVE-2026-43284 (Dirty Frag / xfrm-ESP):** Privilege escalation via IPsec memory corruption. The `xfrm_user` module is loaded by default.\n- **CVE-2026-31431 (Copy Fail):** Privilege escalation in `algif_aead` (AF_ALG socket). **Not mitigated** by ptrace_scope \u2014 requires the full kernel upgrade to 6.12.96+.\n\n**The fix:**\n1. **`kernel.yama.ptrace_scope=2`** \u2014 restricts ptrace to root only. Mitigates CVE-2026-46333 and other ptrace-dependent escalation vectors.\n2. **Block `xfrm_user` / `xfrm_algo`** \u2014 uses both `blacklist` and `install /bin/false` to fully prevent loading of IPsec transform modules, closing CVE-2026-43284. SkyOS does not use kernel-level IPsec.\n\n**Example:**\n\n```\n# BEFORE \u2014 xfrm modules loaded by default\nadmin@switch:~$ lsmod | grep xfrm\nxfrm_user      40960  0\nxfrm_algo       16384  1 xfrm_user        \u2190 attacker can trigger CVE-2026-43284\n\n# AFTER \u2014 modules blacklisted\nadmin@switch:~$ modprobe xfrm_user\nmodprobe: ERROR: could not insert 'xfrm_user': Operation not permitted\n\nadmin@switch:~$ sysctl kernel.yama.ptrace_scope\nkernel.yama.ptrace_scope = 2               \u2190 ptrace restricted to root\n```\n\n**Verified:** Confirmed `lsmod` shows no xfrm modules; `modprobe` fails; ptrace_scope is 2.\n\n---\n\n### UPSW-9533 \u2014 Consent Token Authorization for Elevated Shell Access\n\n&gt; **TL;DR:** `bash` command now requires a time-limited, device-bound consent token obtained through an ECDSA challenge-response protocol before granting shell access.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **Critical** \u2014 unrestricted bash access bypasses all RBAC and audit controls |\n| **PR** | ucli [#1774](https://github.com/upscale-ai-network/ucli/pull/1774) |\n| **Risk** | Medium \u2014 changes the bash access workflow for all users; emergency access preserved when mgmt-framework is down |\n\n**What it is:**\nUnrestricted bash access on a switch allows executing arbitrary commands, extracting secrets, and bypassing audit trails. The security checklist requires bash to be gated behind an authorization mechanism.\n\n**The fix:**\nAn offline ECDSA P-256 challenge-response protocol:\n\n1. `debug shell challenge` \u2014 generates a device-bound, time-limited challenge (serial number, system MAC, hostname, nonce, 10-minute expiry)\n2. Operator forwards the challenge to Upscale support\n3. Support signs the challenge off-box with the ECDSA private key\n4. `debug shell response ` \u2014 verifies the signature and creates an 8-hour bash grant\n5. `bash` \u2014 only works with a valid grant\n\nSecurity properties: asymmetric crypto (only public key on-device), device-bound, time-limited, nonce-protected, offline verification, fully audited to syslog.\n\n**Example:**\n\n```\n# WITHOUT consent token\nadmin@switch:~$ bash\n% Error: Elevated shell access requires a consent token.\n         Use 'debug shell challenge' to initiate.\n\n# WITH consent token\nadmin@switch:~$ debug shell challenge\nChallenge: eyJzZXJpYWwiOiJTTjEyMzQ1Iiw...      \u2190 send this to support\n\nadmin@switch:~$ debug shell response \nConsent granted. Bash access valid for 8 hours.\n\nadmin@switch:~$ bash\nadmin@switch:/home/admin#                         \u2190 shell access granted\n```\n\n**Verified:** Confirmed bash is rejected without token; valid token grants 8-hour access; expired tokens are rejected.\n\n---\n\n### UPSW-9820 \u2014 Gate CLI Crash Fallback Behind Consent Token\n\n&gt; **TL;DR:** CLI crashes previously dropped admin users into bash unconditionally. Now requires a consent token \u2014 same as normal bash access.\n\n| Field | Value |\n|-------|-------|\n| **Severity** | **High** \u2014 privilege escalation through CLI crash |\n| **PR** | ucli [#1831](https://github.com/upscale-ai-network/ucli/pull/1831) |\n| **Depends on** | [#1774](https://github.com/upscale-ai-network/ucli/pull/1774) (UPSW-9533 consent token base) |\n| **Risk** | Low \u2014 emergency access preserved when mgmt-framework is down |\n\n**What it is:**\nWhen `clish` crashes (signal kill, OOM), the login shell's fallback was to unconditionally drop admin users into bash \u2014 giving host root access without any authorization.\n\n**The fix:**\n- Admin **with** valid consent grant \u2192 bash (serviceability preserved)\n- Admin **without** grant, mgmt-framework healthy \u2192 denied with diagnostic message\n- Admin **without** grant, mgmt-framework down \u2192 bash (emergency access)\n- All bash escape paths are now audited via `logger`\n\n**Example:**\n\n```\n# BEFORE \u2014 crash gives free bash\n[clish killed by OOM]\nadmin@switch:/home/admin#                 \u2190 root shell, no questions asked\n\n# AFTER \u2014 consent token required\n[clish killed by OOM]\n% uCLI exited abnormally. Elevated shell access requires a consent token.\n  Use 'debug shell challenge' from a new session.\nConnection closed.\n```\n\n**Verified:** Killed clish with SIGKILL; confirmed bash denied without consent token; emergency access works when mgmt-framework container is down.\n\n", "creation_timestamp": "2026-09-02T19:21:02.927875Z"}