Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require sockets to have a named "context" #33

Open
SoniEx2 opened this issue Apr 5, 2023 · 10 comments
Open

Require sockets to have a named "context" #33

SoniEx2 opened this issue Apr 5, 2023 · 10 comments

Comments

@SoniEx2
Copy link

SoniEx2 commented Apr 5, 2023

The APIs should require a named "context", tho it can be empty for POSIX runtimes. Then the CLI for "granting access" would take the context like so:

--allow-outbound=postgres@tcp://my.postgres.example:5432 --allow-outbound=https@tcp://*:443 --deny-outbound=https@tcp://my.internal.example:443

This would be useful in preventing SSRF. An application which does not support the use of named "context", like a POSIX runtime, would simply use an empty name for these, at the caveat of having weaker protection against SSRF.

@sunfishcode
Copy link
Member

This is the purpose of the network handle argument, which must be passed to bind, connect, and listen. The behavior of this handle is host-specific, and indeed it will vary between POSIX-like and more restrictive environments. Using a handle means we avoid passing around a string, which is desirable since some use cases will want more elaborate rules than a simple string can provide.

@SoniEx2
Copy link
Author

SoniEx2 commented Apr 5, 2023

On the other hand using a string (or something like it) means POSIX could add support for it.

Being able to expose application structure to OS firewall would be amazing, and WASI seems like the perfect place to start. Currently the OS can only see applications as opaque processes, with no way of knowing if a connection to e.g. the database is being made from the database-related code or from a SSRF.

We don't think an opaque handle would be useful outside of WASI. At least, not without undue complexity. A string seems a lot more appropriate for something that can be done at the OS level. But, we'd love to be proven wrong.

@sunfishcode
Copy link
Member

How could POSIX add support for this? I'm not aware of any analogous feature in POSIX.

One complication with strings is that it requires coordination and even a level of trust between the program, its dependencies, and the user of the program. In a large program with many dependencies, how can we be sure that the dependencies all agree on a common naming convention and avoid collisions? The handle approach solves this by avoiding the use of a namespace that everything must implicitly cooperate in, and by putting the needs of a component in the component's signature.

@SoniEx2
Copy link
Author

SoniEx2 commented Apr 6, 2023

The usual way to do it in POSIX (or really anywhere, at least today) is to nag a project's developers to add individual SOCKS proxy settings for the app's different subcomponents, and then run different SOCKS proxies with the appropriate firewall rules.

But it's a lot more expensive than simply having the app tag its own traffic appropriately. Unfortunately the lack of some sort of setsockopt(SO_TAG) requires this complexity. WASI could be the first to provide such a setsockopt(SO_TAG) API. Which, yes, could be done with network, we guess. Whatever can be used for tagging the socket/connection for a given set of local firewall rules.

@badeend
Copy link
Collaborator

badeend commented Apr 9, 2023

I can't think of any problem that context/tag strings solve, that network handles doesn't already solve.

Based on the example in your initial post, I think you're after named "preopens" for network handles. This is most definitely possible to implement, but preopens are not a part of this proposal. Maybe a better place for such a feature would be in wasi-cli?


An application which does not support the use of named "context", like a POSIX runtime, would simply use an empty name for these, at the caveat of having weaker protection against SSRF.

In general, having security be opt-in is not desirable design path.

@SoniEx2
Copy link
Author

SoniEx2 commented Apr 9, 2023

Unfortunately POSIX is a pre-security standard, so if your goal is compatibility with it then you need security to be opt-in. Alternatively you should ditch POSIX entirely.

The thing about context/tag strings is that they're defined by the app. This is a feature, because it allows the app to disclose its internal structure. It allows the app to say "this is the C++ class that is opening this socket". How do you do that with network handles?

@badeend
Copy link
Collaborator

badeend commented Apr 10, 2023

How do you do that with network handles?

In the case of "named preopens", the programs gets passed in a set of network handles and the application code can then look up the appropriate handle by name.

@SoniEx2
Copy link
Author

SoniEx2 commented Apr 10, 2023

Okay, but that's a mechanism that wouldn't be usable by existing software (apps or even OSes), while a setsockopt extension would be. That's the tradeoff.

@badeend
Copy link
Collaborator

badeend commented Apr 10, 2023

It's just as compatible with pre-existing software as adding an brand new socket option.

@SoniEx2
Copy link
Author

SoniEx2 commented Apr 10, 2023

Okay so let's say a security-hardened OS wants built-in support for something like this.

With socket options, it's just a matter of adding it. Replacing how sockets are opened is a lot more involved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants