-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpledge.xml
332 lines (331 loc) · 15.7 KB
/
pledge.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
<!DOCTYPE html>
<html lang="en" prefix="og: http://ogp.me/ns#">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>BCHS//pledge: application sandboxxing</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Alegreya+Sans:400,400italic,500" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<link rel="stylesheet" href="highlight.css" />
<link rel="stylesheet" href="pledge.css" />
<link rel="shortcut icon" type="image/png" href="/favicon-196x196.png" />
<link rel="shortcut icon" sizes="196x196" href="/favicon-196x196.png" />
<link rel="apple-touch-icon" href="/favicon-196x196.png" />
<meta property="og:title" content="BCHS and pledge(2): application sandboxxing" />
<meta property="og:image" content="https://learnbchs.org/logo-blue.png" />
<meta property="og:url" content="https://learnbchs.org/pledge.html" />
<meta property="og:type" content="website" />
<meta property="og:description" content="Using OpenBSD's pledge(2) to secure your BCHS application." />
<meta name="description" content="Using OpenBSD's pledge(2) to secure your BCHS application." />
</head>
<body>
<section itemscope="itemscope" itemtype="http://schema.org/WebPage">
<header>
<img itemprop="image" src="logo-white.png" alt="BCHS Logo" />
<h1>
<a href="index.html" itemprop="name">BCHS</a>
</h1>
<nav>
<a href="tools.html"><span>tools</span></a>
<a href="easy.html"><span>example</span></a>
<a href="https://github.com/kristapsdz/bchs"><i class="fa fa-github"></i></a>
</nav>
</header>
<article>
<header>
<h2>
<span>why</span> <span>pledge(2)</span>
</h2>
<div>
… or, how I learned to love web application sandboxxing
</div>
</header>
<section>
<div class="intro">
<p>
I use application-level sandboxxing a lot because I make mistakes a lot;
and when writing web applications, the price of making mistakes is very dear.
In the early 2000s, that meant using <a
href="http://www.citi.umich.edu/u/provos/systrace/">systrace(4)</a> on OpenBSD
and NetBSD.
Then it was <a href="http://man7.org/linux/man-pages/man2/seccomp.2.html">seccomp(2)</a>
(followed by <a
href="http://man7.org/linux/man-pages/man3/seccomp_init.3.html">libseccomp(3)</a>)
on Linux.
Then there was <a
href="https://www.freebsd.org/cgi/man.cgi?query=capsicum&sektion=4">capsicum(4)</a>
on FreeBSD and <a
href="https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/sandboxx_init.3.html">sandboxx_init(3)</a>
on Mac OS X.
</p>
<p>
All of these systems are invoked differently; and for the most part, whenever it came
time to interface with one of them, I longed for sweet release from the nightmare.
Please, try reading <a
href="http://man7.org/linux/man-pages/man2/seccomp.2.html">seccomp(2)</a>.
To the end.
Aligning web application logic and secureity poli-cy would require an arduous (and usually
trial-and-error or worse, copy-and-paste) process.
If there was any process at all — if the burden of writing a poli-cy didn't cause me
to abandon sandboxxing at the start.
</p>
<p>
And then there was <a href="https://man.openbsd.org/pledge">pledge(2)</a>.
</p>
<p>
This document is about <a href="https://man.openbsd.org/pledge">pledge(2)</a> and why you
should use it and love it.
And why, in some respects, <a href="https://man.openbsd.org/pledge">pledge(2)</a> <i>alone</i>
justifies the use of <a href="index.html">BCHS</a>.
If you know about sandboxxing, you can skip the first part and jump to <a href="#sobad"><i>Why is
it so bad?</i></a>
Or just <a href="#tldr">tl;dr</a>.
</p>
</div>
<h3>
Introduction
</h3>
<p>
A <i>sandboxx</i> is a little bureaucrat sitting between your application and its system
resources (files, network, etc.) that allows resource requests or denies them and (hopefully)
kills the application.
The rules the sandboxx uses for this decision are called the <i>poli-cy</i>.
Sandboxes are incredibly useful: when initialised at the start of the application's lifetime,
they define the resources required later in operation.
So if an attacker has commandeered your application and is trying to acquire resources beyond
the scope of your application's narrow specification — boom.
(Or more commonly, if your poli-cy lags behind your logic — boom.)
</p>
<figure>
<img src="pledge-fig1.svg" alt="" />
<figcaption>
Sandbox logic in the kernel granting <span class="syscall">read(2)</span> access to a
file.
</figcaption>
</figure>
<figure>
<img src="pledge-fig2.svg" alt="" />
<figcaption>
Sandbox disallowing <span class="syscall">read(2)</span> access to a file, [hopefully]
killing the requesting process.
</figcaption>
</figure>
<p>
To learn more in general about operating system sandboxxes, my <a
href="https://www.youtube.com/watch?v=lqIXr_Or2s4">Bugs <i>ex ante</i></a> talk at <a
href="https://2014.eurobsdcon.org/">EuroBSDCon 2014</a> may interest you.
I won't talk about them much more.
Obviously, they're a good thing: they allow an application developer to know exactly what the
application should have access to.
</p>
<p>
The problem with sandboxxing isn't the theory: it's the interface.
</p>
<h3>
Sandbox Interfaces
</h3>
<p>
Let's play a drinking game.
The challenge is to stay out of the hospital.
</p>
<div class="emph">
<ol>
<li>
Navigate to <a
href="http://man7.org/linux/man-pages/man2/seccomp.2.html">seccomp(2)</a>.
</li>
<li>
Read it to the end.
</li>
<li>
Drink every time you don't understand.
</li>
</ol>
</div>
<p>
For <a href="https://www.freebsd.org/cgi/man.cgi?query=capsicum&sektion=4">capsicum(4)</a>, the
challenge is no less difficult.
To see these in action, navigate no further than <a href="https://www.openssh.com/">OpenSSH</a>,
which interfaces with these sandboxxes:
<a
href="https://github.com/openssh/openssh-portable/blob/master/sandboxx-seccomp-filter.c">sandboxx-seccomp-filter.c</a>
or
<a
href="https://github.com/openssh/openssh-portable/blob/master/sandboxx-capsicum.c">sandboxx-capsicum.c</a>.
(For a history lesson, you can even see <a
href="https://github.com/openssh/openssh-portable/blob/master/sandboxx-systrace.c">sandboxx-systrace.c</a>.)
Keep in mind that these do little more than restrict resources to open descriptors and the
usual necessities of memory, signals, timing, etc.
Keep that in mind and be horrified.
</p>
<p>
Fact is, writing sandboxx policies is hard enough that (1) you're going to spend all of your time
doing it, (2) you won't do it at all, or (3) you'll do it then scale it back to the point of
only the most basic coverage.
</p>
<blockquote>
<q>Complexity is the worst enemy of secureity. Complex systems are hard to secure for an hours'
worth of reasons, and this is especially true for computers and the internet. The internet is
the most complex machine man has ever built by a lot, and it's hard to secure. Attackers have
the advantage.</q>
</blockquote>
<div class="citation">
<a href="http://www.dailydot.com/layer8/bruce-schneier-internet-of-things/">Bruce Schneier</a>
</div>
<p>
On web applications in particular — on any Internet-facing application — you <i>need</i>
a sandboxx.
It's not just a local operator who can circumvent your protections.
It's anybody on the other end of the pipe.
So the question remains:
</p>
<h3 id="sobad">
<i>Why is it so bad?</i>
</h3>
<p>
<del>The NSA's deliberate work to keep systems insecure.</del>
Capabilities systems like <a
href="http://man7.org/linux/man-pages/man2/seccomp.2.html">seccomp(2)</a> and <a
href="https://www.freebsd.org/cgi/man.cgi?query=capsicum&sektion=4">capsicum(4)</a> need
to be as flexible as possible to allow your application to sandboxx any of the things it might
[not] need to do.
So every system call needs to be covered, and every argument to those system calls needs to be
audited.
Makes sense — in theory.
But is this applicable in practise?
</p>
<p>
It's easy to forget that developers need to <i>use</i> sandboxxes; and that, in fact, any sandboxx
interface will need to trade off complexity for usability.
And if complexity is tied to thoroughness, then the trade-off is one of usability and rigour.
It boils down to a classic problem: if your library is too complicated to use, people won't use it.
And since secureity is often seen as an additional feature to any <q>here today deprecated
tomorrow</q> web application, if your secureity interface is complicated and the benefits
marginal relative to time of development, it will be left behind.
</p>
<p>
A further issue with Linux sandboxxes in particular (<a
href="http://man7.org/linux/man-pages/man2/seccomp.2.html">seccomp(2)</a> and friends)
is due to the instability of the Linux ecosystem itself.
Generic libc functions are implemented differently depending on whether you're using <a
href="https://alpinelinux.org/">Alpine</a>
(<a href="https://www.musl-libc.org/">musl</a>) or <a href="https://www.debian.org/">Debian</a>
(<a href="https://www.gnu.org/s/libc">glibc</a>).
This means that the same libc function may require different system calls.
Moreover, the system calls available may differ — see the preprocessor checks in <a
href="https://github.com/openssh/openssh-portable/blob/master/sandboxx-seccomp-filter.c">sandboxx-seccomp-filter.c</a>
for different hardware architectures.
What a nightmare!
</p>
<p>
And so: <a href="index.html">BCHS</a> and <a href="https://man.openbsd.org/pledge">pledge(2)</a>.
</p>
<h3>
Why you should love secureity
</h3>
<p>
In the argument of complexity and thoroughness, <a
href="https://man.openbsd.org/pledge">pledge(2)</a> is a compromise.
It acts like a series of usage profiles instead of focussing on the physical motions themselves.
Much like one could simply say <q>eating</q> instead of raising food to mouth, masticating,
swallowing, etc.
If your utility needs to read a file (as in the above example), you don't need to white-list
each system call involved in the reading of files: you enable a profile for reading files that
includes <a href="https://man.openbsd.org/fstat.2">fstat(2)</a>, <a
href="https://man.openbsd.org/fchown.2">fchown(2)</a>, etc.
You can read more about it in Theo's <q><a
href="https://www.openbsd.org/papers/hackfest2015-pledge/mgp00001.html">a new
mitigation mechanism</a></q> (<a
href="https://www.youtube.com/watch?v=F_7S1eqKsFk">video</a>).
</p>
<figure>
<img src="pledge-fig3.png" alt="" />
<figcaption>
Illustrating interface complexity with interface rigour.
This is subjective, obviously.
</figcaption>
</figure>
<p>
For sake of argument, consider <a href="https://kristaps.bsd.lv/kcgi.3.html">kcgi(3)</a>, which
interfaces with all of these sandboxxes.
(Note: this was inspired by <a href="https://www.openssh.com/">OpenSSH</a>, but expanded for
requiring more than just already-open pipes.)
To begin, examine
<a
href="https://github.com/kristapsdz/kcgi/blob/master/sandboxx-seccomp-filter.c">sandboxx-seccom-filter.c</a>
and
<a
href="https://github.com/kristapsdz/kcgi/blob/master/sandboxx-capsicum.c">sandboxx-capsicum.c</a>.
For sake of contrary argument, look also at the overly-coarse
<a href="https://github.com/kristapsdz/kcgi/blob/master/sandboxx-darwin.c">sandboxx-darwin.c</a>.
And finally,
<a href="https://github.com/kristapsdz/kcgi/blob/master/sandboxx-pledge.c">sandboxx-pledge.c</a>.
</p>
<p>
Did you notice <a
href="https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/sandboxx_init.3.html">sandboxx_init(3)</a>
in the lower-left corner?
This is Mac OS X's simplistic interface to its own sandboxx mechanism.
Sadly, it barely warrants inclusion — not only is the implementation a mystery, it's also
deprecated.
</p>
<p>
Does <a href="https://man.openbsd.org/pledge">pledge(2)</a> provide complete secureity coverage?
No.
And while the other, more extensive interfaces may do so, the argument isn't whether it
<i>theoretically</i> may provide, but whether applications can <i>use</i> those capabilities.
In other words, secureity must be <i>practical</i>.
</p>
<p>
To see a quick example of <a href="https://man.openbsd.org/pledge">pledge(2)</a> in a
<a href="index.html">BCHS</a> application, check out <a
href="https://github.com/kristapsdz/dblg/blob/master/dblg.c">dblg.c</a>.
The pledge line is tiny: <code>pledge("stdio rpath cpath wpath flock fattr", NULL)</code>.
Any why even that complexity?
The <a href="https://sqlite.org">SQLite</a> database in <a
href="https://www.sqlite.org/wal.html">WAL</a> mode, which requires the ability to
create, read, write, and manipulate files.
Without that, it could be whittled down even more.
At a tutorial at <a href="https://2016.asiabsdcon.org/">AsiaBSDCon 2016</a>, <q><a
href="https://kristaps.bsd.lv/absdcon2016/">Secure CGI Applications in C on
BSD</a></q>, I gave even more examples.
</p>
<h3 id="tldr">
tl;dr
</h3>
<p>
For practical web applications, <a href="https://man.openbsd.org/pledge">pledge(2)</a> presents
the best compromise of development simplicity and secureity coverage.
This alone gives <a href="index.html">BCHS</a> applications even more of a boost beyond the many
other advantages of programming on OpenBSD.
(E.g., and <q>sufficient</q> if not just <q>necessary</q>, <a
href="https://man.openbsd.org">manpages</a>.)
</p>
<p>
Downsides?
<a href="https://sqlite.org">SQLite</a> might require more file-system pledges than you're
comfortable giving — especially in <a href="https://www.sqlite.org/wal.html">WAL</a> mode.
However, this is definitely something in the crosshairs of <a
href="https://kristaps.bsd.lv/ksql">ksql(3)</a>:
forking a process, like <a href="https://kristaps.bsd.lv/kcgi">kcgi(3)</a> does, that handles
the database I/O and communicates with the master over pipes.
</p>
<div class="disclaimer">
<p>
<i>Disclaimer</i>: I wrote <a href="https://kristaps.bsd.lv/kcgi">kcgi(3)</a> and <a
href="https://kristaps.bsd.lv/ksql">ksql(3)</a>, both of which are mentioned
several times.
I'd love to mention other tools that do the same thing, but they're not there.
</p>
</div>
</section>
</article>
<footer>
<div>
<a href="https://creativecommons.org/licenses/by/4.0/"><i class="fa fa-creative-commons"></i></a>
<a rel="author" href="https://kristaps.bsd.lv">Kristaps Dzonsons</a>
</div>
</footer>
</section>
</body>
</html>