-
Notifications
You must be signed in to change notification settings - Fork 1
π‘οΈ Sentinel: [CRITICAL] Fix sensitive data exposure in logs #172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| ## Sentinel's Journal | ||
|
|
||
| This journal documents CRITICAL security learnings found during codebase audits. | ||
| Only add entries for: | ||
| - Vulnerability patterns specific to this codebase | ||
| - Security fixes with unexpected side effects | ||
| - Rejected security changes with important constraints | ||
| - Surprising security gaps in architecture | ||
| - Reusable security patterns for this project | ||
|
|
||
| --- |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -151,6 +151,19 @@ | |||||||||||||||||||||||||
| s = str(text) | ||||||||||||||||||||||||||
| if TOKEN and TOKEN in s: | ||||||||||||||||||||||||||
| s = s.replace(TOKEN, "[REDACTED]") | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Redact Basic Auth in URLs (e.g. https://user:pass@host) | ||||||||||||||||||||||||||
| s = re.sub(r"://[^/@]+@", "://[REDACTED]@", s) | ||||||||||||||||||||||||||
Check warningCode scanning / Pylintpython3 (reported by Codacy) Variable name "s" doesn't conform to snake_case naming style Warning
Variable name "s" doesn't conform to snake_case naming style
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Redact sensitive query parameters | ||||||||||||||||||||||||||
| sensitive_keys = r"token|key|secret|password|auth|access_token|api_key" | ||||||||||||||||||||||||||
| s = re.sub( | ||||||||||||||||||||||||||
Check warningCode scanning / Pylint (reported by Codacy) Variable name "s" doesn't conform to snake_case naming style Warning
Variable name "s" doesn't conform to snake_case naming style
Check warningCode scanning / Pylintpython3 (reported by Codacy) Variable name "s" doesn't conform to snake_case naming style Warning
Variable name "s" doesn't conform to snake_case naming style
|
||||||||||||||||||||||||||
| r"([?&])(" + sensitive_keys + r")=[^&\s]+", | ||||||||||||||||||||||||||
| r"\1\2=[REDACTED]", | ||||||||||||||||||||||||||
| s, | ||||||||||||||||||||||||||
| flags=re.IGNORECASE, | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
Comment on lines
+160
to
+165
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The regex for redacting sensitive query parameters should also include the fragment separator
Suggested change
Comment on lines
+159
to
+165
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # repr() safely escapes control characters (e.g., \n -> \\n, \x1b -> \\x1b) | ||||||||||||||||||||||||||
| # This prevents log injection and terminal hijacking. | ||||||||||||||||||||||||||
| safe = repr(s) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -67,5 +67,25 @@ | |||||||||||||||||||||||||||||||||||||
| self.assertTrue(found_sanitized, "Should find sanitized name in logs") | ||||||||||||||||||||||||||||||||||||||
| self.assertFalse(found_raw, "Should not find raw name in logs") | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def test_sanitize_for_log_redacts_credentials(self): | ||||||||||||||||||||||||||||||||||||||
| """Test that sanitize_for_log redacts Basic Auth and sensitive query params.""" | ||||||||||||||||||||||||||||||||||||||
| # Test Basic Auth | ||||||||||||||||||||||||||||||||||||||
| url_with_auth = "https://user:password123@example.com/folder.json" | ||||||||||||||||||||||||||||||||||||||
| sanitized = main.sanitize_for_log(url_with_auth) | ||||||||||||||||||||||||||||||||||||||
| self.assertNotIn("password123", sanitized) | ||||||||||||||||||||||||||||||||||||||
| self.assertIn("[REDACTED]", sanitized) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # Test Query Params | ||||||||||||||||||||||||||||||||||||||
| url_with_param = "https://example.com/folder.json?secret=mysecretkey" | ||||||||||||||||||||||||||||||||||||||
| sanitized_param = main.sanitize_for_log(url_with_param) | ||||||||||||||||||||||||||||||||||||||
| self.assertNotIn("mysecretkey", sanitized_param) | ||||||||||||||||||||||||||||||||||||||
| self.assertIn("[REDACTED]", sanitized_param) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # Test Case Insensitivity | ||||||||||||||||||||||||||||||||||||||
| url_with_token = "https://example.com/folder.json?TOKEN=mytoken" | ||||||||||||||||||||||||||||||||||||||
Check noticeCode scanning / Bandit Possible hardcoded password: 'https://example.com/folder.json?TOKEN=mytoken' Note test
Possible hardcoded password: 'https://example.com/folder.json?TOKEN=mytoken'
Check noticeCode scanning / Bandit (reported by Codacy) Possible hardcoded password: 'https://example.com/folder.json?TOKEN=mytoken' Note test
Possible hardcoded password: 'https://example.com/folder.json?TOKEN=mytoken'
|
||||||||||||||||||||||||||||||||||||||
| sanitized_token = main.sanitize_for_log(url_with_token) | ||||||||||||||||||||||||||||||||||||||
| self.assertNotIn("mytoken", sanitized_token) | ||||||||||||||||||||||||||||||||||||||
| self.assertIn("[REDACTED]", sanitized_token) | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current tests are a great start! To make them more robust, I'd suggest a few things:
Here's a suggestion to add a couple more test cases:
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if __name__ == '__main__': | ||||||||||||||||||||||||||||||||||||||
| unittest.main() | ||||||||||||||||||||||||||||||||||||||
Check warning
Code scanning / Pylint (reported by Codacy)
Variable name "s" doesn't conform to snake_case naming style Warning