Protocol: freeze device proof and browser CSRF contracts
This commit is contained in:
+35
-1
@@ -116,7 +116,9 @@ def main() -> int:
|
||||
assert len(fields) == 5, line
|
||||
assert fields[0] not in ids, fields[0]
|
||||
ids.add(fields[0])
|
||||
assert fields[4] == "valid" or fields[4].startswith("invalid:"), line
|
||||
assert fields[4] == "valid" or fields[4].startswith("invalid:") or (
|
||||
fields[2] == "device_proof_transcript" and re.fullmatch(r"[0-9a-f]{224}", fields[4])
|
||||
), line
|
||||
|
||||
fixture_manifest = json.loads((ROOT / "fixtures/manifest.json").read_text(encoding="utf-8"))
|
||||
assert fixture_manifest["files"] == sorted(
|
||||
@@ -145,6 +147,38 @@ def main() -> int:
|
||||
assert "browserSession" not in tunnel_endpoint and "requestBody:" not in tunnel_endpoint
|
||||
assert "$defs/NativeTunnelCredential" in tunnel_endpoint
|
||||
assert "Cache-Control:" in tunnel_endpoint and "const: no-store" in tunnel_endpoint
|
||||
csrf_schemes = """ browserCsrfCookie:
|
||||
type: apiKey
|
||||
in: cookie
|
||||
name: versevdi_csrf
|
||||
description: Must be identical to X-CSRF-Token and is checked against Server session state.
|
||||
browserCsrfHeader:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-CSRF-Token
|
||||
description: Must be identical to the versevdi_csrf cookie and is checked against Server session state.
|
||||
"""
|
||||
assert csrf_schemes in openapi, "missing exact browser CSRF security schemes"
|
||||
browser_requirement = """ security:
|
||||
- browserSession: []
|
||||
browserCsrfCookie: []
|
||||
browserCsrfHeader: []
|
||||
"""
|
||||
for operation_id in (
|
||||
"issueReauthenticationGrant", "logoutSession", "registerDevice", "proveDevice", "revokeDevice",
|
||||
"requestBrokerSession", "allocateBrokerSession", "reconnectBrokerSession", "cancelBrokerSession",
|
||||
):
|
||||
operation = openapi.split(f" operationId: {operation_id}\n", 1)[1].split(" responses:\n", 1)[0]
|
||||
assert browser_requirement.removeprefix(" ") in operation, f"{operation_id}: missing browser CSRF AND requirement"
|
||||
for operation_id in ("logoutSession", "requestBrokerSession", "allocateBrokerSession", "reconnectBrokerSession", "cancelBrokerSession"):
|
||||
operation = openapi.split(f" operationId: {operation_id}\n", 1)[1].split(" responses:\n", 1)[0]
|
||||
assert " browserCsrfHeader: []\n - nativeBearer: []\n" in operation, f"{operation_id}: native bearer must remain a separate OR requirement"
|
||||
for operation_id in ("loginBrowserSession", "rotateNativeCredential", "issueNativeTunnelCredential"):
|
||||
operation = openapi.split(f" operationId: {operation_id}\n", 1)[1].split(" responses:\n", 1)[0]
|
||||
assert "browserCsrf" not in operation, f"{operation_id}: excluded operation gained browser CSRF"
|
||||
for operation_id in ("getAuthenticatedSession", "listResources", "getBrokerSession", "resumeUserEvents"):
|
||||
operation = openapi.split(f" operationId: {operation_id}\n", 1)[1].split(" responses:\n", 1)[0]
|
||||
assert "browserCsrf" not in operation, f"{operation_id}: safe GET gained browser CSRF"
|
||||
assert defs["ManifestGateway"]["properties"]["public_identity"]["description"] == (
|
||||
"Exact TLS server name; distinct from dial addresses, gateway UUIDs, certificate fingerprints, and provider identities."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user