79% vs 51%: independent neobanks lag on app security. Read the report

Deep Dive

Deep Dive

Dropbear SSH Restriction Bypass Reaches Root Sockets

A Dropbear key restricted to one TCP destination can still open unix sockets, including docker.sock, because the per-destination checks skip stream forwarding.

TL;DR

  • Dropbear enforces permitopen and permitlisten for TCP forwarding but not for unix-socket forwarding. A key restricted to one TCP destination can open any socket the account can reach.
  • Every Dropbear release through 2026.94 and Git HEAD 99baf182 is affected. The local and remote stream forwarding options are enabled by default.
  • Researcher knell scores it 9.9 when the account reaches Docker or a database socket. No CVE is assigned and no exploitation is reported. It is not in CISA's Known Exploited Vulnerabilities catalog as of November 14, 2026.
  • No fixed release exists. Add no-port-forwarding to restricted keys, or rebuild Dropbear with the stream forwarding options off. See "How do I fix it?" for the cost of each option.

Am I affected?

You are exposed when all of these hold:

  • The server runs Dropbear, any release or Git HEAD through 99baf182 (2026-11-11).
  • The build keeps unix-socket forwarding enabled. DROPBEAR_SVR_LOCALSTREAMFWD and DROPBEAR_SVR_REMOTESTREAMFWD default to 1.
  • At least one authorized_keys entry carries permitopen= or permitlisten=. The restriction is the reason the key holder is not trusted with general reach.
  • The account behind that key can reach a sensitive unix socket, such as /var/run/docker.sock or a database socket. The researcher's 9.9 case is the Docker socket.
  • The attacker holds that restricted key, or can use the account that holds it.

A key with no permitopen or permitlisten restriction is not the subject of this flaw: its holder already has general forwarding reach. The bypass matters for keys an administrator deliberately narrowed.

Branch Affected versions Fixed version
Releases Through 2026.94 (2026-07-23) None
Git Through 99baf182 (2026-11-11) None

Check the server version and the restricted keys:

# Server and client version
dropbear -V

# Keys that carry a per-destination restriction
grep -R -E 'permitopen=|permitlisten=' /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys 2>/dev/null

# Accounts that can reach the Docker socket
getent group docker

The key list is the important check. A permitopen key whose account is also in the docker group is the 9.9 case the researcher describes.

How do I fix it?

No fixed Dropbear release exists as of November 14, 2026. Apply one of these three mitigations, in order of preference, and remove it when upstream ships a path-based fix.

  1. Add no-port-forwarding to every key that carries permitopen or permitlisten. The stream forwarding handlers check that flag through svr_pubkey_allows_tcpfwd(), so the key can no longer open unix sockets. The cost is that the key loses all TCP forwarding too, including the destination the administrator allowed.
  2. Rebuild Dropbear with DROPBEAR_SVR_LOCALSTREAMFWD 0 and DROPBEAR_SVR_REMOTESTREAMFWD 0 in localoptions.h. The cost is that no account on that server can use unix-socket forwarding.
  3. Start the server with -j -k. The flags set nolocaltcp and noremotefwd, which the stream forwarding handlers check. The cost is that every account loses local and remote forwarding, not only the restricted keys.

Removing the account from the docker group and tightening the socket permissions lowers the impact. It does not close the bypass: the key can still reach any other socket the account can open, including database and service sockets.

The researcher recommends a path-based permitopen equivalent enforced in svr-streamfwd.c with the same list walk the TCP path uses. Watch the Dropbear release page for that change; the project has not published a fixed version.

What is the root cause?

The unix-socket forwarding handlers check only the coarse no-port-forwarding flag. They never call the functions that walk the key's per-destination list.

Dropbear keeps the restrictions in authorized_keys. svr_pubkey_allows_tcpfwd() at src/svr-authpubkeyoptions.c line 65 returns 0 only when the key carries no-port-forwarding:

int svr_pubkey_allows_tcpfwd() {
    if (ses.authstate.pubkey_options 
        && ses.authstate.pubkey_options->no_port_forwarding_flag) {
        return 0;
    }
    return 1;
}

The per-destination checks live in svr_pubkey_allows_local_tcpfwd() and svr_pubkey_allows_remote_tcpfwd() in the same file. src/svr-tcpfwd.c calls them at lines 202 and 99. The two stream forwarding handlers do not.

