Skip to content

Commit 340996a

Browse files
authored
Update vault permissions to always check for asroot (SYN-6726) (#3492)
1 parent 9aa5d57 commit 340996a

File tree

4 files changed

+106
-35
lines changed

4 files changed

+106
-35
lines changed

synapse/lib/storm.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,15 @@ def allowed(self, perms, gateiden=None, default=None):
21872187

21882188
return self.user.allowed(perms, gateiden=gateiden, default=default)
21892189

2190+
def confirmEasyPerm(self, item, perm):
2191+
if not self.asroot:
2192+
self.snap.core._reqEasyPerm(item, self.user, perm)
2193+
2194+
def allowedEasyPerm(self, item, perm):
2195+
if self.asroot:
2196+
return True
2197+
return self.snap.core._hasEasyPerm(item, self.user, perm)
2198+
21902199
def _loadRuntVars(self, query):
21912200
# do a quick pass to determine which vars are per-node.
21922201
for oper in query.kids:

synapse/lib/stormlib/vault.py

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -443,10 +443,6 @@ def getObjLocals(self):
443443
'list': self._listVaults,
444444
}
445445

446-
def _reqEasyPerm(self, vault, perm):
447-
if not self.runt.isAdmin():
448-
self.runt.snap.core._reqEasyPerm(vault, self.runt.user, perm)
449-
450446
async def _addVault(self, name, vtype, scope, owner, secrets, configs):
451447
name = await s_stormtypes.tostr(name)
452448
vtype = await s_stormtypes.tostr(vtype)
@@ -481,15 +477,15 @@ async def _getByName(self, name):
481477
name = await s_stormtypes.tostr(name)
482478

483479
vault = self.runt.snap.core.reqVaultByName(name)
484-
self._reqEasyPerm(vault, s_cell.PERM_READ)
480+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_READ)
485481

486482
return Vault(self.runt, vault.get('iden'))
487483

488484
async def _getByIden(self, iden):
489485
iden = await s_stormtypes.tostr(iden)
490486

491487
vault = self.runt.snap.core.reqVault(iden)
492-
self._reqEasyPerm(vault, s_cell.PERM_READ)
488+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_READ)
493489

494490
return Vault(self.runt, iden)
495491

@@ -500,13 +496,13 @@ async def _getByType(self, vtype, scope=None):
500496
vault = self.runt.snap.core.getVaultByType(vtype, self.runt.user.iden, scope)
501497
if not vault:
502498
return None
503-
self._reqEasyPerm(vault, s_cell.PERM_READ)
499+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_READ)
504500

505501
return Vault(self.runt, vault.get('iden'))
506502

507503
async def _listVaults(self):
508504
for vault in self.runt.snap.core.listVaults():
509-
if not self.runt.snap.core._hasEasyPerm(vault, self.runt.user, s_cell.PERM_READ):
505+
if not self.runt.allowedEasyPerm(vault, s_cell.PERM_READ):
510506
continue
511507

512508
yield Vault(self.runt, vault.get('iden'))
@@ -527,11 +523,12 @@ def __init__(self, runt, valu, path=None):
527523
self.runt = runt
528524

529525
vault = self.runt.snap.core.reqVault(valu)
530-
self.runt.snap.core._reqEasyPerm(vault, self.runt.user, self._vault_perm)
526+
s_stormtypes.confirmEasyPerm(vault, self._vault_perm)
531527

532528
@s_stormtypes.stormfunc(readonly=False)
533529
async def setitem(self, name, valu):
534530
vault = self.runt.snap.core.reqVault(self.valu)
531+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_EDIT)
535532

536533
name = await s_stormtypes.tostr(name)
537534

@@ -544,6 +541,7 @@ async def setitem(self, name, valu):
544541

545542
async def deref(self, name):
546543
vault = self.runt.snap.core.reqVault(self.valu)
544+
s_stormtypes.confirmEasyPerm(vault, self._vault_perm)
547545

548546
name = await s_stormtypes.tostr(name)
549547

@@ -552,6 +550,8 @@ async def deref(self, name):
552550

553551
async def iter(self):
554552
vault = self.runt.snap.core.reqVault(self.valu)
553+
self.runt.confirmEasyPerm(vault, self._vault_perm)
554+
555555
data = vault.get(self._vault_field_name)
556556

557557
for item in data.items():
@@ -564,19 +564,23 @@ def __len__(self):
564564

565565
async def stormrepr(self):
566566
vault = self.runt.snap.core.reqVault(self.valu)
567+
s_stormtypes.confirmEasyPerm(vault, self._vault_perm)
567568
data = vault.get(self._vault_field_name)
568569
return repr(data)
569570

