-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Conversation
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.
Docs look great to me, it's really nice to have a concrete example
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.
lgtm with one non-blocking suggestion
pkg/common/http.go
Outdated
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) |
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.
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
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.
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.
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.
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 |
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.
optional: You could maybe just check s.client == nil
and use it on line 59 below, rather than creating a client every time.
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.
do you mean mutating the scanner struct?
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.
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.
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. |
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'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 -
trufflehog/pkg/detectors/dockerhub/dockerhub.go
Lines 79 to 82 in 8ec5e49
// 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.
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 was trying to pick language that made it clear that was a hypothetical case, but I guess I didn't do a good job :(
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.
Maybe a separate paragraph for the start of the hypothetical case? And potentially changing the would
to would likely
?
1c719c7
to
96ab00c
Compare
96ab00c
to
af642d6
Compare
This isn't an "important" detector - except that it's the template detector that the detector generator runs on! This PR also:
Duration
directly instead of interpreting aint64
as a number of secondsint64
values to Durations, so we need to be careful when making this change elsewhere