///|
fn require(condition : Bool, message : String) -> Unit {
guard condition else { abort(message) }
}
///|
fn main {
let encoded_secret = "eyJ0b2tlbiI6InN5bnRoZXRpYy1zZWNyZXQifQ=="
let bodies : Array[@moonvcr.Body] = [
@moonvcr.Empty,
@moonvcr.Base64(encoded_secret),
@moonvcr.Text("not-json"),
]
let mut rejected = 0
for optional in [false, true] {
for response_side in [false, true] {
let rules = @moonvcr.RedactionConfig::default()
if optional {
rules.optional_json_paths.push("/token")
} else {
rules.json_paths.push("/token")
}
let defaults = @moonvcr.RedactionConfig::default()
let policy : @moonvcr.RedactionPolicy = if response_side {
{ request: defaults, response: rules, }
} else {
{ request: rules, response: defaults, }
}
for body in bodies {
let session = @moonvcr.Session::new_with_redaction_policy(
@moonvcr.example_cassette(),
@moonvcr.Record,
@moonvcr.MatchConfig::default(),
policy,
)
let before = session.cassette().encode()
let request : @moonvcr.Request = {
method: "POST",
url: "https://test.invalid",
headers: [],
body: if response_side {
@moonvcr.Empty
} else {
body
},
}
let response : @moonvcr.Response = {
status: 200,
headers: [],
body: if response_side {
body
} else {
@moonvcr.Empty
},
}
require(
session.record_response(request, response) is Err(_),
"unsafe JSON body was recorded",
)
require(
session.cassette().encode() == before,
"failed redaction changed cassette",
)
require(
!session.cassette().encode().contains(encoded_secret),
"Base64 secret persisted",
)
rejected += 1
}
}
}
let plain = ["t", "o", "k", "e", "n"]
let lower = ["%74", "%6f", "%6b", "%65", "%6e"]
let upper = ["%54", "%4F", "%4B", "%45", "%4E"]
for combination in 0..<1024 {
let mut choices = combination
let mut name = ""
for index in 0..<5 {
name += match choices % 4 {
0 => plain[index]
1 => plain[index].to_upper()
2 => lower[index]
_ => upper[index]
}
choices /= 4
}
let session = @moonvcr.Session::with_defaults(
@moonvcr.Cassette::empty(),
@moonvcr.Record,
)
let request : @moonvcr.Request = {
method: "GET",
url: "https://test.invalid/?" + name + "=query-secret#fragment-secret",
headers: [],
body: @moonvcr.Empty,
}
let response : @moonvcr.Response = {
status: 200,
headers: [],
body: @moonvcr.Empty,
}
require(
session.record_response(request, response) is Ok(_),
"safe query recording failed",
)
let text = session.cassette().encode()
require(
!text.contains("query-secret") && !text.contains("fragment-secret"),
"encoded query or fragment leaked",
)
}
let cassette = @moonvcr.example_cassette()
let request = cassette.interactions[0].request
let offline = @moonvcr.Session::with_defaults(
cassette,
@moonvcr.StrictOffline,
)
let response : @moonvcr.Response = {
status: 200,
headers: [],
body: @moonvcr.Empty,
}
require(
offline.record_response(request, response) is Err(_),
"offline session recorded a response",
)
require(offline.replay(request) is Ok(_), "offline replay failed")
require(offline.assert_complete() is Ok(_), "offline cassette incomplete")
let recorder = @moonvcr.Session::with_defaults(
@moonvcr.Cassette::empty(),
@moonvcr.Record,
)
let transport = (_ : @moonvcr.Request) => {
Err(@moonvcr.TransportError::Failed("transport-secret"))
}
match recorder.send(request, transport) {
Err(error) =>
require(
!@debug.to_string(error).contains("transport-secret"),
"transport Debug leaked",
)
Ok(_) => abort("failing transport unexpectedly succeeded")
}
println(
"security acceptance passed rejected=" +
rejected.to_string() +
" encoded_names=1024 retained_secrets=0",
)
audit_followup_acceptance()
}
///|
/// Public-API checks for the second independent audit. These run against the
/// candidate archive and, after publication, a downloaded registry package.
fn audit_followup_acceptance() -> Unit {
let mut pointer_cases = 0
for (suffix, escaped) in [(" ", " "), ("\t", "\\t"), ("\n", "\\n")] {
for optional in [false, true] {
for response_side in [false, true] {
let rules = @moonvcr.RedactionConfig::default()
if optional {
rules.optional_json_paths.push("/token" + suffix)
} else {
rules.json_paths.push("/token" + suffix)
}
let policy : @moonvcr.RedactionPolicy = if response_side {
{ request: @moonvcr.RedactionConfig::default(), response: rules, }
} else {
{ request: rules, response: @moonvcr.RedactionConfig::default(), }
}
let body = @moonvcr.Text(
"{\"token" +
escaped +
"\":\"pointer-audit-secret\",\"token\":\"public-control\"}",
)
let request : @moonvcr.Request = {
method: "POST",
url: "https://test.invalid",
headers: [],
body: if response_side {
@moonvcr.Empty
} else {
body
},
}
let response : @moonvcr.Response = {
status: 200,
headers: [],
body: if response_side {
body
} else {
@moonvcr.Empty
},
}
let session = @moonvcr.Session::new_with_redaction_policy(
@moonvcr.Cassette::empty(),
@moonvcr.Record,
@moonvcr.MatchConfig::default(),
policy,
)
require(
session.record_response(request, response) is Ok(_),
"exact pointer recording failed",
)
let saved = session.cassette().encode()
require(
!saved.contains("pointer-audit-secret"),
"whitespace pointer secret retained",
)
require(
saved.contains("public-control"),
"pointer modified the adjacent key",
)
pointer_cases += 1
}
}
}
let original : @moonvcr.Request = {
method: "GET",
url: "https://test.invalid/?role=user&role=admin",
headers: [],
body: @moonvcr.Empty,
}
let changed : @moonvcr.Request = {
method: "GET",
url: "https://test.invalid/?role=admin&role=user",
headers: [],
body: @moonvcr.Empty,
}
let config = @moonvcr.MatchConfig::default()
require(
@moonvcr.request_match_key(original, config) !=
@moonvcr.request_match_key(changed, config),
"duplicate query order lost",
)
let header_first : @moonvcr.Request = {
method: "GET",
url: "https://test.invalid",
body: @moonvcr.Empty,
headers: [
{ name: "X-Mode", value: "user", },
{ name: "x-mode", value: "admin", },
],
}
let header_reversed : @moonvcr.Request = {
method: "GET",
url: "https://test.invalid",
body: @moonvcr.Empty,
headers: [
{ name: "x-mode", value: "admin", },
{ name: "X-Mode", value: "user", },
],
}
require(
@moonvcr.request_match_key(header_first, config) !=
@moonvcr.request_match_key(header_reversed, config),
"duplicate header order lost",
)
let raw : @moonvcr.Request = {
method: "GET",
url: "https://test.invalid/?token=import-audit-secret",
headers: [],
body: @moonvcr.Empty,
}
let cassette : @moonvcr.Cassette = {
format_version: 1,
interactions: [
{
request: raw,
response: { status: 200, headers: [], body: @moonvcr.Empty, },
},
],
}
let session = @moonvcr.Session::with_defaults(
cassette,
@moonvcr.StrictOffline,
)
require(
session.replay(raw) is Err(_),
"raw imported cassette unexpectedly matched",
)
let report = session.diagnose(raw)
require(
report.differences.length() > 0,
"diagnosis disagrees with replay miss",
)
require(
!@debug.to_string(report).contains("import-audit-secret"),
"diagnosis leaked raw cassette",
)
let whitespace_contract = @moonvcr.ResponseContract::permissive()
whitespace_contract.json_fields.push({
path: "/id ",
expected_kind: @moonvcr.JsonNumber,
})
let incompatible : @moonvcr.Response = {
status: 200,
headers: [],
body: @moonvcr.Text("{\"id \":\"wrong\",\"id\":123}"),
}
require(
!incompatible.validate_contract(whitespace_contract).is_valid(),
"contract checked adjacent key",
)
let array_request : @moonvcr.Request = {
method: "POST",
url: "https://test.invalid",
headers: [],
body: @moonvcr.Text(
"{\"items\":[{\"token\":\"a\"},{\"token\":\"array-audit-secret\"}]}",
),
}
for optional in [false, true] {
let rules = @moonvcr.RedactionConfig::default()
if optional {
rules.optional_json_paths.push("/items/01/token")
} else {
rules.json_paths.push("/items/01/token")
}
require(
@moonvcr.redact_request(array_request, rules) is Err(_),
"invalid array index accepted",
)
}
let array_contract = @moonvcr.ResponseContract::permissive()
array_contract.optional_json_fields.push({
path: "/items/01/token",
expected_kind: @moonvcr.JsonString,
})
let array_response : @moonvcr.Response = {
status: 200,
headers: [],
body: array_request.body,
}
require(
!array_response.validate_contract(array_contract).is_valid(),
"optional contract ignored invalid index",
)
let nested : @moonvcr.Request = {
method: "POST",
url: "https://test.invalid",
headers: [],
body: @moonvcr.Text(
"{\"credentials\":{\"token\":\"overlap-audit-secret\"}}",
),
}
let mut saved_body : @moonvcr.Body? = None
for
paths in [
["/credentials", "/credentials/token"],
["/credentials/token", "/credentials"],
] {
let rules = @moonvcr.RedactionConfig::default()
for path in paths {
rules.json_paths.push(path)
}
let safe = match @moonvcr.redact_request(nested, rules) {
Ok(value) => value
Err(_) => abort("overlapping rules depended on order")
}
match saved_body {
None => saved_body = Some(safe.body)
Some(expected) =>
require(expected == safe.body, "overlapping results depended on order")
}
require(
!@debug.to_string(safe).contains("overlap-audit-secret"),
"overlap retained secret",
)
}
println(
"audit acceptance passed pointer_cases=" +
pointer_cases.to_string() +
" retained_secrets=0 duplicate_order=preserved diagnosis=consistent invalid_indices=rejected overlapping_rules=stable",
)
}