570571
def value(self):
571572
vault = self.runt.snap.core.reqVault(self.valu)
573+
self.runt.confirmEasyPerm(vault, self._vault_perm)
572574
return vault.get(self._vault_field_name)
573575

574576
class VaultSecrets(VaultConfigs):
575577
_vault_field_name = 'secrets'
576578
_vault_perm = s_cell.PERM_EDIT
577579

580+
@s_stormtypes.stormfunc(readonly=False)
578581
async def setitem(self, name, valu):
579582
vault = self.runt.snap.core.reqVault(self.valu)
583+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_EDIT)
580584

581585
name = await s_stormtypes.tostr(name)
582586

@@ -680,13 +684,9 @@ def getObjLocals(self):
680684
def __hash__(self): # pragma: no cover
681685
return hash((self._storm_typename, self.valu))
682686

683-
def _reqEasyPerm(self, vault, perm):
684-
if not self.runt.isAdmin():
685-
self.runt.snap.core._reqEasyPerm(vault, self.runt.user, perm)
686-
687687
async def _storName(self, name):
688688
vault = self.runt.snap.core.reqVault(self.valu)
689-
self._reqEasyPerm(vault, s_cell.PERM_EDIT)
689+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_EDIT)
690690

691691
name = await s_stormtypes.tostr(name)
692692

@@ -703,22 +703,20 @@ async def _gtorConfigs(self):
703703
async def _storConfigs(self, configs):
704704
configs = await s_stormtypes.toprim(configs)
705705
vault = self.runt.snap.core.reqVault(self.valu)
706-
self._reqEasyPerm(vault, s_cell.PERM_EDIT)
706+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_EDIT)
707707
return await self.runt.snap.core.replaceVaultConfigs(self.valu, configs)
708708

709709
async def _gtorSecrets(self):
710710
vault = self.runt.snap.core.reqVault(self.valu)
711-
if not self.runt.isAdmin():
712-
edit = self.runt.snap.core._hasEasyPerm(vault, self.runt.user, s_cell.PERM_EDIT)
713-
if not edit:
714-
return None
711+
if not s_stormtypes.allowedEasyPerm(vault, s_cell.PERM_EDIT):
712+
return None
715713

716714
return VaultSecrets(self.runt, self.valu)
717715

718716
async def _storSecrets(self, secrets):
719717
secrets = await s_stormtypes.toprim(secrets)
720718
vault = self.runt.snap.core.reqVault(self.valu)
721-
self._reqEasyPerm(vault, s_cell.PERM_EDIT)
719+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_EDIT)
722720
return await self.runt.snap.core.replaceVaultSecrets(self.valu, secrets)
723721

724722
async def _gtorPermissions(self):
@@ -727,7 +725,7 @@ async def _gtorPermissions(self):
727725

728726
async def _methSetPerm(self, iden, level):
729727
vault = self.runt.snap.core.reqVault(self.valu)
730-
self._reqEasyPerm(vault, s_cell.PERM_ADMIN)
728+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_ADMIN)
731729

732730
iden = await s_stormtypes.tostr(iden)
733731
level = await s_stormtypes.toint(level)
@@ -736,7 +734,7 @@ async def _methSetPerm(self, iden, level):
736734

737735
async def _methDelete(self):
738736
vault = self.runt.snap.core.reqVault(self.valu)
739-
self._reqEasyPerm(vault, s_cell.PERM_ADMIN)
737+
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_ADMIN)
740738

741739
return await self.runt.snap.core.delVault(self.valu)
742740

@@ -746,9 +744,7 @@ async def stormrepr(self):
746744
def value(self):
747745
vault = self.runt.snap.core.reqVault(self.valu)
748746

749-
if not self.runt.isAdmin():
750-
edit = self.runt.snap.core._hasEasyPerm(vault, self.runt.user, s_cell.PERM_EDIT)
751-
if not edit:
752-
vault.pop('secrets')
747+
if not self.runt.allowedEasyPerm(vault, s_cell.PERM_EDIT):
748+
vault.pop('secrets')
753749

754750
return vault

synapse/lib/stormtypes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ def confirm(perm, gateiden=None):
5050
def allowed(perm, gateiden=None):
5151
return s_scope.get('runt').allowed(perm, gateiden=gateiden)
5252

