Hacker News new | ask | show | jobs
by brasic 1061 days ago
How would this even be mitigated while preserving the (wacky) existing support for runtime-selected PKCS#11 provider libraries? It strikes me that the most compatible way might be to double down on the wackiness and try to perform the required feature detection in some more indirect way like parsing the named lib with readelf(1) or the platform equivalent.

The sensible thing would be to force users to register available provider shared libraries in an ssh-agent config file, but that feels like a pretty big breaking change.

Edit: Didn’t realize a patch was already available. I see that they did in fact fix this with a breaking change, by simply disabling the functionality by default, and recommending that users allowlist their specific libraries:

  Potentially-incompatible changes
  --------------------------------
  
   * ssh-agent(8): the agent will now refuse requests to load PKCS#11
     modules issued by remote clients by default. A flag has been added
     to restore the previous behaviour "-Oallow-remote-pkcs11"
https://www.openssh.com/releasenotes.html#9.3p2
2 comments

By finally acknowledging that loading plugins via shared objects is a bad idea, and it was only valuable in the days of resource constrained computers.

Any application that wants to use plugins and is security sensitive, should adopt OS IPC, and load them as separate processes.

Process separation was already in place. The PKCS#11 library is loaded by a long lived helper process, not ssh-agent itself.

  > (Note to the curious readers: for security reasons, and as explained in
  > the "Background" section below, ssh-agent does not actually load such a
  > shared library in its own address space (where private keys are stored),
  > but in a separate, dedicated process, ssh-pkcs11-helper.)

That didn’t help because the long lived nature of the helper process exposed it to the shared lib side effects such that they could be chained into a gadget. If I understand correctly, the long life is important for interacting with many smart cards and HSMs because of their APIs.

If you are suggesting that there should be an IPC API for this process and vendors ship a full program that speaks it, that seems reasonable at a glance, but not really something the OpenSSH project can dictate.

Indeed, my suggestion is zero dynamic libraries in security critical code/applications.

If security is a goal, loading in-process foreign code is already a lost battle.

Plugins as dynamic libraries made sense when we were fighting for each MB, not when people have hardware where they go to the extreme of running containers for every application they can think of.

Bonus, processes aren't as heavy as containers.

Would IPC help if a remote attacker was still allowed to execute arbitrary plugins?
It would help against attacks that depend on corrupting process address space, like this one.

Additionally, one could use OS security features to reduce API surface for each plugin, depending on what they are actually supposed to be doing, e.g. no need for file system access if they only do in-memory data processing.

As for "would it help in 100% of the attacks?", no.

Even if there were no plugins support, there is still the possibility to exploit logical errors anyway.

What matters is having a balance between reducing attack surface, and application features, and it than regard process sandboxing is much safer than loading foreign code in-process.

> How would this even be mitigated while preserving the (wacky) existing support for runtime-selected PKCS#11 provider libraries?

Put the pkcs11 libraries in a specific directory, configure only that directory, let users manually add others. Or stop using forwarding and configure ProxyJump where needed. (If that's the only use case you're interested in)