File: threat-model.md

package info (click to toggle)
rust-ntpd 1.6.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,904 kB
  • sloc: sh: 57; makefile: 28
file content (438 lines) | stat: -rw-r--r-- 15,118 bytes parent folder | download | duplicates (2)
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
# Threat model

This document a threat model, based on the methodology presented by Eleanor
Saitta, that we as developers use as a guide in our development process. It may
not contain all the context needed to fully understand it, if clarifications are
needed please ask us.

The used methodology is entirely manual, but is derived from
[Trike](https://www.octotrike.org/).

## Actors, Assets & Actions

### Actors

We model the following actors:

- System Admin: Administrator of the system running ntpd-rs
- System User: Non-administrator user of the system running ntpd-rs
- Reference Source: A remote time server we use as a source for our time.
- External Client: A remote user that is allowed to use this instance of
  ntpd-rs to receive time.
- Anonymous: Any other party

### Assets

We model the following assets:

- Clock: The system clock
- Source configuration: The configuration on which sources to use, including
  some metadata on the current status of those sources
- Server configuration: The configuration on which interfaces to provide an
  NTP server on, and who can use those, including some metadata on the current
  server status.
- Request nonce: The random nonce a client uses for a specific request to the
  server to match the response to the request.
- Client NTS keys: The keys a client uses to communicate with a server.
- Client NTS cookies: The cookies a client uses to communicate with the server.
- Server NTS keys: The keys a server uses to communicate with a client
  (ephemeral).
- Server NTS cookies: The cookies a server is about to send to a client
  (ephemeral).
- NTS Cookie keys: The keys a server uses to encrypt cookies.

### Actions

<table>
    <tr>
        <th></th>
        <th colspan=2>Clock</th>
        <th colspan=2>Source Configuration</th>
        <th colspan=2>Server Configuration</th>
        <th colspan=2>Request Nonce</th>
        <th colspan=2>Client NTS Keys</th>
        <th colspan=2>Client NTS Cookies</th>
        <th colspan=2>Server NTS Keys</th>
        <th colspan=2>Server NTS Cookies</th>
        <th colspan=2>NTS Cookie keys</th>
    </tr>
    <tr>
        <th rowspan=2>System admin</th>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Always</td>
        <td bgcolor="green">Create - Always</td>
        <td bgcolor="green">Read - Always</td>
        <td bgcolor="green">Create - Always</td>
        <td bgcolor="green">Read - Always</td>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Always</td>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Always</td>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Always</td>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Always</td>
        <td bgcolor="green">Create - Always</td>
        <td bgcolor="green">Read - Always</td>
        <td bgcolor="green">Create - Always</td>
        <td bgcolor="green">Read - Always</td>
    </tr>
    <tr>
        <td bgcolor="green">Update - Always</td>
        <td>Delete - N/A</td>
        <td bgcolor="green">Update - Always</td>
        <td>Delete - N/A</td>
        <td bgcolor="green">Update - Always</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td bgcolor="green">Update - Always</td>
        <td bgcolor="green">Delete - Always</td>
    </tr>
    <tr>
        <th rowspan=2>System user</th>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Always</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td bgcolor="orange">Create - Sometimes</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td bgcolor="orange">Create - Sometimes</td>
        <td bgcolor="orange">Read - Sometimes</td>
    </tr>
    <tr>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td bgcolor="orange">Update - Sometimes</td>
        <td bgcolor="orange">Delete - Sometimes</td>
    </tr>
    <tr>
        <th rowspan=2>Reference source</th>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
    </tr>
    <tr>
        <td bgcolor="orange">Update - Sometimes</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td bgcolor="red">Delete - Never</td>
    </tr>
    <tr>
        <th rowspan=2>External client</th>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Always</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="green">Read - Always</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td bgcolor="orange">Create - Sometimes</td>
        <td bgcolor="orange">Read - Sometimes</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
    </tr>
    <tr>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td bgcolor="red">Delete - Never</td>
    </tr>
    <tr>
        <th rowspan=2>Anonymous</th>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
        <td bgcolor="red">Create - Never</td>
        <td bgcolor="red">Read - Never</td>
    </tr>
    <tr>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td bgcolor="red">Update - Never</td>
        <td bgcolor="red">Delete - Never</td>
    </tr>
</table>

- Reference sources may update the Clock only when sufficiently many agree and
  don't exceed configured adjustment limits.
- Reference sources may only know request information related to requests to
  them.
- System users may read configuration (both types) only when allowed by system
  admin.
- External clients may know key material and cookies related to their session.

## Failure cases

<table>
    <tr>
        <th></th>
        <th colspan=2>Escalation of Privilege</th>
        <th colspan=2>Denial of Service</th>
    </tr>
    <tr>
        <th rowspan=2>Clock</th>
        <td>Create - NA</td>
        <td bgcolor="green">Read - Low</td>
        <td>Create - NA</td>
        <td bgcolor="yellow">Read - Medium</td>
    </tr>
    <tr>
        <td bgcolor="red">Update - Critical</td>
        <td>Delete - N/A</td>
        <td bgcolor="yellow">Update - Medium</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>Source configuration</th>
        <td bgcolor="red">Create - Critical</td>
        <td bgcolor="yellow">Read - Medium</td>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Low</td>
    </tr>
    <tr>
        <td bgcolor="red">Update - Critical</td>
        <td>Delete - N/A</td>
        <td bgcolor="green">Update - Low</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>Server configuration</th>
        <td bgcolor="yellow">Create - Medium</td>
        <td bgcolor="green">Read - Low</td>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Low</td>
    </tr>
    <tr>
        <td bgcolor="yellow">Update - Medium</td>
        <td>Delete - N/A</td>
        <td bgcolor="green">Update - Low</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>Request nonce</th>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Low</td>
        <td>Create - N/A</td>
        <td>Read - N/A</td>
    </tr>
    <tr>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>Client NTS keys</th>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Critical</td>
        <td>Create - N/A</td>
        <td>Read - N/A</td>
    </tr>
    <tr>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>Client NTS cookies</th>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Low</td>
        <td>Create - N/A</td>
        <td>Read - N/A</td>
    </tr>
    <tr>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>Server NTS keys</th>
        <td>Create - N/A</td>
        <td bgcolor="red">Read - Critical</td>
        <td>Create - N/A</td>
        <td>Read - N/A</td>
    </tr>
    <tr>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>Server NTS cookies</th>
        <td>Create - N/A</td>
        <td bgcolor="green">Read - Low</td>
        <td>Create - N/A</td>
        <td>Read - N/A</td>
    </tr>
    <tr>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
    </tr>
    <tr>
        <th rowspan=2>NTS Cookie keys</th>
        <td bgcolor="red">Create - Critical</td>
        <td bgcolor="red">Read - Critical</td>
        <td>Create - N/A</td>
        <td>Read - N/A</td>
    </tr>
    <tr>
        <td bgcolor="red">Update - Critical</td>
        <td bgcolor="yellow">Delete - Medium</td>
        <td>Update - N/A</td>
        <td>Delete - N/A</td>
    </tr>
</table>

 - Request nonce: The random nonce a client uses for a specific request to the
   server to match the response to the request.
 - Client NTS keys: The keys a client uses to communicate with a server.
 - Client NTS cookies: The cookies a client uses to communicate with the server.
 - Server NTS keys: The keys a server uses to communicate with a client
   (ephemeral).
 - Server NTS cookies: The cookies a server is about to send to a client
   (ephemeral).
 - NTS Cookie keys: The keys a server uses to encrypt cookies.

## Security strategy

- If any actor tries to read the clock, the system will not respond with a
  valid time if the IP address is not on the configured allowlist
- If any actor tries to update the clock, the system tries to verify consensus
  among multiple reference sources
- If any actor tries to update the clock, the system refuses updates beyond a
  configured limit
- If the configuration file (used to create the configuration) is
  world-writable, the system will emit a warning
- If the configuration socket (used to update the configuration) is
  world-writable, the system will emit a warning
- The observability socket (used to read the configuration/status) is a Unix
  socket, which is unreachable over the network by default
- If any actor tries to read the clock too often, the system will stop
  responding a valid time to them
- If the NTS cookie key storage file is world-readable, the system will emit a
  warning. The system will never create this file with permissions other than
  `0600`.

## Data flow diagram

![](flowdiagram.svg)

- The security boundaries between the admin and system users and ntpd-rs run
  through the Unix sockets used for communication.
- The security boundaries for reference sources and external clients run
  through the network sockets used for communication.