53+
def confirmEasyPerm(item, perm):
54+
return s_scope.get('runt').confirmEasyPerm(item, perm)
55+
56+
def allowedEasyPerm(item, perm):
57+
return s_scope.get('runt').allowedEasyPerm(item, perm)
58+
5359
class StormTypesRegistry:
5460
# The following types are currently undefined.
5561
base_undefined_types = (

synapse/tests/test_lib_stormlib_vault.py

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,7 @@ async def test_stormlib_vault(self):
142142

143143
# List vaults
144144
opts = {'user': visi1.iden}
145-
ret = await core.callStorm('return($lib.vault.list())', opts=opts)
146-
vaults = [k async for k in ret]
147-
self.len(3, vaults)
145+
self.eq(3, await core.callStorm('return($lib.len($lib.vault.list()))', opts=opts))
148146

149147
# Delete some vaults
150148
opts = {'vars': {'uiden': uiden}}
@@ -157,9 +155,7 @@ async def test_stormlib_vault(self):
157155

158156
# List vaults again
159157
opts = {'user': visi1.iden}
160-
ret = await core.callStorm('return($lib.vault.list())', opts=opts)
161-
vaults = [k async for k in ret]
162-
self.len(1, vaults)
158+
self.eq(1, await core.callStorm('return($lib.len($lib.vault.list()))', opts=opts))
163159

164160
# Rename vault
165161
opts = {'vars': {'giden': giden}}
@@ -190,6 +186,12 @@ async def test_stormlib_vault(self):
190186
q = 'return($lib.vault.get($giden).configs)'
191187
self.eq(await core.callStorm(q, opts=opts), {'server': 'gvault'})
192188

189+
# Set config item without EDIT perms
190+
opts = {'vars': {'giden': giden}, 'user': visi1.iden}
191+
q = '$configs=$lib.vault.get($giden).configs $configs.foo=bar return($configs)'
192+
with self.raises(s_exc.AuthDeny):
193+
await core.callStorm(q, opts=opts)
194+
193195
# replace configs
194196
opts = {'vars': {'giden': giden}}
195197
q = '$lib.vault.get($giden).configs = ({"server": "foobar"}) return($lib.vault.get($giden).configs)'
@@ -222,9 +224,67 @@ async def test_stormlib_vault(self):
222224

223225
# List vaults again
224226
opts = {'user': visi1.iden}
225-
ret = await core.callStorm('return($lib.vault.list())', opts=opts)
226-
vaults = [k async for k in ret]
227-
self.len(0, vaults)
227+
self.eq(0, await core.callStorm('return($lib.len($lib.vault.list()))', opts=opts))
228+
229+
# Runtime asroot
230+
231+
await core.addStormPkg({
232+
'name': 'vpkg',
233+
'version': '0.0.1',
234+
'modules': [
235+
{
236+
'name': 'vmod',
237+
'asroot': True,
238+
'storm': '''
239+
function setSecret(iden, key, valu) {
240+
$secrets = $lib.vault.get($iden).secrets
241+
$secrets.$key = $valu
242+
return($secrets)
243+
}
244+
245+
function smashSecrets(iden, dict) {
246+
$vault = $lib.vault.get($iden)
247+
$vault.secrets = $dict
248+
return($vault.secrets)
249+
}
250+
251+
function setConfig(iden, key, valu) {
252+
$configs = $lib.vault.get($iden).configs
253+
$configs.$key = $valu
254+
return($configs)
255+
}
256+
257+
function smashConfigs(iden, dict) {
258+
$vault = $lib.vault.get($iden)
259+
$vault.configs = $dict
260+
return($vault.configs)
261+
}
262+
'''
263+
},
264+
],
265+
})
266+
267+
await core.nodes('auth.user.addrule visi1 storm.asroot.mod.vmod')
268+
269+
opts = {'vars': {'giden': giden}, 'user': visi1.iden}
270+
q = 'return($lib.import(vmod).setSecret($giden, foo, bar))'
271+
ret = await core.callStorm(q, opts=opts)
272+
self.eq(ret, {'apikey': 'foobar', 'foo': 'bar'})
273+
274+
opts = {'vars': {'giden': giden}, 'user': visi1.iden}
275+
q = 'return($lib.import(vmod).smashSecrets($giden, ({"apikey": "new"})))'
276+
ret = await core.callStorm(q, opts=opts)
277+
self.eq(ret, {'apikey': 'new'})
278+
279+
opts = {'vars': {'giden': giden}, 'user': visi1.iden}
280+
q = 'return($lib.import(vmod).setConfig($giden, foo, bar))'
281+
ret = await core.callStorm(q, opts=opts)
282+
self.eq(ret, {'server': 'foobar', 'foo': 'bar'})
283+
284+
opts = {'vars': {'giden': giden}, 'user': visi1.iden}
285+
q = 'return($lib.import(vmod).smashConfigs($giden, ({"server": "new"})))'
286+
ret = await core.callStorm(q, opts=opts)
287+
self.eq(ret, {'server': 'new'})
228288

229289
async def test_stormlib_vault_cmds(self):
230290
async with self.getTestCore() as core:

0 commit comments

Comments
 (0)