wave16: nova/keystone/crystal/dovecot/wireshark CWE-407 patches + unit tests
nova-0001: scheduler/manager.py selected_hosts list → set (273x, CRITICAL) nova-0002: scheduler/host_manager.py lowered_hosts_to_force list → set (43x, HIGH) keystone-0001: api/users.py token_roles list → set (32x, HIGH) crystal-0001: syntax/parser.cr type_vars Array#includes? → Set (25x, CRITICAL) crystal-0002: semantic/restrictions.cr discarded Array#includes? → Set (5x, CRITICAL) dovecot-0001: mail-storage-hooks.c array_lsearch → sort+bsearch (4x, HIGH) wireshark-0001: proto_data.c GSList → wmem_map_t (8x, HIGH) 7 unit tests: 9/9 PASS
This commit is contained in:
parent
291620b115
commit
59ae52c7b4
12 changed files with 724 additions and 177 deletions
14
defects/keystone/patch/keystone-0001-token-roles-set.patch
Normal file
14
defects/keystone/patch/keystone-0001-token-roles-set.patch
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
--- a/keystone/api/users.py
|
||||
+++ b/keystone/api/users.py
|
||||
@@ -663,7 +663,7 @@ class UsersResource(ks_flask.ResourceBase):
|
||||
# credential users from escallating their privileges to include
|
||||
# additional roles that the trustor or application credential
|
||||
# creator has assigned on the project.
|
||||
- token_roles = [r['id'] for r in token.roles]
|
||||
+ token_role_ids = {r['id'] for r in token.roles}
|
||||
for role in roles:
|
||||
- if role['id'] not in token_roles:
|
||||
+ if role['id'] not in token_role_ids:
|
||||
detail = _(
|
||||
'Cannot create an application credential with '
|
||||
'unassigned role'
|
||||
62
defects/keystone/unit/test_keystone_cwe407.py
Normal file
62
defects/keystone/unit/test_keystone_cwe407.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"""
|
||||
CWE-407 unit test for keystone defect.
|
||||
|
||||
keystone-0001: token_roles list → set in users.py
|
||||
token_roles = [r['id'] for r in token.roles] # list O(T)
|
||||
for role in roles: # outer O(R)
|
||||
if role['id'] not in token_roles: # inner O(T) scan → O(R×T)
|
||||
"""
|
||||
import time
|
||||
|
||||
|
||||
def validate_roles_list(roles, token_roles_raw):
|
||||
"""O(R × T) — list scan (defect)."""
|
||||
token_roles = [r['id'] for r in token_roles_raw]
|
||||
invalid = []
|
||||
for role in roles:
|
||||
if role['id'] not in token_roles:
|
||||
invalid.append(role['id'])
|
||||
return invalid
|
||||
|
||||
|
||||
def validate_roles_set(roles, token_roles_raw):
|
||||
"""O(R + T) — set lookup (fixed)."""
|
||||
token_role_ids = {r['id'] for r in token_roles_raw}
|
||||
invalid = []
|
||||
for role in roles:
|
||||
if role['id'] not in token_role_ids:
|
||||
invalid.append(role['id'])
|
||||
return invalid
|
||||
|
||||
|
||||
def test_keystone_0001_token_roles_set():
|
||||
T = 500 # token roles
|
||||
R = 500 # requested roles
|
||||
token_roles = [{'id': f'role-{i}'} for i in range(T)]
|
||||
# requested roles: half valid (in token), half not
|
||||
roles = [{'id': f'role-{i}'} for i in range(R // 2)] + \
|
||||
[{'id': f'extra-{i}'} for i in range(R // 2)]
|
||||
|
||||
r_list = validate_roles_list(roles, token_roles)
|
||||
r_set = validate_roles_set(roles, token_roles)
|
||||
assert sorted(r_list) == sorted(r_set), "list and set must detect same invalid roles"
|
||||
|
||||
t0 = time.perf_counter()
|
||||
for _ in range(100):
|
||||
validate_roles_list(roles, token_roles)
|
||||
t_list = time.perf_counter() - t0
|
||||
|
||||
t0 = time.perf_counter()
|
||||
for _ in range(100):
|
||||
validate_roles_set(roles, token_roles)
|
||||
t_set = time.perf_counter() - t0
|
||||
|
||||
ratio = t_list / t_set
|
||||
print(f"keystone-0001: list={t_list:.3f}s set={t_set:.3f}s ratio={ratio:.1f}×")
|
||||
assert ratio > 20, f"Expected >20× speedup, got {ratio:.1f}×"
|
||||
print("PASS keystone-0001")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_keystone_0001_token_roles_set()
|
||||
print("ALL PASS")
|
||||
Loading…
Add table
Add a link
Reference in a new issue