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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 7]>
<html id="ie7" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html id="ie8" dir="ltr" lang="en-US">
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html dir="ltr" lang="en-US"><!--<![endif]--><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>ExMachina Code Audit | Somewhere Between Nowhere</title>
<link rel="profile" href="http://gmpg.org/xfn/11">
<link rel="stylesheet" type="text/css" media="all" href="ExMachina%20Code%20Audit%20%7C%20Somewhere%20Between%20Nowhere_files/style.css">
<link rel="pingback" href="https://www.betweennowhere.net/blog/xmlrpc.php">
<!--[if lt IE 9]>
<script src="https://www.betweennowhere.net/blog/wp-content/themes/twentyeleven/js/html5.js" type="text/javascript"></script>
<![endif]-->
<meta name="robots" content="noindex,nofollow">
<link rel="alternate" type="application/rss+xml" title="Somewhere Between Nowhere » Feed" href="https://www.betweennowhere.net/blog/feed/">
<link rel="alternate" type="application/rss+xml" title="Somewhere Between Nowhere » Comments Feed" href="https://www.betweennowhere.net/blog/comments/feed/">
<link rel="alternate" type="application/rss+xml" title="Somewhere Between Nowhere » ExMachina Code Audit Comments Feed" href="https://www.betweennowhere.net/blog/2012/11/exmachina/feed/">
<script type="text/javascript" src="ExMachina%20Code%20Audit%20%7C%20Somewhere%20Between%20Nowhere_files/comment-reply.js"></script>
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://www.betweennowhere.net/blog/xmlrpc.php?rsd">
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="https://www.betweennowhere.net/blog/wp-includes/wlwmanifest.xml">
<link rel="prev" title="ExMachina Review Delayed" href="https://www.betweennowhere.net/blog/2012/10/exmachina-review-delayed/">
<link rel="next" title="I Don’t Care About the Election" href="https://www.betweennowhere.net/blog/2012/11/i-dont-care-about-the-election/">
<meta name="generator" content="WordPress 3.4.2">
<link rel="canonical" href="https://www.betweennowhere.net/blog/2012/11/exmachina/">
<link rel="shortlink" href="https://www.betweennowhere.net/blog/?p=392">
</head>
<body class="single single-post postid-392 single-format-standard single-author singular two-column right-sidebar">
<div id="page" class="hfeed">
<header id="branding" role="banner">
<hgroup>
<h1 id="site-title"><span><a href="https://www.betweennowhere.net/blog/" title="Somewhere Between Nowhere" rel="home">Somewhere Between Nowhere</a></span></h1>
<h2 id="site-description">It's a funny place to be.</h2>
</hgroup>
<a href="https://www.betweennowhere.net/blog/">
<img src="ExMachina%20Code%20Audit%20%7C%20Somewhere%20Between%20Nowhere_files/shore.jpg" alt="" height="288" width="1000">
</a>
<form method="get" id="searchform" action="https://www.betweennowhere.net/blog/">
<label for="s" class="assistive-text">Search</label>
<input class="field" name="s" id="s" placeholder="Search" type="text">
<input class="submit" name="submit" id="searchsubmit" value="Search" type="submit">
</form>
<nav id="access" role="navigation">
<h3 class="assistive-text">Main menu</h3>
<div class="skip-link"><a class="assistive-text" href="#content" title="Skip to primary content">Skip to primary content</a></div>
<div class="skip-link"><a class="assistive-text" href="#secondary" title="Skip to secondary content">Skip to secondary content</a></div>
<div class="menu"><ul><li><a href="https://www.betweennowhere.net/blog/" title="Home">Home</a></li></ul></div>
</nav><!-- #access -->
</header><!-- #branding -->
<div id="main">
<div id="primary">
<div id="content" role="main">
<nav id="nav-single">
<h3 class="assistive-text">Post navigation</h3>
<span class="nav-previous"><a href="https://www.betweennowhere.net/blog/2012/10/exmachina-review-delayed/" rel="prev"><span class="meta-nav">←</span> Previous</a></span>
<span class="nav-next"><a href="https://www.betweennowhere.net/blog/2012/11/i-dont-care-about-the-election/" rel="next">Next <span class="meta-nav">→</span></a></span>
</nav><!-- #nav-single -->
<article id="post-392" class="post-392 post type-post status-publish format-standard hentry category-uncategorized">
<header class="entry-header">
<h1 class="entry-title">ExMachina Code Audit</h1>
<div class="entry-meta">
<span class="sep">Posted on </span><a href="https://www.betweennowhere.net/blog/2012/11/exmachina/" title="2131" rel="bookmark"><time class="entry-date" datetime="2012-11-04T21:31:56+00:00" pubdate="">2012.1104</time></a><span class="by-author"> <span class="sep"> by </span> <span class="author vcard"><a class="url fn n" href="https://www.betweennowhere.net/blog/author/nick/" title="View all posts by nick" rel="author">nick</a></span></span> </div><!-- .entry-meta -->
</header><!-- .entry-header -->
<div class="entry-content">
<ul>
<li><a href="#exmachina-sec-1">Introduction</a></li>
<li><a href="#exmachina-sec-2">Code Snippets</a>
<ul>
<li><a href="#sec2_1">Authentication</a>
<ul>
<li><a href="#sec2_1_1">Authentication is Optional</a>
<ul>
<li><a href="#exmachina-sec-2_1_1_1">Non-Optional Authentication</a></li>
</ul>
</li>
<li><a href="#exmachina-sec-2_1_2">Authentication Failures Kill the Server</a></li>
<li><a href="#exmachina-sec-2_1_3">Plain Text Passwords</a>
<ul>
<li><a href="#exmachina-sec-2_1_3_1">Don’t Store the Password in Plain Text</a></li>
</ul>
</li>
<li><a href="#exmachina-sec-2_1_4">Untrusted Client Password Setting</a>
<ul>
<li><a href="#exmachina-sec-2_1_4_1">Don’t Set the Password from an Untrusted Client</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#exmachina-sec-2_2">Socket Binding</a>
<ul>
<li><a href="#exmachina-sec-2_2_1">A Self DOSing Platform</a>
<ul>
<li><a href="#exmachina-sec-2_2_1_1">Don’t Self DOS</a></li>
</ul>
</li>
<li><a href="#exmachina-sec-2_2_2">Problematically Trustworthy</a>
<ul>
<li><a href="#exmachina-sec-2-2-2_1">Be Less Trusting</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#exmachina-sec-3">Conclusion</a></li>
</ul>
<div id="outline-container-1" class="outline-2">
<h1 id="exmachina-sec-1">Introduction</h1>
<div id="text-1" class="outline-text-2">
<p>I’ve been poking around <a href="https://github.com/bnewbold/exmachina">Ex Machina</a>
(EM) for a bit. While doing my poking, I tried to see if I could find
any ways to break it. I’m writing this as a running log of my
investigation, so that other folks can see bits of the investigative
process I followed to complete a layman’s security audit.</p>
<p>I’ll make the relevant changes to ExMachina soon. Till then, it shouldn’t be used in production.</p>
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h1 id="exmachina-sec-2">Code Snippets</h1>
<p>For each of these snippets, I’ll first display the code involved,
then state the problems it contains, and finally post the solutions I’ve
been able to find for those problems.</p>
<div id="outline-container-2_1" class="outline-3">
<h2 id="exmachina-sec-2_1">Authentication</h2>
<div id="text-2_1" class="outline-text-3">
<p>For reference, I’m talking about the following block of code. Don’t
worry if you don’t understand it, I’ll break it down the best that I can
understand:</p>
<pre class="src src-python"><span style="color: #00ffff;">class</span> <span style="color: #98fb98;">ExMachinaHandler</span>(bjsonrpc.handlers.BaseHandler):
<span style="color: #ff7f24;"># authentication state variable. If not None, still need to authenticate;</span>
<span style="color: #ff7f24;"># if None then authentication not require or was already successful for</span>
<span style="color: #ff7f24;"># this instantiation of the Handler. This class variable gets optionally</span>
<span style="color: #ff7f24;"># overridden on a per-process basis</span>
secret_key = <span style="color: #7fffd4;">None</span>
<span style="color: #ff7f24;"># ... </span>
<span style="color: #00ffff;">def</span> <span style="color: #87cefa;">authenticate</span>(<span style="color: #00ffff;">self</span>, secret_key):
<span style="color: #00ffff;">if</span> <span style="color: #00ffff;">not</span> <span style="color: #00ffff;">self</span>.secret_key:
log.warn(<span style="color: #ffa07a;">"Unecessary authentication attempt"</span>)
<span style="color: #00ffff;">return</span>
<span style="color: #00ffff;">if</span> <span style="color: #00ffff;">not</span> <span style="color: #00ffff;">self</span>.hash(secret_key.strip()) == <span style="color: #00ffff;">self</span>.secret_key:
<span style="color: #ff7f24;"># fail hard </span>
log.error(<span style="color: #ffa07a;">"Authentication failed!"</span>)
sys.exit()
<span style="color: #00ffff;">self</span>.secret_key = <span style="color: #7fffd4;">None</span></pre>
<p>This is a small piece of code from the class that defines an RPC
server, the bit of code that acts on system maintenence requests from
other programs. This is the workhorse program that actually tries to
change the underlying system based on requests it receives. Some program
uses the exmachina client to send a request to the exmachina server
which in turn changes the underlying system. If you’re a visual learner,
it looks like this:</p>
<pre class="example">"some program" -> "exmachina client" -> "exmachina server" -> "system"</pre>
<p>Since any old “some program” could send data to the EM client, which
passes it along to the EM server, that server had better make sure that
only clients it trusts can send data, otherwise anybody could try to
send destructive commands, like <code>sudo rm -rf /</code>, which is the
equivalent of detonating a small bomb on your computer’s harddrive:
after that command finishes, everything you care about on your system
will be gone.</p>
<p>To use the authentication feature, the client does the following:</p>
<pre class="src src-python"><span style="color: #00ffff;">class</span> <span style="color: #98fb98;">ExMachinaClient</span>():
<span style="color: #00ffff;">def</span> <span style="color: #87cefa;">__init__</span>(<span style="color: #00ffff;">self</span>, socket_path=<span style="color: #ffa07a;">"/tmp/exmachina.sock"</span>, secret_key=<span style="color: #7fffd4;">None</span>):
<span style="color: #ff7f24;"># ... some initialization ... </span>
<span style="color: #00ffff;">if</span> secret_key:
<span style="color: #00ffff;">self</span>.conn.call.authenticate(secret_key)
<span style="color: #ff7f24;"># ... more initialization ... </span></pre>
<p>These code snippets create a few different problems.</p>
</div>
<div id="outline-container-2_1_1" class="outline-4">
<h3 id="exmachina-sec-2_1_1">Authentication is Optional</h3>
<div id="text-2_1_1" class="outline-text-4">
<p>The client has to willingly use the authentication feature. Nothing
bad happens to a client that doesn’t authenticate. The reference code
doesn’t even handle an error condition (“if authentication fails, then
…”), it just keeps initializing.</p>
<p>Servers with keys don’t require clients to have or use those keys:</p>
<pre class="src src-sh"><strong>$ echo <span style="color: #ffa07a;">"12345"</span> | ./exmachina.py -vks /tmp/exmachina.sock &</strong>
2012-10-20 15:06:09,562 DEBUG Waiting for secret key on stdin...
2012-10-20 15:06:09,562 DEBUG Got it!
2012-10-20 15:06:09,562 WARNING Expected to be running as root!
<strong>$ ./test_exmachina.py</strong>
========= Testing JSON-RPC connection
/*: None
/augeas/*: None
/etc/* files:
...</pre>
<p>It should’ve bailed instead of returning results.</p>
</div>
<div id="outline-container-2_1_1_1" class="outline-5">
<h4 id="exmachina-sec-2_1_1_1">Non-Optional Authentication</h4>
<div id="text-2_1_1_1" class="outline-text-5">
<p>The EM server should verify the client once per connection, or every
call, if it’s impossible to determine (or possible to fake) a call’s
source. This brings up the whole ordeal of authentication tokens, which
is a hairy mess I’m not looking forward to.</p>
<p>The best I can do, I think, is to just decorate every function call with an authenticator. I’m not sure how to best do this.</p>
</div>
</div>
</div>
<div id="outline-container-2_1_2" class="outline-4">
<h3 id="exmachina-sec-2_1_2">Authentication Failures Kill the Server</h3>
<div id="text-2_1_2" class="outline-text-4">
<p>Incorrectly authenticating the client kills the server. This is like
taking Google offline because somebody mistyped their Gmail passsword.</p>
<pre class="src src-sh"><strong>$ echo <span style="color: #ffa07a;">"12345"</span> | ./exmachina.py -vks /tmp/exmachina.sock &</strong>
2012-10-20 15:06:09,562 DEBUG Waiting for secret key on stdin...
2012-10-20 15:06:09,562 DEBUG Got it!
2012-10-20 15:06:09,562 WARNING Expected to be running as root!
<strong>$ echo <span style="color: #ffa07a;">"the kind of thing an idiot would have on his luggage"</span> | ./test_exmachina.py -k &</strong>
========= Testing JSON-RPC connection
2012-10-20 15:05:50,453 ERROR Authentication failed!
<strong>$ jobs</strong>
[1]- Done echo <span style="color: #ffa07a;">"12345"</span> | ./exmachina.py -vks /tmp/exmachina.sock
[2]+ Exit 1 echo <span style="color: #ffa07a;">"the kind of thing an idiot would have on his luggage"</span> | ./test_exmachina.py -k
<strong>$</strong></pre>
<p>The server should’ve rejected the client, the server shouldn’t've died.</p>
<p>Looking through the code, it seems like the author might’ve forgot
they were working in the server and actually meant to put that code in
the client.</p>
</div>
</div>
<div id="outline-container-2_1_3" class="outline-4">
<h3 id="exmachina-sec-2_1_3">Plain Text Passwords</h3>
<div id="text-2_1_3" class="outline-text-4">
<p>Next, the password’s stored in plain text. An attacker who wanted to
read the password from the server should be able to… Well, no, the
process separation (via the socket) should prevent that, sort of. As
long as the process separation only exposes entry points into the
server’s functions and not the server object itself, the server’s data
should be protected. This comes with one very obvious caveat:</p>
<p>Anything exported by the host object can be called by the client
object, so the client might be able to set the secret key. We should
make sure that the secret key can only be set by a trusted user.</p>
</div>
<div id="outline-container-2_1_3_1" class="outline-5">
<h4 id="exmachina-sec-2_1_3_1">Don’t Store the Password in Plain Text</h4>
<div id="text-2_1_3_1" class="outline-text-5">
<p>Hashing in Python is simple:</p>
<pre class="src src-python"><span style="color: #00ffff;">def</span> <span style="color: #87cefa;">hash</span>(<span style="color: #00ffff;">self</span>, secret_key, salt):
<span style="color: #ffa07a;">"""Hash the secret key with the salt."""</span>
<span style="color: #00ffff;">if</span> <span style="color: #00ffff;">not</span> salt:
salt = os.urandom(128)
<span style="color: #00ffff;">return</span> hashlib.sha256(secret_key.strip() + salt)</pre>
<p>Set the secret key to that value and it’s generally available.
Salting with a 128 bit salt, while not strictly necessary if no client
has access to the secret key, is nonetheless preventative, in case
somebody does figure out how to read the key. This way, each ExMachina
appears to have a different password (even those with the same password)
and those beautiful SHA256 rainbow tables are mostly irrelevant: nobody
creates 340282366920938463463374607431768211456 tables just in case.</p>
</div>
</div>
</div>
<div id="outline-container-2_1_4" class="outline-4">
<h3 id="exmachina-sec-2_1_4">Untrusted Client Password Setting</h3>
<div id="text-2_1_4" class="outline-text-4">
<p>Unless bjsonrpc offers sufficient process separation between the server and client, <strong>this is introspective Python</strong>
so any program could simply reach far enough up into the client to find
the server and its password. Thus, even if the authentication code
worked, the idea is still completely screwed at a fundamental level.</p>
</div>
<div id="outline-container-2_1_4_1" class="outline-5">
<h4 id="exmachina-sec-2_1_4_1">Don’t Set the Password from an Untrusted Client</h4>
<div id="text-2_1_4_1" class="outline-text-5">
<p>So, this isn’t actually a problem, just something I wanted to point out. The process separation<strong> seems</strong> sufficient, given how bjsonrpc is built, that no client <strong>should</strong>
be able to reach into the server to pull out the password. The server
exposes functions that the client can call, as filtered by bjsonrpc. If
the server doesn’t expose it as a function, the client can’t ask for it.
Thus, the client can’t simply ask for non-functional data: that’s
effectively private, thanks to the process separation.</p>
<p>Even if clients could read the hashed password, as long as they can’t
set data directly on the server, we can safely allow clients to set a
custom password. First, we’d need to force the server to reject any
subsequent attempts to set the password, if it’s already set, and then
we’d need to prevent untrusted users from writing to the socket until
the password is successfully set. We can prevent users from writing data
to the socket by setting the file permissions on the socket correctly
(0×0600, preventing other users from writing to it), before we start
using it for communication. Preventing the server from accepting a new
password involves adding only a few lines of code:</p>
<pre class="src src-python"><span style="color: #00ffff;">def</span> <span style="color: #87cefa;">set_password</span>(<span style="color: #00ffff;">self</span>, password):
<span style="color: #00ffff;">if</span> <span style="color: #00ffff;">self</span>.secret_key:
<span style="color: #00ffff;">return</span>
<span style="color: #00ffff;">else</span>:
<span style="color: #00ffff;">self</span>.secret_key = <span style="color: #00ffff;">self</span>.hash(password, <span style="color: #00ffff;">self</span>.salt)</pre>
<p>Even if client functions can be re-bound, the server’s process separation still protects us here. So, a client could change<code> self.server.call.set_password</code>
to another function, but then it’s no longer a parameter-passing shim
between the client and server process (the part that does the real
work): the client can change its functions, but then it’s no longer
calling the server. This is just message passing, so as long as bjsonrpc
itself doesn’t support clients modifying the server (which I didn’t see
evidence of when I looked, but might’ve missed, but would be shameful
if it did exist).</p>
</div>
</div>
</div>
</div>
<div id="outline-container-2_2" class="outline-3">
<h2 id="exmachina-sec-2_2">Socket Binding</h2>
<div id="text-2_2" class="outline-text-3">
<p>This might be the most important problem, but is likely the one that
requires the most code changes and strictest set of fixes. See if you
can’t figure out what’s up with this code:</p>
<pre class="src src-python"><span style="color: #00ffff;">def</span> <span style="color: #87cefa;">run_server</span>(socket_path, secret_key=<span style="color: #7fffd4;">None</span>, socket_group=<span style="color: #7fffd4;">None</span>):
<span style="color: #ff7f24;"># ... </span>
<span style="color: #00ffff;">if</span> os.path.exists(socket_path):
os.unlink(socket_path)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(socket_path)
sock.listen(1)
<span style="color: #00ffff;">if</span> socket_group <span style="color: #00ffff;">is</span> <span style="color: #00ffff;">not</span> <span style="color: #7fffd4;">None</span>:
socket_uid = os.stat(socket_path).st_uid
socket_gid = grp.getgrnam(socket_group).gr_gid
os.chmod(socket_path, 0660)
os.chown(socket_path, socket_uid, socket_gid)
<span style="color: #00ffff;">else</span>:
os.chmod(socket_path, 0666)
<span style="color: #ff7f24;"># ... </span></pre>
</div>
<div id="outline-container-2_2_1" class="outline-4">
<p id="exmachina-sec-2_2_1">There are two problems. Did you catch them both?</p>
<h3>A Self DOSing Platform</h3>
<div id="text-2_2_1" class="outline-text-4">
<p>If you create multiple ExMachinae each one takes over the default socket after it initializes, DOSing the real EM.</p>
</div>
<div id="outline-container-2_2_1_1" class="outline-5">
<h4 id="exmachina-sec-2_2_1_1">Don’t Self DOS</h4>
<div id="text-2_2_1_1" class="outline-text-5">
<p>Unix file permissions to the rescue again! Set the <strong>directory that contains the socket files</strong> to forbid writes from any but the owning user. That’ll prevent anyone <em>else</em> from overwriting the existing sockets.</p>
<p>If we do that, each socket that replaces the previous one will have
the same permissions the previous one did. We’ll lose communication with
running processes, but that’s about it.</p>
</div>
</div>
</div>
<div id="outline-container-2_2_2" class="outline-4">
<h3 id="exmachina-sec-2_2_2">Problematically Trustworthy</h3>
<div id="text-2_2_2" class="outline-text-4">
<p>We accept input from any user on the system. As mentioned above,
that’s not a great idea, because it makes the process vulnerable to a
wider selection of attackers than necessary.</p>
</div>
<div id="outline-container-2_2_2_1" class="outline-5">
<h4 id="exmachina-sec-2_2_2_1">Be Less Trusting</h4>
<div id="text-2_2_2_1" class="outline-text-5">
<p>Simple. Don’t give any groups access to the socket unless specifically requested. <strong>Never</strong> give the <em>other</em> user access to the socket.</p>
<pre class="src src-python"><span style="color: #00ffff;">def</span> <span style="color: #87cefa;">run_server</span>(socket_path, secret_key=<span style="color: #7fffd4;">None</span>, socket_group=<span style="color: #7fffd4;">None</span>):
<span style="color: #ff7f24;"># ... </span>
<span style="color: #00ffff;">if</span> os.path.exists(socket_path):
os.unlink(socket_path)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(socket_path)
os.chmod(socket_path, 0600)
<span style="color: #00ffff;">if</span> socket_group:
os.chmod(socket_path, 0660)
os.chown(socket_path, gid=grp.getgrnam(socket_group).gr_gid)
<span style="color: #ff7f24;"># ... </span></pre>
</div>
</div>
</div>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h1 id="exmachina-sec-3">Conclusion</h1>
<div id="text-3" class="outline-text-2">
<p>ExMachina is a neat idea but it shouldn’t be used till these issues
are fixed. Then, it should be considered in a testing phase, undergo
peer review, and folks should try to break it for a while before it’s
considered solid.</p>
</div>
</div>
<div style="display: none; font-style: normal; left: 0px; top: 0px; position: absolute; z-index: 9999; border: 1px solid black; background-color: white; padding: 4px;">is a…<p></p>
<div></div>
</div>
</div><!-- .entry-content -->
<footer class="entry-meta">
This entry was posted in <a href="https://www.betweennowhere.net/blog/category/uncategorized/" title="View all posts in Uncategorized" rel="category tag">Uncategorized</a> by <a href="https://www.betweennowhere.net/blog/author/nick/">nick</a>. Bookmark the <a href="https://www.betweennowhere.net/blog/2012/11/exmachina/" title="Permalink to ExMachina Code Audit" rel="bookmark">permalink</a>.
</footer><!-- .entry-meta -->
</article><!-- #post-392 -->
<div id="comments">
<div id="respond">
<h3 id="reply-title">Leave a Reply <small><a rel="nofollow" id="cancel-comment-reply-link" href="https://www.betweennowhere.net/blog/2012/11/exmachina/#respond" style="display: none;">Cancel reply</a></small></h3>
<form action="https://www.betweennowhere.net/blog/wp-comments-post.php" method="post" id="commentform">
<p class="comment-notes">Your email address will not be published. Required fields are marked <span class="required">*</span></p> <p class="comment-form-author"><label for="author">Name</label> <span class="required">*</span><input id="author" name="author" size="30" aria-required="true" type="text"></p>
<p class="comment-form-email"><label for="email">Email</label> <span class="required">*</span><input id="email" name="email" size="30" aria-required="true" type="text"></p>
<p class="comment-form-url"><label for="url">Website</label><input id="url" name="url" size="30" type="text"></p>
<p class="comment-form-comment"><label for="comment">Comment</label><textarea id="comment" name="comment" cols="45" rows="8" aria-required="true"></textarea></p> <p class="form-allowed-tags">You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: <code><a
href="" title=""> <abbr title=""> <acronym title="">
<b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike>
<strong> </code></p> <p class="form-submit">
<input name="submit" id="submit" value="Post Comment" type="submit">
<input name="comment_post_ID" value="392" id="comment_post_ID" type="hidden">
<input name="comment_parent" id="comment_parent" value="0" type="hidden">
</p>
</form>
</div><!-- #respond -->
</div><!-- #comments -->
</div><!-- #content -->
</div><!-- #primary -->
</div><!-- #main -->
<footer id="colophon" role="contentinfo">
<div id="site-generator">
<a href="http://wordpress.org/" title="Semantic Personal Publishing Platform" rel="generator">Proudly powered by WordPress</a>
</div>
</footer><!-- #colophon -->
</div><!-- #page -->
</body></html>
|