Merge branch 'harness/B-implementation' into harness/A-integration
This commit is contained in:
@@ -43,6 +43,97 @@ class RenderTerminalTest(unittest.TestCase):
|
||||
with self.subTest(raw=raw):
|
||||
self.assertEqual(expected, redact_line(raw))
|
||||
|
||||
def test_credentials_inside_a_command_line_are_redacted(self):
|
||||
"""줄 맨 앞이 아니라 명령 인자 안에 있는 자격증명.
|
||||
|
||||
터미널 증거에서 Bearer 가 가장 흔히 나오는 자리가 `curl -H` 의 인자다.
|
||||
값은 닫는 따옴표 앞까지만 먹는다 — 넘겨 먹으면 명령의 나머지가 통째로 가려진다.
|
||||
아래 값은 전부 합성이고 실제 비밀값이 아니다.
|
||||
"""
|
||||
cases = {
|
||||
'curl -H "Authorization: Bearer TESTONLY-aaa.bbb.ccc" https://example.test/api':
|
||||
'curl -H "Authorization: Bearer [REDACTED]" https://example.test/api',
|
||||
"curl -H 'Authorization: Bearer TESTONLY-xyz' -sS https://example.test":
|
||||
"curl -H 'Authorization: Bearer [REDACTED]' -sS https://example.test",
|
||||
'curl -H "Cookie: SESSION=TESTONLY-sess" https://example.test/api':
|
||||
'curl -H "Cookie: [REDACTED]" https://example.test/api',
|
||||
"Set-Cookie: SESSION=TESTONLY-x; HttpOnly":
|
||||
"Set-Cookie: [REDACTED]",
|
||||
}
|
||||
for raw, expected in cases.items():
|
||||
with self.subTest(raw=raw):
|
||||
self.assertEqual(expected, redact_line(raw))
|
||||
|
||||
def test_connection_string_password_is_redacted_and_user_is_kept(self):
|
||||
"""scheme://user:pw@host 의 암호만 가린다.
|
||||
|
||||
어느 계정으로 붙었는지는 증거의 일부라 사용자 이름을 남긴다.
|
||||
"""
|
||||
cases = {
|
||||
"psql postgresql://app:TESTONLY-pw@db:5432/app":
|
||||
"psql postgresql://app:[REDACTED]@db:5432/app",
|
||||
"DATABASE_URL=mysql://root:TESTONLY-pw@127.0.0.1:3306/app":
|
||||
"DATABASE_URL=mysql://root:[REDACTED]@127.0.0.1:3306/app",
|
||||
"redis://default:TESTONLY-pw@cache:6379/0":
|
||||
"redis://default:[REDACTED]@cache:6379/0",
|
||||
}
|
||||
for raw, expected in cases.items():
|
||||
with self.subTest(raw=raw):
|
||||
self.assertEqual(expected, redact_line(raw))
|
||||
|
||||
def test_masking_does_not_eat_the_closing_quote(self):
|
||||
"""가려졌다는 것과 명령이 그대로라는 것은 다르다.
|
||||
|
||||
값의 끝을 공백까지로 두면 닫는 따옴표까지 먹어 증거에 실린 명령이 실제로 돌린
|
||||
명령과 달라진다. 가려진 것만 보고 지나치지 않도록 따옴표 수를 함께 센다.
|
||||
아래 값은 전부 합성이고 실제 비밀값이 아니다.
|
||||
"""
|
||||
lines = (
|
||||
'curl -H "X-Api-Key: TESTONLY-i-apikey-header" https://example.invalid/d',
|
||||
'curl -H "X-Token: TESTONLY-x" -H "Accept: application/json" https://example.invalid/d',
|
||||
'export TOKEN="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJURVNUT05MWSJ9.TESTONLYsig"',
|
||||
"curl -H 'X-Api-Key: TESTONLY-single' https://example.invalid/d",
|
||||
)
|
||||
for raw in lines:
|
||||
with self.subTest(raw=raw):
|
||||
out = redact_line(raw)
|
||||
self.assertIn("[REDACTED]", out)
|
||||
self.assertNotIn("TESTONLY", out)
|
||||
self.assertEqual(raw.count('"'), out.count('"'), out)
|
||||
self.assertEqual(raw.count("'"), out.count("'"), out)
|
||||
|
||||
def test_basic_auth_shapes_are_redacted(self):
|
||||
"""Bearer 말고도 자격증명이 실리는 자리가 있다."""
|
||||
cases = {
|
||||
'curl -H "Authorization: Basic VEVTVE9OTFk6cHc=" https://example.invalid/d':
|
||||
'curl -H "Authorization: Basic [REDACTED]" https://example.invalid/d',
|
||||
'curl -H "Proxy-Authorization: Basic VEVTVE9OTFk6cHc=" https://example.invalid/d':
|
||||
'curl -H "Proxy-Authorization: Basic [REDACTED]" https://example.invalid/d',
|
||||
"curl -u admin:TESTONLY-basic-pw https://example.invalid/d":
|
||||
"curl -u admin:[REDACTED] https://example.invalid/d",
|
||||
"curl --user admin:TESTONLY-basic-pw https://example.invalid/d":
|
||||
"curl --user admin:[REDACTED] https://example.invalid/d",
|
||||
}
|
||||
for raw, expected in cases.items():
|
||||
with self.subTest(raw=raw):
|
||||
self.assertEqual(expected, redact_line(raw))
|
||||
|
||||
def test_a_bare_jwt_is_redacted(self):
|
||||
"""`eyJ` 로 시작하는 점 두 개짜리 base64url 은 다른 것과 헷갈리지 않는다."""
|
||||
raw = "Set token eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJURVNUT05MWSJ9.TESTONLYsig now"
|
||||
out = redact_line(raw)
|
||||
self.assertEqual("Set token [REDACTED] now", out)
|
||||
|
||||
def test_ordinary_urls_are_not_touched(self):
|
||||
"""자격증명이 없는 주소는 그대로 둔다. 과하게 가리면 증거를 못 읽는다."""
|
||||
for line in (
|
||||
"https://example.test/api?x=1",
|
||||
"git clone https://github.com/org/repo.git",
|
||||
"GET https://example.test/studio/documents/abc-123/edit -> 200",
|
||||
):
|
||||
with self.subTest(line=line):
|
||||
self.assertEqual(line, redact_line(line))
|
||||
|
||||
def test_normal_output_is_not_changed_by_redaction(self):
|
||||
line = "GET /api/me -> 200 in 14ms"
|
||||
self.assertEqual(line, redact_line(line))
|
||||
|
||||
Reference in New Issue
Block a user