Fix the diff scanner that misses AWS keys
Your task
An assistant generated a Go client that uploads backups to S3, with an AWS access key and secret pasted into the source. A reviewer skimming the diff missed them, so the team now runs a scanner on every diff before merge.
An assistant wrote scan_diff_for_secrets(diff_lines). It is in the editor. It has a bug. Find it and fix it.
Input and output:
diff_lines: the lines of a unified diff, in order. Added lines start with+, removed lines with-, unchanged lines with a space. The file header starts with+++.- Return a list of findings, each
"<line number>:<rule>". Line numbers start at 1 and count every line of the input.
Rules the tests check:
- Scan only added lines: lines that start with
+but not with+++. Skip every other line. A removed key is already in git history, and the gate that matters is the one that stops new keys. - Check each scanned line against four rules, in this order. Report each rule at most once per line.
aws_access_key_id:AKIAfollowed directly by 16 characters, each an uppercase letter A to Z or a digit. It counts anywhere in the line, even inside a longer word.aws_secret_access_key: a quoted string of exactly 40 characters, each an ASCII letter, a digit,/,+or=. Pair the line's double quotes left to right: the 1st with the 2nd, the 3rd with the 4th, and so on. Every"counts, even one after a backslash. A last quote with no partner is ignored.hardcoded_password: the firstpassword=in the line (case matters) is followed by at least one character, and that character is not the space character. A tab, for example, still counts as a finding.discarded_error: the line contains, _ :=or, _ =, the Go pattern that throws an error away.
- List findings by line number, and within a line in the rule order above.
Examples:
- For
["+++ b/uploader.go", "+ creds := credentials.NewStaticCredentialsProvider(", "+ \"AKIAIOSFODNN7EXAMPLE\",", "+ \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\",", "+ cfg, _ := config.LoadDefaultConfig(context.TODO(),"], it returns["3:aws_access_key_id", "4:aws_secret_access_key", "5:discarded_error"]. - For
["- \"AKIAIOSFODNN7EXAMPLE\",", " some context", "+ // nothing to see here"], it returns[]: the key is on a removed line. - For
["+ db, _ := sql.Open(dsn + \"password=hunter2\")"], it returns["1:hardcoded_password", "1:discarded_error"].
Then, in a sentence or two: how would you catch this kind of bug in review?
Examples
scan_diff_for_secrets(diff_lines: list[str]) -> list[str]Example 1
Input
scan_diff_for_secrets(["+++ b/uploader.go", "+ creds := credentials.NewStaticCredentialsProvider(", "+ \"AKIAIOSFODNN7EXAMPLE\",", "+ \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\",", "+ cfg, _ := config.LoadDefaultConfig(context.TODO(),"])Output
["3:aws_access_key_id", "4:aws_secret_access_key", "5:discarded_error"]Example 2
Input
scan_diff_for_secrets(["- \"AKIAIOSFODNN7EXAMPLE\",", " some context", "+ // nothing to see here"])Output
[]Example 3
Input
scan_diff_for_secrets(["+ db, _ := sql.Open(dsn + \"password=hunter2\")"])Output
["1:hardcoded_password", "1:discarded_error"]