mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
Security: IME log pattern PUT must be GlobalAdminOnly
PUT rules/ime-log-patterns/{patternId} sat on the TenantAdminOrGA tier
while the handler only checks ?global=true and writes the GLOBAL pattern
with no GA re-gate - any customer tenant admin could mutate platform-wide
patterns via direct API call. The UI gate (isGlobalAdmin && globalAdminMode)
was cosmetic only.
Moved the entry to GlobalAdminOnly next to the reseed route and added a
regression test pinning both IME pattern write routes to that tier.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+17
@@ -174,6 +174,23 @@ public class EndpointPolicyCatalogCompletenessTests
|
||||
Assert.Equal(EndpointPolicy.TenantAdminOrGA, postRules.Policy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IME log pattern edits write GLOBAL patterns (all tenants) and the handler has no GA
|
||||
/// re-gate, so the PUT must stay GlobalAdminOnly — a downgrade to TenantAdminOrGA would let
|
||||
/// any customer tenant admin mutate platform-wide patterns via ?global=true.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void ImeLogPatternWrites_AreGlobalAdminOnly()
|
||||
{
|
||||
var putPattern = EndpointAccessPolicyCatalog.FindPolicy("PUT", "/api/rules/ime-log-patterns/IME-001");
|
||||
var reseed = EndpointAccessPolicyCatalog.FindPolicy("POST", "/api/rules/ime-log-patterns/reseed");
|
||||
|
||||
Assert.NotNull(putPattern);
|
||||
Assert.NotNull(reseed);
|
||||
Assert.Equal(EndpointPolicy.GlobalAdminOnly, putPattern.Policy);
|
||||
Assert.Equal(EndpointPolicy.GlobalAdminOnly, reseed.Policy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregistered routes must return null (fail-closed).
|
||||
/// </summary>
|
||||
|
||||
@@ -311,7 +311,6 @@ public static class EndpointAccessPolicyCatalog
|
||||
new("POST", "rules/analyze/{ruleId}/create-from-template", EndpointPolicy.TenantAdminOrGA),
|
||||
new("PUT", "rules/analyze/{ruleId}", EndpointPolicy.TenantAdminOrGA),
|
||||
new("DELETE", "rules/analyze/{ruleId}", EndpointPolicy.TenantAdminOrGA),
|
||||
new("PUT", "rules/ime-log-patterns/{patternId}", EndpointPolicy.TenantAdminOrGA),
|
||||
new("POST", "sessions/{sessionId}/mark-failed", EndpointPolicy.TenantAdminOrGA),
|
||||
new("POST", "sessions/{sessionId}/mark-succeeded", EndpointPolicy.TenantAdminOrGA),
|
||||
// Operator tier so troubleshooting staff can queue request_diagnostics ("Collect Logs" in
|
||||
@@ -541,6 +540,9 @@ public static class EndpointAccessPolicyCatalog
|
||||
new("GET", "vulnerability/ignored-software", EndpointPolicy.GlobalReadOrAdmin),
|
||||
new("POST", "vulnerability/ignored-software", EndpointPolicy.GlobalAdminOnly),
|
||||
new("DELETE", "vulnerability/ignored-software", EndpointPolicy.GlobalAdminOnly),
|
||||
// Both routes mutate GLOBAL patterns (all tenants); there is no tenant-scoped variant yet,
|
||||
// so PUT must not sit on the TenantAdminOrGA tier — the handler has no GA re-gate.
|
||||
new("PUT", "rules/ime-log-patterns/{patternId}", EndpointPolicy.GlobalAdminOnly),
|
||||
new("POST", "rules/ime-log-patterns/reseed", EndpointPolicy.GlobalAdminOnly),
|
||||
new("GET", "global/mcp-users", EndpointPolicy.GlobalReadOrAdmin),
|
||||
new("POST", "global/mcp-users", EndpointPolicy.GlobalAdminOnly),
|
||||
|
||||
Reference in New Issue
Block a user