Skip to content
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

Support indeterminacy in alchemy and update detector docs #1510

Merged
merged 18 commits into from
Jul 21, 2023

Conversation

rosecodym
Copy link
Collaborator

@rosecodym rosecodym commented Jul 18, 2023

This isn't an "important" detector - except that it's the template detector that the detector generator runs on! This PR also:

  • Updates the associated documentation
  • Changes the method that creates a common testing HTTP client with a timeout to accept a Duration directly instead of interpreting a int64 as a number of seconds
    • Go will silently convert int64 values to Durations, so we need to be careful when making this change elsewhere

@rosecodym rosecodym requested a review from a team July 19, 2023 14:24
@rosecodym rosecodym requested a review from a team as a code owner July 19, 2023 14:57
hack/docs/Adding_Detectors_external.md Outdated Show resolved Hide resolved
@rosecodym rosecodym changed the title Migrate alchemy detector to tri-state verification Support indeterminacy in alchemy and update detector docs Jul 19, 2023
@rosecodym rosecodym requested review from a team July 19, 2023 17:56
Copy link
Contributor

@samdatkins samdatkins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs look great to me, it's really nice to have a concrete example

Copy link
Collaborator

@mcastorina mcastorina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with one non-blocking suggestion

Comment on lines 155 to 181
func SaneHttpClientTimeOut(timeOutSeconds int64) *http.Client {
func SaneHttpClientTimeOut(timeoutMs int64) *http.Client {
httpClient := &http.Client{}
httpClient.Timeout = time.Second * time.Duration(timeOutSeconds)
httpClient.Timeout = time.Millisecond * time.Duration(timeoutMs)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're changing the units here already, could we change the input parameter to be a time.Duration so the user can choose? It also help readability:

client := SaneHttpClientTimeOut(10 * time.Second) // 10s
client := SaneHttpClientTimeOut(10000)            // ???

This will also make code that imports this function not compile* when it gets updated, which is better than silently making all timeouts 1000x faster.

*I think.. hopefully Go doesn't silently promote an int64 to a time.Duration

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good suggestion but it looks like Go will silently interpret int64 values as nanoseconds. As you pointed out, this means we should be careful when vendoring the change in.

Copy link
Collaborator

@trufflesteeeve trufflesteeeve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just some small adjustments.

@@ -47,6 +48,10 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}

if verify {
client := s.client
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional: You could maybe just check s.client == nil and use it on line 59 below, rather than creating a client every time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean mutating the scanner struct?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Or set it as a default somewhere? As it is, every time this attempts to verify it will create a new client. Which is fine, but probably not necessary.

hack/docs/Adding_Detectors_external.md Outdated Show resolved Hide resolved
In Trufflehog parlance, the first type of verification response is called _determinate_ and the second type is called _indeterminate_. Verification code should distinguish between the two by returning an error object in the result struct **only** for indeterminate failures. In general, a verifier should return an error (indicating an indeterminate failure) in all cases that haven't been explicitly identified as determinate failure states. For example, if a verifier makes an HTTP request to a hypothetical authentication endpoint, the response codes could determine what to return:
* Any `2xx` response would indicate that verification succeeded.
* A `403` response would indicate that verification failed **determinately** and no error object should be returned.
* Any other response would indicate that verification failed **indeterminately** and an error object should be returned.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we can say this is true for all apis we test against. e.g. Docker can still be a valid credential and return a 401 -

// Valid credentials can still return a 401 status code if 2FA is enabled
if (res.StatusCode >= 200 && res.StatusCode < 300) || (res.StatusCode == 401 && strings.Contains(string(body), "login_2fa_token")) {
s1.Verified = true
}

So maybe adjust the language to be less certain about the indeterminate verification failure in the case of non 2XX or 403 responses.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to pick language that made it clear that was a hypothetical case, but I guess I didn't do a good job :(

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a separate paragraph for the start of the hypothetical case? And potentially changing the would to would likely?

@rosecodym rosecodym merged commit ebf1038 into main Jul 21, 2023
10 checks passed
@rosecodym rosecodym deleted the alchemy-indeterminacy branch July 21, 2023 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants