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
|
<!-- -*- markdown -*- -->
as --A- Become someone else
===========================
The `as` command can be used to run commands as different users. It should not
leak the existence/absence of a user, nor should it leak permissions from the
calling user into the effective user.
Verification of `as` in the simple case
---------------------------------------
In the simple case, `as` is being called by someone who has permission to do
so, on behalf of a user which exists and can be used.
SCENARIO Default case for as
GIVEN a standard instance
AND testinstance has keys called other
WHEN testinstance, using adminkey, adds user other, using testinstance other
AND testinstance adminkey runs as other whoami
THEN stdout contains other
AND stdout does not contain gitano-admin
Another trivial case is that a user without permission tries to run `as`.
WHEN testinstance other, expecting failure, runs as other whoami
THEN stdout is empty
AND stderr contains Ruleset denied action
AND stderr contains exit:1
The final trivial case is that a user which can run `as` cannot use it to run
`as`.
WHEN testinstance adminkey, expecting failure, runs as other as other whoami
THEN stdout is empty
AND stderr contains Cannot use 'as' to run 'as'
AND stderr contains Validation of command line failed
AND stderr contains exit:1
FINALLY the instance is torn down
Security-related cases for `as` invocation
------------------------------------------
There are a number of security implications for the `as` command. In the
simplest of cases it is only necessary to grant gitano-admin members the right
to run commands `as` other users. In this way, only those who could otherwise
alter the users in the first place can act on their behalf.
There is, however, a potential information leak -- namely if someone who does
not have the right to run commands 'as' another user runs an `as` with a user
which does not exist. It is critical that this simply be reported as a lack of
permission to run any command, and not leak that the target user does not exist
in any way.
SCENARIO Ensuring 'as' does not leak user presence
GIVEN a standard instance
AND testinstance has keys called other
WHEN testinstance, using adminkey, adds user other, using testinstance other
AND testinstance adminkey runs as other whoami
THEN stderr is empty
WHEN testinstance other, expecting failure, runs as badger sshkey list
THEN stdout is empty
AND stderr does not contain badger
Finally we ensure that when a user who may run `as` commands does so, but
manages to typo a username, they get a useful error message.
WHEN testinstance adminkey, expecting failure, runs as badger whoami
THEN stderr contains badger
AND stderr contains does not exist
AND stderr contains exit:1
AND stdout is empty
FINALLY the instance is torn down
As well as not leaking information, use of `as` must not thwart auditability,
so a user with elevated permissions must not be able to frame another user.
SCENARIO Ensuring 'as' does not thwart auditability
GIVEN a standard instance
AND testinstance has keys called other
AND testinstance has keys called sneakybackdoor
WHEN testinstance, using adminkey, adds user other, using testinstance other
AND testinstance uses their ssh public key called sneakybackdoor as stdin
AND testinstance adminkey runs as other sshkey add sneakybackdoor
AND server-side gitano-admin reads git object HEAD^{commit}
THEN stdout contains Added sneakybackdoor for other
AND stdout contains committer Administrator
FINALLY the instance is torn down
Regression checks
=================
When running `as` with commands which consider the keytag during `_prep()` it's
essential that `as` resets it to the "<*>" token which is used during `_run()`
too. This used not to be the case, making it hard to manage SSH keys of users
whose sshkeys had the same names as the keys used by the admin trying to manage
them.
SCENARIO Ensuring 'as' replaces keytag during '_prep()'
GIVEN a standard instance
AND testinstance has keys called other
AND testinstance has keys called spare
WHEN testinstance, using adminkey, adds user other, using testinstance other
AND testinstance adminkey runs as other whoami
THEN stderr is empty
WHEN testinstance uses their ssh public key called spare as stdin
AND testinstance other runs sshkey add adminkey
AND testinstance adminkey runs as other sshkey del adminkey
THEN the output contains SSH authorised key file updated
|