mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 11:56:38 +00:00
343 lines
12 KiB
JSON
343 lines
12 KiB
JSON
{
|
||
"protocolVersion": "v1",
|
||
"fixtureSet": "redaction",
|
||
"fixture": "secret-vectors",
|
||
"description": "Realistic secret material presented to the engine. Every literal in secretLiterals must be absent from the redacted output, from any log, and from any exception. The example values are synthetic: the PEM body is not a usable key and the AWS values are the documented example credentials.",
|
||
"expectations": [
|
||
"expectedCanonicalJson is the exact output bytes for this document at rustfs.connect.redaction.v1.",
|
||
"valueRule names the rule that fires for ruleSubject; a null valueRule means the removal comes from the allow-list, a key rule, or the ASCII key rule instead."
|
||
],
|
||
"vectors": [
|
||
{
|
||
"name": "an S3 access key id smuggled into the version field",
|
||
"source": "inventory",
|
||
"valueRule": "AWS_ACCESS_KEY_ID",
|
||
"ruleSubject": "AKIAIOSFODNN7EXAMPLE",
|
||
"document": {
|
||
"rustfsVersion": "AKIAIOSFODNN7EXAMPLE",
|
||
"nodeCount": 4
|
||
},
|
||
"secretLiterals": [
|
||
"AKIAIOSFODNN7EXAMPLE"
|
||
],
|
||
"expectedCanonicalJson": "{\"nodeCount\":4,\"rustfsVersion\":\"[REDACTED]\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "an S3 secret access key standing alone in an offline OS summary",
|
||
"source": "offline-diagnostic",
|
||
"valueRule": "AWS_SECRET_ACCESS_KEY",
|
||
"ruleSubject": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
||
"document": {
|
||
"osSummary": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
||
"rustfsVersion": "1.19.4"
|
||
},
|
||
"secretLiterals": [
|
||
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||
],
|
||
"expectedCanonicalJson": "{\"osSummary\":\"[REDACTED]\",\"rustfsVersion\":\"1.19.4\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a captured bearer authorization header in a kernel summary",
|
||
"source": "offline-diagnostic",
|
||
"valueRule": "BEARER_TOKEN",
|
||
"ruleSubject": "Linux 6.8.0; upstream call used Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk",
|
||
"document": {
|
||
"kernelSummary": "Linux 6.8.0; upstream call used Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk"
|
||
},
|
||
"secretLiterals": [
|
||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk"
|
||
],
|
||
"expectedCanonicalJson": "{\"kernelSummary\":\"[REDACTED]\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a JSON web token inside a heartbeat capability list",
|
||
"source": "heartbeat",
|
||
"valueRule": "JWT",
|
||
"ruleSubject": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk",
|
||
"document": {
|
||
"capabilities": [
|
||
"inventory",
|
||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk",
|
||
"jobs"
|
||
],
|
||
"sequence": 12
|
||
},
|
||
"secretLiterals": [
|
||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk"
|
||
],
|
||
"expectedCanonicalJson": "{\"capabilities\":[\"inventory\",\"[REDACTED]\",\"jobs\"],\"sequence\":12}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a connection string carrying an embedded password",
|
||
"source": "offline-diagnostic",
|
||
"valueRule": "URL_CREDENTIALS",
|
||
"ruleSubject": "postgresql://rustfs:s3cr3t-p4ss@db.internal:5432/connect",
|
||
"document": {
|
||
"filesystemSummary": "postgresql://rustfs:s3cr3t-p4ss@db.internal:5432/connect"
|
||
},
|
||
"secretLiterals": [
|
||
"s3cr3t-p4ss",
|
||
"db.internal"
|
||
],
|
||
"expectedCanonicalJson": "{\"filesystemSummary\":\"[REDACTED]\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a PEM private key nested inside a coarse node summary",
|
||
"source": "heartbeat",
|
||
"valueRule": "PEM_PRIVATE_KEY",
|
||
"ruleSubject": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAxEXAMPLEKEYBODYnotarealkey0000000000000000000000\nEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE=\n-----END RSA PRIVATE KEY-----",
|
||
"document": {
|
||
"coarseNodeSummary": {
|
||
"healthy": 4,
|
||
"note": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAxEXAMPLEKEYBODYnotarealkey0000000000000000000000\nEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE=\n-----END RSA PRIVATE KEY-----"
|
||
}
|
||
},
|
||
"secretLiterals": [
|
||
"-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAxEXAMPLEKEYBODYnotarealkey0000000000000000000000\nEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE=\n-----END RSA PRIVATE KEY-----",
|
||
"EXAMPLEKEYBODY"
|
||
],
|
||
"expectedCanonicalJson": "{\"coarseNodeSummary\":{\"healthy\":4,\"note\":\"[REDACTED]\"}}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a DSN password assignment in a CPU summary",
|
||
"source": "offline-diagnostic",
|
||
"valueRule": "PASSWORD_ASSIGNMENT",
|
||
"ruleSubject": "Server=db;User Id=rustfs;Password=hunter2xyz;",
|
||
"document": {
|
||
"cpuSummary": "Server=db;User Id=rustfs;Password=hunter2xyz;"
|
||
},
|
||
"secretLiterals": [
|
||
"hunter2xyz"
|
||
],
|
||
"expectedCanonicalJson": "{\"cpuSummary\":\"[REDACTED]\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a session identifier assignment appended to an OS version",
|
||
"source": "inventory",
|
||
"valueRule": "SESSION_ID_ASSIGNMENT",
|
||
"ruleSubject": "Ubuntu 22.04.5 LTS; PHPSESSID=9f8a7b6c5d4e3f2a1b0c",
|
||
"document": {
|
||
"osVersion": "Ubuntu 22.04.5 LTS; PHPSESSID=9f8a7b6c5d4e3f2a1b0c"
|
||
},
|
||
"secretLiterals": [
|
||
"9f8a7b6c5d4e3f2a1b0c"
|
||
],
|
||
"expectedCanonicalJson": "{\"osVersion\":\"[REDACTED]\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a registration token assignment in an agent version string",
|
||
"source": "heartbeat",
|
||
"valueRule": "CREDENTIAL_ASSIGNMENT",
|
||
"ruleSubject": "rustfs-agent/1.19.4 registration_token=rft-9f8a7b6c5d4e3f2a1b0c",
|
||
"document": {
|
||
"agentVersion": "rustfs-agent/1.19.4 registration_token=rft-9f8a7b6c5d4e3f2a1b0c"
|
||
},
|
||
"secretLiterals": [
|
||
"rft-9f8a7b6c5d4e3f2a1b0c"
|
||
],
|
||
"expectedCanonicalJson": "{\"agentVersion\":\"[REDACTED]\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "KMS key material recognised by its key name alone",
|
||
"source": "inventory",
|
||
"valueRule": null,
|
||
"ruleSubject": null,
|
||
"document": {
|
||
"coarseFlags": {
|
||
"degraded": false,
|
||
"kms_master_key": "AQIDAHhEXAMPLEkmsDataKeyCiphertext"
|
||
}
|
||
},
|
||
"secretLiterals": [
|
||
"AQIDAHhEXAMPLEkmsDataKeyCiphertext"
|
||
],
|
||
"expectedCanonicalJson": "{\"coarseFlags\":{\"degraded\":false,\"kms_master_key\":\"[REDACTED]\"}}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a secret access key under a separated and mixed-case key name",
|
||
"source": "inventory",
|
||
"valueRule": null,
|
||
"ruleSubject": null,
|
||
"document": {
|
||
"coarseFlags": {
|
||
"Secret-Access-Key": "zz9EXAMPLEkey",
|
||
"driveCount": 24
|
||
}
|
||
},
|
||
"secretLiterals": [
|
||
"zz9EXAMPLEkey"
|
||
],
|
||
"expectedCanonicalJson": "{\"coarseFlags\":{\"Secret-Access-Key\":\"[REDACTED]\",\"driveCount\":24}}",
|
||
"expectedCounts": {
|
||
"droppedField": 0,
|
||
"redactedValue": 1,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "a brand new secret-bearing field that matches no value rule at all",
|
||
"source": "inventory",
|
||
"valueRule": null,
|
||
"ruleSubject": null,
|
||
"document": {
|
||
"rustfsVersion": "1.19.4",
|
||
"vendorSupportCredential": "ordinary-looking-handle-42",
|
||
"objectStoreRootPassphrase": "correct horse battery staple"
|
||
},
|
||
"secretLiterals": [
|
||
"ordinary-looking-handle-42",
|
||
"correct horse battery staple",
|
||
"vendorSupportCredential",
|
||
"objectStoreRootPassphrase"
|
||
],
|
||
"expectedCanonicalJson": "{\"rustfsVersion\":\"1.19.4\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 2,
|
||
"redactedValue": 0,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 2
|
||
},
|
||
{
|
||
"name": "deferred L2 and L3 collection is refused by the allow-list",
|
||
"source": "offline-diagnostic",
|
||
"valueRule": null,
|
||
"ruleSubject": null,
|
||
"document": {
|
||
"rustfsVersion": "1.19.4",
|
||
"configuration": {
|
||
"endpoint": "https://s3.example.internal"
|
||
},
|
||
"logs": [
|
||
"level=error msg=\"auth failed for user rustfs\""
|
||
],
|
||
"traces": "span 8f2c1a",
|
||
"profiles": "cpu.pprof"
|
||
},
|
||
"secretLiterals": [
|
||
"s3.example.internal",
|
||
"auth failed for user rustfs",
|
||
"span 8f2c1a",
|
||
"cpu.pprof"
|
||
],
|
||
"expectedCanonicalJson": "{\"rustfsVersion\":\"1.19.4\"}",
|
||
"expectedCounts": {
|
||
"droppedField": 4,
|
||
"redactedValue": 0,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 4
|
||
},
|
||
{
|
||
"name": "a confusable non-ASCII key inside an allow-listed object is dropped",
|
||
"source": "inventory",
|
||
"valueRule": null,
|
||
"ruleSubject": null,
|
||
"document": {
|
||
"coarseFlags": {
|
||
"secretAccessKey": "AKIAIOSFODNN7EXAMPLE",
|
||
"degraded": true
|
||
}
|
||
},
|
||
"secretLiterals": [
|
||
"AKIAIOSFODNN7EXAMPLE",
|
||
"secretAccessKey"
|
||
],
|
||
"expectedCanonicalJson": "{\"coarseFlags\":{\"degraded\":true}}",
|
||
"expectedCounts": {
|
||
"droppedField": 1,
|
||
"redactedValue": 0,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 1
|
||
},
|
||
{
|
||
"name": "an allow-listed object that loses every entry is removed entirely",
|
||
"source": "heartbeat",
|
||
"valueRule": null,
|
||
"ruleSubject": null,
|
||
"document": {
|
||
"coarseNodeSummary": {
|
||
"perNode": {
|
||
"hostname": "node-01.rustfs.internal"
|
||
}
|
||
},
|
||
"sequence": 7
|
||
},
|
||
"secretLiterals": [
|
||
"node-01.rustfs.internal",
|
||
"perNode",
|
||
"coarseNodeSummary"
|
||
],
|
||
"expectedCanonicalJson": "{\"sequence\":7}",
|
||
"expectedCounts": {
|
||
"droppedField": 3,
|
||
"redactedValue": 0,
|
||
"redactedOversizeValue": 0
|
||
},
|
||
"expectedRedactedCount": 3
|
||
}
|
||
]
|
||
}
|