In src/svr-streamfwd.c, the local handler newstreamlocal() checks svr_opts.nolocaltcp and svr_pubkey_allows_tcpfwd() at line 294. The remote handler svr_remotestreamlocalreq() checks svr_opts.noremotefwd and the same function at line 219. A search of the tree finds the two per-destination functions referenced only from src/svr-tcpfwd.c.

The default build enables both stream forwarding options at src/default_options.h lines 76 and 77. The channel is registered in src/svr-session.c.

The incomplete fix is visible in the history. Commit 796a89ef (2024-04-03), "Apply tcp forwarding restrictions to unix sockets too", added the coarse gate to newstreamlocal() and updated the manual. It did not add the per-destination check its title announces. The author notes at src/svr-streamfwd.c lines 213 and 214 that the check could be relaxed if a permitlisten equivalent existed for streamlocal; it does not exist.

How is it exploited?

  1. The attacker authenticates with a key that the administrator restricted to one TCP destination with permitopen="host:port".
  2. The attacker opens a direct-streamlocal@openssh.com channel to a unix socket path instead of a TCP destination.
  3. Dropbear's stream forwarding handler checks the no-port-forwarding flag and the server-wide forwarding switch. Both pass, because the key does not carry no-port-forwarding.
  4. The handler never consults the permitopen list, so it connects to the requested socket.
  5. The attacker speaks the protocol of the socket. On /var/run/docker.sock, the Docker API can start a container with the host filesystem mounted, which is host root.

The researcher demonstrated the bypass on a local rig built from the pinned source. A key carrying permitopen="127.0.0.1:1" was refused when it asked for 127.0.0.1:22, but the same key reached /tmp/target.sock. The same key then opened /var/run/docker.sock and received HTTP/1.1 200 OK, Api-Version 1.56 from the real daemon.

The remote direction works the same way. A key with permitlisten can make the server listen on an arbitrary writable unix path and shadow a service socket.

How does the attack flow?

A restricted key passes the coarse forwarding check, asks for a unix socket instead of a TCP destination, and reaches a socket the administrator never allowed.

