Basis Lab

Letting a Model Call Your Code Safely

Run It as Nobody, Owning Nothing

Last timeChoosing Where the Boundary Goes

The identity a submission runs under is the whole list of what it can reach, so hand it one that owns nothing and ask the kernel for only the sixty entry points the job uses.

A service that runs a submitted program against ten inputs and hands back what

it printed has already decided the interesting part before the program starts.

The decision is not which code to accept. It is which identity the code gets to

borrow.

What is actually at risk

The instinct is to look at the submission. Read it, scan it, run a pattern over

it, decide whether it looks hostile. That instinct is answering the wrong

question, and the reason is mechanical rather than philosophical. A program is

not text that does things. It is a sequence of requests to the kernel, and the

kernel does not grant a request because the code meant well. It grants a

request because the identity making it is permitted to.

So the question to settle first is not what this program does. It is what the

identity it will run under can reach. That reach is transitive and almost

nobody draws the whole of it. If the identity may read one file, it may read

every credential that file holds. If a credential opens a database, the reach

includes the database. If the database holds other readers' submissions, the

reach includes those as well, and the submission never had to do anything

inventive to arrive there.

Two of the ten things a hostile submission tries are exactly this and nothing

more. Reading a file that holds credentials, and reading another reader's

submission, are ordinary file reads made by an identity that was allowed to

make them. There is no exploit in either. There is a permission.

FIG 1Four refusals, and what is left after them
The four refusals are independent and they do not substitute for each other. Read the bottom box as the honest limit of this page: taking privileges away answers the attempts that need permission, and says nothing at all about the ones that need only a large number.

Run as nobody

Nobody is a specific thing, and it is three conditions rather than one. An

identity whose numeric id is not zero. An identity that owns no file anywhere

on the host. An identity that belongs to no group which grants access to

anything. The first condition is the one everybody applies. The second and

third are what make the first worth applying.

Running as the privileged identity inside the boundary is the single most

common mistake here, and the usual defence is that the boundary holds anyway.

Sometimes it does. The trouble is that the privileged identity is what every

published escape is written against, because an escape has to begin with a call

that only a privileged identity may make. Dropping the identity costs nothing

at start-up and removes the first step of most of them.

Give each submission a fresh identity where you can. Two readers sharing one

identity share everything either of them may read, which turns the tenth

attempt on the list, leaving a process running after the answer was returned,

into a way of watching the next reader's work.

The lesson stops here

9 more paragraphs to go

You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.

The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.

See the planThe contents

This is the reading half

Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.

The contents

The rest of this course

  1. 01What a Submitted Program Can Actually Ask For
  2. 02Four Places the Boundary Can Go, and What Each One Stopsopening only
  3. 03Run It as Nobody, Owning Nothingyou are here
  4. 04Five Ceilings, and the Twenty Cores They Implyopening only
  5. 05Give It No Route Out, Then Name the Exceptionsopening only
  6. 06Nothing in the Environment Worth Stealingopening only
  7. 07The Narrow Door, and Nothing Elseopening only
  8. 08Ten Checks, and the One Wall That Can Still Fallopening only

Read alongside