[HN Gopher] Can we get the benefits of transitive dependencies w...
___________________________________________________________________
Can we get the benefits of transitive dependencies without
undermining security?
Author : ltratt
Score : 47 points
Date : 2025-01-28 20:28 UTC (2 hours ago)
(HTM) web link (tratt.net)
(TXT) w3m dump (tratt.net)
| jerf wrote:
| If anything is going to put capabilities into the programmer
| ecosystem, I think it's this problem.
|
| The neat thing about this particular problem is that you can do
| some really coarse things and get some immediate benefit.
| Capabilities in their original form, and perhaps their truest
| form, carry down the call stack, so that code can do things like
| "restrict everything that I call can only append to files in this
| specific subtree" in the most sophisticated implementations. But
| you could do something more coarse with libraries and just do
| things like "These libraries can not access the network", and get
| big wins on some simple assertions. If you're a library for
| turning jpegs into their pixels, you don't need network access,
| and with only a bit more work, you shouldn't even need filesystem
| access (get passed in files if you need them, but no ability to
| spontaneously create files).
|
| This would not be a complete solution, or perhaps even an
| adequate solution, but it would be a great bang-for-the-buck
| solution, and a great way to step into that world and immediately
| get benefits without requiring the entire world to immediately
| rewrite everything to use granular capabilities everywhere.
| marcosdumay wrote:
| Just to say, but You are describing an effect type system. (Or,
| to the "types are static" people, possibly a dynamic effect
| system.)
|
| Capabilities taken literally are more of a network thing (it's
| how you prove you have access to a computer that doesn't trust
| you). On a language, you don't need the capabilities
| themselves.
| wyago wrote:
| Effect typing can achieve capability security statically, but
| I've also frequently seen capabilities used to describe
| dynamic capability systems via various methods involving
| passing capabilities down as reified objects of some sort.
|
| This of course also depends on some related static guarantees
| that a function can't access ambient capabilities not passed
| directly in their arguments, but this is a much simpler
| static guarantee than effect typing and doesn't require
| specific analysis over normal parameter types.
| jonahx wrote:
| > Capabilities taken literally are more of a network thing
| (it's how you prove you have access to a computer that
| doesn't trust you). On a language, you don't need the
| capabilities themselves.
|
| You may be thinking of the term in a different context. In
| this context, they are a general security concept and
| definitely apply to more than the network, including
| languages:
|
| https://en.wikipedia.org/wiki/Capability-based_security
|
| http://habitatchronicles.com/2017/05/what-are-capabilities/
| (this is a great article)
|
| https://www.ponylang.io/
|
| etc...
| bluGill wrote:
| > On a language, you don't need the capabilities
| themselves.
|
| Why not? Sometimes I want that. Just today I was looking at
| some code and realized that it was being used by groups
| that shouldn't. The code needs to be there and is great for
| the correct users, but someone is going around our
| architecture and we didn't notice it.
| jonahx wrote:
| You are replying to the wrong post. I was quoting the GP.
| ajb wrote:
| Capabilities are more general than that. They have been
| around for a long time; one academic design implemented them
| in hardware in 1970[1]. they can be used in as fine grained a
| way as 'you are allowed to access this array in memory and
| nothing else'- which is the sort of thing that needs to be
| built into languages to be maximally useful.
|
| [1] https://en.wikipedia.org/wiki/CAP_computer
| convolvatron wrote:
| I disagree about your last point. I looked at a product
| design once which allowed one to associate a profile with
| each third party library. accesses across library
| boundaries were implementing using classic call gates from
| segmented architectures which could change memory
| visibility and syscall filtering.
|
| so while I agree that language integration is really
| useful, I think you can get a lot out of appropriate
| support in the runtime, most notably the library loader.
| justinpombrio wrote:
| You can do a lot with capabilities at the language level, if
| the language supports it. It doesn't require effect types:
| it's extremely boring from a type system perspective, which
| is an advantage.
|
| Imagine these changes to a language, making it "capability
| safe":
|
| - There is a `Network` object, and it's the _only_ way to
| access the network. Likewise, there 's a `Filesystem` object,
| and it's the _only_ way to access the file system.
|
| - Code cannot construct a `Network` or `Filesystem` object.
| Like, you just can't, there's no constructor.
|
| - The `main()` function is passed a `Network` object and a
| `Filesystem` object.
|
| Consider the consequences of this. The log4j vulnerability
| involved a logging library doing network access. In a
| capability safe language, this could only happen if you
| passed a `Network` object to the logger, either in its
| constructor or in one of its methods. So the vulnerability is
| still possible. But! Now you can't be surprised that your
| logger was accessing the network because you _gave it the
| network_. And a logger asking for network access is
| sufficiently sketchy that log4j almost certainly would have
| made network access _optional_ for the few users that wanted
| that feature, which would have prevented the vulnerability
| for everyone else!
|
| I talked about there being a single monolithic `Filesystem`
| object. That _is_ what would be passed into `main()`, but you
| should also be able to make finer grained capabilities out of
| it. For example, you should be able to use the `Filesystem`
| object to construct an object that has read /write access to
| a directory and its subdirectories. So if a function takes
| one of these as an argument, you know its not mucking around
| outside of the directory you gave it.
|
| Capability safety _within_ a language is stronger than the
| sort of capability safety you can get at the process level or
| at the level of multiple machines. But we want those too!
| gnafkcud wrote:
| this was the original approach for Java, and the main idea
| behind being able to ship untrusted apps directly to the
| user and run them in the browser
|
| tomcat also gave different privilege levels to different
| parts of the classpath
|
| nice idea, but didn't seem to work in practice
| justinpombrio wrote:
| That's what I'm calling capabilities at the application
| level (where you say "this .jar can't access the
| network"), rather than at the language level (where you
| say "this function wasn't given access to the network as
| an argument"). I don't think any widely known language
| has tried capabilities at the language level. (The
| language not widely known that does it is E.)
|
| The real power will come when you can mix them. In one
| direction, that looks like `main()` not getting passed a
| `Network` object because the ".jar" wasn't granted
| network access. In the other direction, that looks like
| the system C library you invoked failing to access the
| network because when you invoked it from Java you failed
| to provide a `Network` object, so it was automatically
| sandboxed to not be able to access the network.
| jonahx wrote:
| Capabilities are the only way.
|
| It is insane to me that in 2025 there is no easy way for me to
| run a program that, say, "can't touch the filesystem or
| network". As you say, even a few simple, very coarse grained
| categories of capabilities would be sufficient for 95% of
| cases.
| IncreasePosts wrote:
| bubblewrap?
| jonahx wrote:
| Nothing in the container space would qualify as "easy" for
| me. I am talking about native OS features. Also linux only
| (afaik)...
|
| Or even, for that matter, some sane capabilities for
| browser extensions.
| taeric wrote:
| I'm curious what all you want to run that you don't want to
| access the filesystem? Or the network?
|
| Like, I get it for a few things. But it is a short path to
| wanting access to files I have created for other things.
| Pictures and videos being obvious files that I likely want
| access to from applications that didn't create them.
|
| Similarly, it is a short hop from "I don't want any other
| application to be able to control my browser" to "except for
| this accessibility application, and this password management
| application, and ..." As we push more and more to happen in
| the browser, it should be little surprise that we need more
| and more things to interact with said browser.
| jonahx wrote:
| I think you misunderstood. Among the coarse grained
| capabilities I mentioned would be "access to folder X and
| it's subfolders" (read or write).
|
| But to answer your question there are, eg, _tons_ of
| programming packages in any language that I want _purely_
| for their computational abilities, and I know this for
| certain when using them. In fact for the vast majority of
| GUI programs I use, or programming packages I use, I know
| exactly what kind of permissions they need, and yet I
| cannot easily restrict them in those ways.
| taeric wrote:
| It is specifically running applications that always trips
| me up here. As a user/operator of the computer, I have
| been bitten by applications being too locked down for
| them to be useful in the past. I /think/ we have gotten
| better such that it is easy to have better OS behavior
| when it wants to restrict an application. But
| specifically sandboxing by default has been a source of
| terrible application behavior for me, in the past. Is a
| lot like using a shadow banned account where everything
| looks correct, but nothing is actually showing up. Very
| confusing.
|
| Now, I think your point on restricting the libraries that
| are imported to a program makes a ton of sense. I'm not
| entirely clear where I would want the "breaker box" of
| what an application is allowed to do to be located, but
| it is crazy how much just importing some library will do
| in many programs.
| jonahx wrote:
| Well you are ofc free to give applications full reign if
| you want. But you should at least be _able_ to say, "No,
| desktop calculator I just downloaded, you can't do
| anything but compute and draw things in your application
| window".
|
| More broadly, creating a good UI around granting
| capabilities is non-trivial. But that's a separate
| problem from simply not being able to make even the most
| basic kinds of restrictions that you want in most cases.
| taeric wrote:
| Totally fair. I just don't know of that many (any?)
| "desktop calculator" applications that people download.
| I'm far more expecting that people are downloading and
| running social applications than they are isolated
| things.
|
| Mostly fair that it would be good if we could say "on
| site foo.com, request for any access to not-foo.whatever
| that happens." I can't remember the last time I saw the
| sheer number of third party network accesses that happens
| on far too many sites. It was sobering.
| groby_b wrote:
| Simple example: Third party SW in a corporate context.
| Maybe you want to extend some permissions to some internal
| sites/parts of the FS, but fundamentally, there's limited
| trust.
| taeric wrote:
| This is an odd one. At face value, I want to agree. At
| the same time, if you don't trust the operator of the
| computer with access to data, why are we also worried
| about programs they run? If you don't trust them with
| access, then just don't give them access?
|
| I'm open to the idea that some people are locked down
| such that they can't install things. And, that makes a
| lot of sense. You can have a relationship that is
| basically, "I trust them with access to data running this
| closed set of applications." Managing system
| configurations makes a ton of sense.
|
| But, as soon as you have full trust of system management
| on a group, you start getting in odd worlds where you
| want to allow them to have full access, but want to stop
| unauthorized use. Which, we don't have a way to
| distinguish use from access for most data.
| groby_b wrote:
| Trusting the user does not transitively extend to the
| software they use. You might be OK with them e.g. looking
| at company financials, but you'd really like to be sure
| e.g. that the syntax highlighter they use doesn't go and
| exfil that data. You still want them to be able to use
| the syntax highlighter. (Yes, it's an obviusly made-up
| example_
|
| You _can_ fully vet apps, each and every one. Or you can
| choose a zero-trust approach and only vet the apps where
| it's necessary to extend trust.
| bluGill wrote:
| Anything really. I tried to print from a sandboxed
| application the other day and turns out it can't be done -
| or at least it can't be done by "common user". As an
| educated person who has been using unix of all sorts I
| could probably figure it out, but it isn't something I
| should have to figure out in 2025. (it was a pain in 1998,
| but it worked better than the snap sandboxes of today
| despite the pushers of snap from an organization claiming
| that ease of use is important)
| taeric wrote:
| Right, but this is largely to my point? I said in another
| thread that sandboxing often feels like being shadow
| banned on your own computer.
|
| I get wanting "safe" computers. I'm not clear that we can
| technically define what legally "safe" means, though. :(
|
| Now, i grant, we can probably get further than I would
| spit ball based on some bad interactions in the past.
| BobbyTables2 wrote:
| How about "curl" and "wget" shouldn't have free rein to
| read/upload and/or overwrite every damn file owned by my
| user?
|
| Why does "ping" need to have file system access?
| zokier wrote:
| systemd-run inherits afaik all the extensive sandboxing
| features from systemd
|
| https://www.freedesktop.org/software/systemd/man/latest/syst.
| ..
|
| https://www.freedesktop.org/software/systemd/man/latest/syst.
| ..
|
| sure, the command line get bit verbose but nothing that an
| alias or small wrapper couldn't solve
|
| the big problem is that modern operating systems have huge
| surface area and applications tend to expect all sorts of
| things, so figuring out what you need to allow is often non-
| trivial
| dooglius wrote:
| Can do this with Qubes OS by running in a non-networked qube
| est31 wrote:
| What about Deno?
| https://docs.deno.com/runtime/fundamentals/security/#key-
| pri...
| IshKebab wrote:
| Deno controls access at the process level, so it's better
| than nothing but it doesn't really help with this specific
| problem. Also it delegates setting the permissions up to
| the user, and we know that in practice everyone is just
| going to --allow-all.
| daveguy wrote:
| Doing this at the program level is implemented in Linux by
| SELinux, which defines mandatory access controls (aka
| limitations on capabilities). This was difficult to get right
| by default and make a smoothly functioning distro with
| policies enabled. But it is enabled by default in Fedora.
|
| https://en.m.wikipedia.org/wiki/Security-Enhanced_Linux
|
| To enable this at the programming level would require an
| enforcement mechanism at the level of a language VM or OS. It
| would require more overhead to enforce at that level, but the
| safety benefits within a language may be worth it.
| fsflover wrote:
| > in 2025 no easy way for me to run a program that, say,
| "can't touch the filesystem or network".
|
| Qubes OS exists for more than 10 years already. My daily
| driver, can't recommend it enough.
| Veserv wrote:
| That is almost the exact backwards way to talk about
| capabilities. It is not about "restricting" access, it is about
| "granting" access.
|
| "These libraries can not access the network." No. "These
| libraries have not been given access to the network (and by
| default none are given access)."
|
| From an implementation perspective, this is just passing in
| access rights as "local" resources instead of using "global"
| resources. For instance, it is self-evident that other code can
| not use your B-Tree local variable if you did not pass a
| reference to it to any called functions (assuming no arbitrary
| pointer casts). You just do the same with these "resources". It
| is just passing things to functions instead of relying on
| globals. The only difficulty is making these actions/resources
| "passable", which is trivial at the language-level, and "fine-
| grained/divisible" to avoid over-granting.
| JoachimSchipper wrote:
| I really like this article. I do think it's useful to consider
| that the unit of isolation ("process") of the cloud era is a VM
| or container, and that the major clouds _do_ have some sort of
| permissions model.
| zokier wrote:
| I'm bit surprised that browsers did not get a mention here. They
| are one of the big examples of how an application can be split
| into gazillion small processes, split along trust boundaries,
| while also being pretty performance sensitive applications.
|
| As for transitive deps, I have some hopes for more "distro" like
| models to arise. In particular I see clear parallels in how
| traditional Linux distros work and how large faang style
| monorepos work. So maybe we could see more these sort of
| platforms/collections of curated libraries that avoid these deep
| transitive dep trees by hoisting all the deps into one _cohesive_
| global dependency that has at least some more eyes on it.
| mike_hearn wrote:
| Yes, and Chrome's Mojo IPC system is actually one of the only
| parts of the codebase that's neatly factored out (somewhat)
| into a reusable library.
|
| https://chromium.googlesource.com/chromium/src/+/master/mojo...
|
| In the past I used the Java SecurityManager to do a PoC PDF
| renderer that sandboxed the Apache PDFbox library. I lowered
| the privilege of the PDF rendering component and tested it with
| a PDF that exploited an old XXE vulnerability in the library.
| It worked! Unfortunately, figuring out how to do that wasn't
| easy and the Java maintainers got tired of maintaining
| something that wasn't widely used, so they ripped it out.
|
| There are some conceptual and social difficulties with this
| kind of security, at some point I should write about them.
|
| 1. People get distracted by the idea of pure capability
| systems. See the thread above. Pure caps don't work, it's been
| tried and is an academic concept that nothing real uses but
| which sucks up energy and mental bandwidth.
|
| 2. People get distracted by speculation attacks. In process
| sandboxing can't stop sandboxed code from reading the address
| space, so this is often taken as meaning everything has to be
| multi-process (like Mojo). But that's not the case. Speculation
| attacks are read only attacks. To do anything useful you have
| to be able to exfiltrate data. A lot of libraries, if properly
| restricted, have no way to exfiltrate any data they
| speculatively access. So in-process sandboxing can still be
| highly useful even in the presence of Spectre. At the same
| time, some libraries DO need to be put into a separate address
| space, and it may even change depending on how it's used. Mojo
| is neat partly because it abstracts location, allowing
| components to run either inproc or outproc and the calling code
| doesn't know.
|
| 3. People get distracted by language neutrality. Once you add
| IPC you need RPC, and once you add RPC it's easy to end up
| making something that's fully language neutral so it turns into
| a fairly complex IDL driven system. The SecurityManager was
| nice because it didn't have this problem.
|
| 4. Kernel sandboxing is an absolute shitshow on every OS.
| Either the APIs are atrocious and impossible to figure out, or
| they're undocumented, or both, and none of them provide
| sandboxing at the right level e.g. you can't allow a process to
| make HTTP requests to specific hosts because the kernel doesn't
| know anything about HTTP.
|
| Sandboxing libraries effectively is still IMHO an open research
| problem. The usability problems need someone to crack it, and
| it'll probably be language/runtime specific when they do even
| if libraries like Mojo are sitting there under the hood.
___________________________________________________________________
(page generated 2025-01-28 23:00 UTC)