flowchart LR A["Attacker holds a key with
permitopen to one TCP host"] --> B["Connects to Dropbear
with that key"] B --> C["Opens a direct-streamlocal
channel to docker.sock"] C --> D["Handler checks only
no-port-forwarding"] D --> E["permitopen list
is never consulted"] E --> F["Dropbear connects to
the root-owned socket"] F --> G["Docker API runs a container
with the host filesystem"]

What can an attacker do?

The attacker reaches unix sockets that the account can open, even though the key was restricted to one TCP destination. When the account can reach the Docker socket, that is host root.

The impact depends on the sockets the account's operating-system identity can touch:

  • /var/run/docker.sock lets the attacker run a container with the host filesystem mounted as root. The researcher calls this host-root-equivalent.
  • Database sockets such as /run/mysqld/mysqld.sock and /run/postgresql/.s.PGSQL.5432 expose the database to the key holder.
  • Agent and service sockets expose whatever those services accept.
  • In the permitlisten direction, the attacker can make the server listen on an arbitrary writable path and shadow a service socket.

The conditions are part of the impact. The attacker needs a valid restricted key, the account must be able to open the target socket, and the build must keep stream forwarding enabled. The researcher scores the Docker case CVSS v3.1 9.9 with AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H, and about 7 when only the account's own sockets are reachable.

This is not an unauthenticated flaw. The attacker holds a key the administrator issued, and the administrator restricted it precisely to limit what that key can do.

Why does the fix work?

No upstream fix exists yet. The change that closes the bypass applies the same per-destination list walk to the two stream forwarding handlers that the TCP handlers already use.

The missing check is visible in both handlers. The local handler at src/svr-streamfwd.c line 294 currently reads:

if (svr_opts.nolocaltcp || !svr_pubkey_allows_tcpfwd()) {

A complete check would also call a path-based equivalent of svr_pubkey_allows_local_tcpfwd() for the requested socket path. It would reject the channel when the key carries a destination list that does not include it. The remote handler at line 219 needs the same change for permitlisten.

The researcher's recommendation is to refuse streamlocal channels outright for any key that carries a per-destination restriction until a path-based option exists. That is the conservative fix and it is simple to reason about: a key that names destinations does not get unix sockets.

The no-port-forwarding mitigation works because it sets the flag the existing coarse check reads. The build and -j -k mitigations work because they set the server-wide switches the handlers read. None of them is a code fix for the missing list walk.

How do I check if I was compromised?

No exploitation has been reported and no indicators of compromise have been published. The checks look for the conditions and the socket use, not for a known payload.

  • List every key that carries permitopen or permitlisten, and the account that owns it.
  • Check whether those accounts are in the docker group or can open database sockets.
  • Review Docker daemon audit logs for API calls from unexpected local processes or users, especially container-create calls with host bind mounts.
  • Review database logs for local socket connections from operating-system users that do not normally connect.
  • Look for new containers, images or bind mounts that nobody on the team created.

Dropbear's default logging is minimal, and the write-up publishes no log signature. A failed attempt may leave no trace, and a successful one leaves the effects in the service the socket belongs to.

Timeline

  • 2024-04-03: Commit 796a89ef applies the coarse TCP forwarding restriction to unix sockets but not the per-destination checks.
  • 2025-12-09: Commit 00cfa132 blocks unix stream forwarding for forced-command keys, a different restriction on the same path.
  • 2026-07-23: Dropbear releases 2026.94.
  • 2026-11-11: The researcher tests Git HEAD 99baf182; the bypass is present.
  • 2026-11-13: The researcher publishes the analysis and the live proof to the oss-security mailing list.

From the incomplete fix to the disclosure
Figure 1: The coarse restriction landed in April 2024 and the per-destination half stayed missing. The bypass was disclosed on November 13, 2026. Source: Dropbear Git history and the oss-security disclosure, checked November 14, 2026

FAQ

Is there a CVE for this flaw?

No. The researcher published the analysis on the oss-security mailing list on November 13, 2026, and no CVE record exists as of November 14. The Dropbear project has not published an advisory.

Does permitopen protect unix sockets?

No. permitopen and permitlisten are enforced only on the TCP forwarding paths. The unix-socket handlers check the no-port-forwarding flag and the server-wide forwarding switch, not the destination list.

Is this a remote, unauthenticated vulnerability?

No. The attacker needs a valid key that the administrator restricted with permitopen or permitlisten. The severity depends on what the account behind that key can reach.

Which versions are affected?

Every Dropbear release through 2026.94 and Git HEAD through 99baf182 (2026-11-11). There is no fixed release as of November 14, 2026.

Does no-port-forwarding block the bypass?

Yes. no-port-forwarding sets the flag that svr_pubkey_allows_tcpfwd() reads, so both stream forwarding handlers refuse the channel. It also blocks all TCP forwarding for that key, including the destination the key was allowed.

What if the account is not in the docker group?

The attacker can still reach any socket the account can open, such as a database or service socket. The impact is lower than host root, but it is still reach that the key restriction was meant to withhold.

References

  • knell, "Dropbear: the restriction names an address", oss-security, November 13, 2026, the analysis and the live proof: https://www.openwall.com/lists/oss-security/2026/11/13/4 (checked November 14, 2026)
  • The researcher's paper, "Not an address", the full write-up and harness: https://archive.org/details/knell-not-an-address (checked November 14, 2026)
  • Dropbear source at 99baf182, src/svr-streamfwd.c, the two stream forwarding handlers: https://github.com/mkj/dropbear/blob/99baf1828c13e88de048e641d03694bfe8923251/src/svr-streamfwd.c (checked November 14, 2026)
  • Dropbear source at 99baf182, src/svr-authpubkeyoptions.c, the coarse and per-destination checks: https://github.com/mkj/dropbear/blob/99baf1828c13e88de048e641d03694bfe8923251/src/svr-authpubkeyoptions.c (checked November 14, 2026)
  • Dropbear source at 99baf182, src/default_options.h lines 76 and 77, the stream forwarding defaults: https://github.com/mkj/dropbear/blob/99baf1828c13e88de048e641d03694bfe8923251/src/default_options.h (checked November 14, 2026)
  • Commit 796a89ef, "Apply tcp forwarding restrictions to unix sockets too", April 3, 2024: https://github.com/mkj/dropbear/commit/796a89efd21f (checked November 14, 2026)
  • Commit 00cfa132, "Disallow unix stream forwarding for forced command", December 9, 2025: https://github.com/mkj/dropbear/commit/00cfa132fcbf (checked November 14, 2026)
  • Dropbear project page, the embedded and router use case and the 2026.94 release: https://matt.ucc.asn.au/dropbear/dropbear.html (checked November 14, 2026)
  • CISA Known Exploited Vulnerabilities catalog JSON feed, checked for a Dropbear entry on November 14, 2026 (none): https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (checked November 14, 2026)