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
|
---
title: CI threat model
...
Sorry
CI in the abstract
STRIDE
Threats
---
# Sorry
* RelEng is de-scoping the new CI project to only continuous
integration, dropping delivery and deployment. For now.
* This is a recent change (last week), and may come as a surprise. This
presentation has a butchered threat model that hasn't been reviewed by
other parties yet.
---
~~~dot
digraph "abstract2" {
labelloc=b
developer [shape=octagon label="Developer"];
deployer [shape=octagon label="Reviewer"];
gerrit [label="Gerrit"];
subgraph cluster_ci {
label="CI"
build [label="Untrusted build \n worker"];
build2 [label="Trusted build \n worker"];
arts [label="Artifact store"];
}
developer -> gerrit [headlabel="push \n patchset"];
gerrit -> build [label="trigger"];
deployer -> gerrit [taillabel="CR+2"];
gerrit -> build2 [label="merge and \n upload"];
build2 -> arts [label="upload"];
}
~~~
---
~~~dot
digraph "ci-threat" {
labelloc=b
dev [label="Developer"]
vcs [label="Code review\nsystem", style=filled]
dep [label="Deployer"]
# Developers can submit patches to the VCS system
dev -> vcs [label="patch",color="blue"]
# Deployers can merge patches in the codebase
dep -> vcs [label="+2",color="red"]
# This graph includes all of the "untrusted" environments
subgraph cluster_untrusted {
node [style=filled]
label = "Untrusted environents"
color=blue
subgraph cluster_unt_ci {
label="CI"
style="dashed"
ci [label="CI system"]
ciui [label="CI RO web UI"]
tempartifacts [label="Artifact store\n for temporary blobs\nincl. build logs"]
}
subgraph cluster_testing {
node [style=filled]
testenv [label="test cluster"]
label = "deployment-prep"
style = "dashed"
}
}
subgraph cluster_trusted {
node [style=filled]
label = "Trusted environents"
color=red
subgraph cluster_tr_ci {
label="Trusted CI"
style = "dashed"
trustedci [label="Secure CI component"]
trustedciui [label="Admin CI UI"]
artifacts [label="Artifact store\n for persistent blobs"]
# the trusted CI component can upload artifacts to the store(s)
trustedci -> artifacts
# The admin CI interface can submit and view jobs in the secure ci
trustedciui -> trustedci [label="submit/view"]
}
subgraph cluster_prod {
label = "Production"
style = "dashed"
prodenv [label="Production nodes"]
deployment [label="Deployment nodes"]
# The deployment nodes can deploy artifacts to production
deployment -> prodenv
}
# The artifact store
deployment -> artifacts [style="dashed",label="pull"]
}
# The admin CI interface can submit jobs to the untrusted CI
trustedciui -> ci [label="submit"]
# Merging a patch generates a trusted job
vcs -> trustedci [label="+2/gns",color="red"]
# The developer can view the results of builds
dev -> ciui [style="dashed"]
ciui -> ci [style="dashed"]
ciui -> tempartifacts [style="dashed"]
vcs -> ci [label="PS", color="blue"]
# The insecure ci can upload artifacts to the temporary store
ci -> tempartifacts
testenv -> tempartifacts [style="dashed",label="pull"]
# Deployers can deploy the resulting artifacts
dep -> deployment [label="deploy"]
# The deployer can submit/view jobs on the trusted CI
dep -> trustedciui [label="submit/view"]
subgraph cluster_legend {
labelloc=t
label="Legend"
{
key [label=<<table border="0" cellspacing="0" cellpadding="2">
<tr><td align="right" port="rw">Read-Write</td></tr>
<tr><td align="right" port="ro">Read-Only</td></tr>
</table>>,shape=plaintext]
dest [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td port="rw"> </td></tr>
<tr><td port="ro"> </td></tr>
</table>>,shape=plaintext]
key:rw:e -> dest:rw:w
key:ro:e -> dest:ro:w [style="dashed"]
rankdir=RL
rank=same
}
}
}
~~~
---
# STRIDE
**S**poofing
**T**ampering
**R**epudiation
**I**nformation disclosure
**D**enial of service
**E**levation of privilege
---
# Threats: Low severity
* Deny service by
* using all build node capacity
* service by filling Gerrit storage
* service by filling temporary artifact storage
* service by filling persistent artifact storage
* service by filling production node storage
* service by using all test environment capacity
* service by using all production node capacity
# Medium severity
* Spoof
* developer to Gerrit web UI
* developer to test environment, via HTTP
* developer to CI web UI
# High severity
* Tamper
* with code modifying it in Gerrit
* with code operating the build node itself
* Disclose
* information about production site users
* secrets from build nodes, e.g., credentials
* security fixes under embargo, from prod
* Elevate privilege by impersonating SRE/admin
* on Gerrit host (shell), over ssh
* on Gerrit UI/API, over HTTP
* on test environment, over ssh
* on test environment, over HTTP
* on CI web UI node, over ssh
* on CI web UI node, over HTTP
* on build nodes, over ssh
* by breaking out of build sandbox on build nodes
|