-
Notifications
You must be signed in to change notification settings - Fork 1
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
PYIC-6710: remove common secrets from .scerets.baseline #2034
Conversation
.secrets.baseline
Outdated
"^.*{[a-zA-Z0-9-_\":,]+OXt0P05ZsQcK7eYusgIPsqZdaBCIJiW4imwUtnaAthU[a-zA-Z0-9-_\":,]+}$", | ||
"^.*[a-zA-Z0-9._]+KClzxkHU35ck5Wck7jECzt0_TAkiy4iXRrUg_aftDg2uUpLOC0Bnb-77lyTlhSTuotEQbqB1YZqV3X_SotEQbg", | ||
"^.*{[a-zA-Z0-9-_\":,]+qoXdkYVomy6HWT6yNLqjHSmYoICs6ioUF565Btx0apw[a-zA-Z0-9-_\":,]+}$", | ||
"^.*{[a-zA-Z0-9-_\":,]+wfSHxlvJlJcdS20r5PKKmqdPeW3Y4ir3WsVVeiht2iOZUreUO5O3V3o7ImvEjPS[a-zA-Z0-9-_\":,]+}$", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of values that look like this that I wasn't sure how to capture in a single regex:
{"kty":"EC","d":"OXt0P05ZsQcK7eYusgIPsqZdaBCIJiW4imwUtnaAthU","crv":"P-256","x":"E9ZzuO..., "y": "safsW....}
I tried something like
{(?:\"[a-zA-z]+\":\"[a-zA-Z0-9_]+\",)+(?:\"[a-zA-z]+\":\"[a-zA-Z0-9-_]+\")}
which got rid of a lot of secrets but I think might be too generic 😨
Another option could be specifying a combination of keys
{(?:\"(kty|x|y|d)\":\"[a-zA-Z0-9_]+\",)+(?:\"(kty|x|y|d)\":\"[a-zA-Z0-9-_]+\")}
but I think it might still let a real secret through if it had a similar structure.
So I've opted for finding common key values instead that have been re-used across the codebase. This might be less likely to catch a new false positive but I think would be more likely to prevent a real secret from being added.
I'd like to get more thoughts/ideas on this though!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely don't want to exclude anything in that format - since that'll include all keys (including prod ones!)
Can we just exclude the entirety of the test key strings? I think this is basically what you've done, but including the entire JSON object.
TEST_SIGNING_KEY = ECKey.parse(EC_PUBLIC_JWK); | ||
TEST_SIGNING_KEY2 = | ||
ECKey.parse( | ||
"{\"crv\":\"P-256\",\"d\":\"o1orSH_mS3u1zzi4wXa9C-cgY2bPyZWN5DxK78JCN6E\",\"kty\":\"EC\",\"x\":\"LziA3lV476BwPG5glvLLx8-FzMbeX2ti9wYlhwCWNhQ\",\"y\":\"NfvgSlu1TMNjjMRM3um29Tv79C4NL8x6WEY7t4BBneA\"}"); | ||
"{\"crv\":\"P-256\",\"d\":\"o1orSH_mS3u1zzi4wXa9C-cgY2bPyZWN5DxK78JCN6E\",\"kty\":\"EC\",\"x\":\"LziA3lV476BwPG5glvLLx8-FzMbeX2ti9wYlhwCWNhQ\",\"y\":\"NfvgSlu1TMNjjMRM3um29Tv79C4NL8x6WEY7t4BBneA\"}"); // pragma: allowlist secret |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of common test values e.g. TEST_SIGNING_KEY
or FAILED_F2F_VC_PASSPORT_SIGNATURE
with unique values which spans more than one line because of the length of the string. However, I think detect-secrets processes files line by line so we can't use something like the exclude_line filter with a regex to look at the value of the line before it:
(?im)(?<=.test_signing_key =\n).*$
So I think it might be the case that we'll have to use an inline exclusion for these as they typically have unique values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is the 'secret' matching against TEST_SIGNING_KEY2
rather than the key value itself? That's annoying :(
If they're unique, then I think an allowlist comment is probably better anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's matching against the value itself which is typically unique. We can't match it using the name of the variable it's assigned to unless the whole thing is on one line in which case we can use something like the exclude-line
filter to match against the name of the variable it's assigned to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we explicitly don't want to match against the variable name - there's nothing guaranteeing that a variable named 'test_key' is not actually a genuine secret!
If it's unique then I think the allowlist comment is the best approach, then someone has to explicitly decide that it's safe each time.
.secrets.baseline
Outdated
{ | ||
"path": "detect_secrets.filters.regex.should_exclude_file", | ||
"pattern": [ | ||
".*/TestFixtures.java$" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excluding this file since all of these are used for testing but wondering if I should use inline exclusions here instead for added safety?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. Excluding by file feels a little risky - I could certainly see a scenario where a dev replaces a test VC with a prod one and uses a unit test as a way of running the decryption.
(but if it's really painful then this might be risk we want to accept)
.secrets.baseline
Outdated
{ | ||
"path": "detect_secrets.filters.regex.should_exclude_file", | ||
"pattern": [ | ||
".*/TestFixtures.java$" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. Excluding by file feels a little risky - I could certainly see a scenario where a dev replaces a test VC with a prod one and uses a unit test as a way of running the decryption.
(but if it's really painful then this might be risk we want to accept)
.secrets.baseline
Outdated
"^.*{[a-zA-Z0-9-_\":,]+OXt0P05ZsQcK7eYusgIPsqZdaBCIJiW4imwUtnaAthU[a-zA-Z0-9-_\":,]+}$", | ||
"^.*[a-zA-Z0-9._]+KClzxkHU35ck5Wck7jECzt0_TAkiy4iXRrUg_aftDg2uUpLOC0Bnb-77lyTlhSTuotEQbqB1YZqV3X_SotEQbg", | ||
"^.*{[a-zA-Z0-9-_\":,]+qoXdkYVomy6HWT6yNLqjHSmYoICs6ioUF565Btx0apw[a-zA-Z0-9-_\":,]+}$", | ||
"^.*{[a-zA-Z0-9-_\":,]+wfSHxlvJlJcdS20r5PKKmqdPeW3Y4ir3WsVVeiht2iOZUreUO5O3V3o7ImvEjPS[a-zA-Z0-9-_\":,]+}$", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely don't want to exclude anything in that format - since that'll include all keys (including prod ones!)
Can we just exclude the entirety of the test key strings? I think this is basically what you've done, but including the entire JSON object.
.secrets.baseline
Outdated
"x-api-key", | ||
"ScnF4dGXthZYXS_5k85ObEoSU04W-H3qa_p6npv2ZUY", | ||
"^.*eyJpc3MiOiJpcHYtY29yZSIsInN1YiI6Imlwdi1jb3JlIiwiYXVkIjoiZHVtbX.*$", | ||
"^.*&code=dummyAuthCode.*$" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume there's no way of putting comments against these? It'd be nice to know what these are, and what the justification for excluding them is...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly I don't think you can put comments in this file :( My main motivation for putting a rule down for a secret is that it exists in multiple places either as a whole e.g. "ScnF4dGXthZYXS_5k85ObEoSU04W-H3qa_p6npv2ZUY"
or a variation of that secret e.g. "^.*eyJpc3MiOiJpcHYtY29yZSIsInN1YiI6Imlwdi1jb3JlIiwiYXVkIjoiZHVtbX.*$"
TEST_SIGNING_KEY = ECKey.parse(EC_PUBLIC_JWK); | ||
TEST_SIGNING_KEY2 = | ||
ECKey.parse( | ||
"{\"crv\":\"P-256\",\"d\":\"o1orSH_mS3u1zzi4wXa9C-cgY2bPyZWN5DxK78JCN6E\",\"kty\":\"EC\",\"x\":\"LziA3lV476BwPG5glvLLx8-FzMbeX2ti9wYlhwCWNhQ\",\"y\":\"NfvgSlu1TMNjjMRM3um29Tv79C4NL8x6WEY7t4BBneA\"}"); | ||
"{\"crv\":\"P-256\",\"d\":\"o1orSH_mS3u1zzi4wXa9C-cgY2bPyZWN5DxK78JCN6E\",\"kty\":\"EC\",\"x\":\"LziA3lV476BwPG5glvLLx8-FzMbeX2ti9wYlhwCWNhQ\",\"y\":\"NfvgSlu1TMNjjMRM3um29Tv79C4NL8x6WEY7t4BBneA\"}"); // pragma: allowlist secret |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is the 'secret' matching against TEST_SIGNING_KEY2
rather than the key value itself? That's annoying :(
If they're unique, then I think an allowlist comment is probably better anyway.
.secrets.baseline
Outdated
"hXYrKJ_W9YItUbZxu3T63gQgScVoSMqHZ43UPfdB8im8L4d0mZPLC6BlwMJSsfjiAyU1y3c37vm-rV8kZo2uyw", | ||
"EFfq4iMeJ9ekCYJDZS8MTqxK0semEH7HRMac9Tc69zILtxzlVmJxnrhsVSgjpMNi3osCBUhWlz3Zh-jEUB4izw", | ||
"^.*eyJzdWIiOiIxMjM0IiwiYXVkIjoiYWRtaW4iLCJpc3MiOiJtYXNvbi5tZXRhbXVnLm5ldCIsImV4cCI6MTU3NDUxMjc2NSwiaWF0IjoxNTY.*", | ||
"x-api-key", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I confirm, this is excluding values that are exactly x-api-key
- not just secrets that contain it?
(We don't want to exclude, e.g., x-api-key: some-very-secret-value
)
ff96559
to
5604460
Compare
… contract tests and exclude from baseline
This reverts commit 6989639.
62e1964
to
1859d12
Compare
…paste to other tools
# Conflicts: # .secrets.baseline # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/addressCri/ContractTest.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/bavCri/ContractTest.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/cicCri/ContractTest.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/dcmawCri/ContractTest.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/drivingLicenceCri/CredentialTests.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/experianKbvCri/ContractTest.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/fraudCri/CredentialTests.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/hmrcKbvCri/ContractTest.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/ninoCri/ContractTest.java # lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/passportCri/CredentialTests.java # libs/verifiable-credentials/src/test/java/uk/gov/di/ipv/core/library/verifiablecredential/validator/VerifiableCredentialValidatorTest.java
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Proposed changes
What changed
TestFixtures
Why did it change
The .secrets.baseline file was being updated with new secrets every time a "secret" was detected. Instead, we should use rules to avoid false positives being added to the baseline. This means we'll have less conflicts as the only changes made to the baseline should be if the filters are updated.
Issue tracking