-
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
add tri-state verification to mongodb detector #1575
Changes from all commits
f558bd8
de75bac
394067b
f7bd9d5
e1cddec
b41fa9d
b866e46
2e3b1d3
28c2bde
6a0d10d
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 |
---|---|---|
|
@@ -2,6 +2,8 @@ package mongodb | |
|
||
import ( | ||
"context" | ||
"go.mongodb.org/mongo-driver/x/mongo/driver/auth" | ||
"go.mongodb.org/mongo-driver/x/mongo/driver/topology" | ||
"regexp" | ||
"strings" | ||
"time" | ||
|
@@ -14,12 +16,15 @@ import ( | |
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" | ||
) | ||
|
||
type Scanner struct{} | ||
type Scanner struct { | ||
timeout time.Duration // Zero value means "default timeout" | ||
} | ||
|
||
// Ensure the Scanner satisfies the interface at compile time. | ||
var _ detectors.Detector = (*Scanner)(nil) | ||
|
||
var ( | ||
defaultTimeout = 2 * time.Second | ||
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives. | ||
keyPat = regexp.MustCompile(`\b(mongodb(\+srv)?://[\S]{3,50}:([\S]{3,88})@[-.%\w\/:]+)\b`) | ||
// TODO: Add support for sharded cluster, replica set and Atlas Deployment. | ||
|
@@ -46,30 +51,49 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result | |
} | ||
|
||
if verify { | ||
func() { | ||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) | ||
defer cancel() | ||
client, err := mongo.Connect(ctx, options.Client().ApplyURI(resMatch)) | ||
if err != nil { | ||
return | ||
} | ||
defer func() { | ||
if err := client.Disconnect(ctx); err != nil { | ||
return | ||
} | ||
}() | ||
if err := client.Ping(ctx, readpref.Primary()); err != nil { | ||
return | ||
} | ||
s1.Verified = true | ||
}() | ||
timeout := s.timeout | ||
if timeout == 0 { | ||
timeout = defaultTimeout | ||
} | ||
err := verifyUri(resMatch, timeout) | ||
s1.Verified = err == nil | ||
if !isErrDeterminate(err) { | ||
s1.VerificationError = err | ||
} | ||
} | ||
results = append(results, s1) | ||
} | ||
|
||
return results, nil | ||
} | ||
|
||
func isErrDeterminate(err error) bool { | ||
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. suggestion: I think you can simplify this with:
or i guess if we want to use the errors pkg:
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. i actually specifically wrote this not to be as terse as possible, but to make it easy to extend with other error cases in the future. do you find it hard to read as it is? 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. ahh okay, i think that makes sense. I sorta had the feeling, but wasn't sure. If we leave the switches might be worth adding the default case to each, no mandatory though. One of the the go linters happens to yell at me when i have a switch with no default. 🤷 |
||
switch e := err.(type) { | ||
case topology.ConnectionError: | ||
switch e.Unwrap().(type) { | ||
case *auth.Error: | ||
return true | ||
default: | ||
return false | ||
} | ||
default: | ||
return false | ||
} | ||
} | ||
|
||
func verifyUri(uri string, timeout time.Duration) error { | ||
ctx, cancel := context.WithTimeout(context.Background(), timeout) | ||
defer cancel() | ||
client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) | ||
if err != nil { | ||
return err | ||
} | ||
defer func() { | ||
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. nit: since we are ignoring the err here anyways we can inline it: 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. huh, i could have sworn the linter didn't let me do that... 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. might've complained that you are ignoring the err i suppose. 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. yeah |
||
_ = client.Disconnect(ctx) | ||
}() | ||
return client.Ping(ctx, readpref.Primary()) | ||
} | ||
|
||
func (s Scanner) Type() detectorspb.DetectorType { | ||
return detectorspb.DetectorType_MongoDB | ||
} |
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.
@ahrav i think this was just discarding the result of
client.Disconnect
so i simplified it a bit when i moved it, but give a shout if the new version looks wrongThere 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!