diff --git a/hack/docs/Adding_Detectors_external.md b/hack/docs/Adding_Detectors_external.md index a40de07fb326..08ef68ed77fe 100644 --- a/hack/docs/Adding_Detectors_external.md +++ b/hack/docs/Adding_Detectors_external.md @@ -52,7 +52,7 @@ Note: Be sure to update the tests to reference the new secret values in GSM, or 3. Proceed from step 3 of [Creating a new Secret Scanner](#creating-a-new-secret-scanner) -### Creating a new Secret Scanner +### Creating a new Secret Detector 1. Add a new Secret Detector enum to the [`DetectorType` list here](/proto/detectors.proto). @@ -69,40 +69,19 @@ Note: Be sure to update the tests to reference the new secret values in GSM, or Add the secret scanner to the [`pkg/engine/defaults.go`](https://github.com/trufflesecurity/trufflehog/blob/main/pkg/engine/defaults.go) file like [`github.com/trufflesecurity/trufflehog/v3/pkg/detectors/`](https://github.com/trufflesecurity/trufflehog/blob/b71ea27a696bdf1c3141f637fda4ee4936c2f2d6/pkg/engine/defaults.go#L9) and [`.Scanner{}`](https://github.com/trufflesecurity/trufflehog/blob/b71ea27a696bdf1c3141f637fda4ee4936c2f2d6/pkg/engine/defaults.go#L1546) -5. Complete the secret detector. +5. Complete the Secret Detector. The previous step templated a boilerplate + some example code as a package in the `pkg/detectors` folder for you to work on. - The secret detector can be completed with these general steps: + The Secret Detector can be completed with these general steps: - 1. Create a [test secrets file, and export the variable](#using-a-test-secret-file) - 2. Update the pattern regex and keywords. Try iterating with [regex101.com](http://regex101.com/). - 3. Update the verifier code to use a non-destructive API call that can determine whether the secret is valid or not. + 1. Update the pattern regex and keywords. Try iterating with [regex101.com](http://regex101.com/). + 2. Update the verifier code to use a non-destructive API call that can determine whether the secret is valid or not. * Make sure you understand [verification indeterminacy](#verification-indeterminacy). - 4. Update the tests with these test cases at minimum: - 1. Found and verified (using a credential loaded from GCP Secrets) - 2. Found and unverified (determinately, i.e. the secret is invalid) - 3. Found and unverified (indeterminately due to timeout) - 4. Found and unverified (indeterminately due to an unexpected API response) - 5. Not found - 6. Any false positive cases that you come across - 5. Create a pull request for review. + 3. Create a [test for the detector](#testing-the-detector) + 4. Create a pull request for review. -## Addendum - -### Verification indeterminacy - -There are two types of reasons that secret verification can fail: -* The candidate secret is not actually a valid secret. -* Something went wrong in the process unrelated to the candidate secret, such as a transient network error or an unexpected API response. - -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, consider a hypothetical authentication endpoint that returns `200 OK` for valid credentials and `403 Forbidden` for invalid credentials. The verifier for this endpoint could make an HTTP request and use the response status code to decide what to return: -* A `200` response would indicate that verification succeeded. (Or maybe any `2xx` response.) -* 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. - -### Using a test secret file +### Testing the Detector +To ensure the quality of your PR, make sure your tests are passing with verified credentials. 1. Create a file called `.env` with this env file format: @@ -116,8 +95,49 @@ For example, consider a hypothetical authentication endpoint that returns `200 O ```bash export TEST_SECRET_FILE=".env" ``` +The `.env` file should be in the new detector's directory like this: +``` +├── tailscale +│   ├── .env +│   ├── tailscale.go +│   └── tailscale_test.go +``` + +Now that a `.env` file is present, the test file can load secrets locally. + +Next, Update the tests with these test cases at minimum: +1. Found and verified (using a credential loaded from the .env file) +2. Found and unverified (determinately, i.e. the secret is invalid) +3. Found and unverified (indeterminately due to timeout) +4. Found and unverified (indeterminately due to an unexpected API response) +5. Not found + +[Here is an exemplary test file for a detector which covers all 5 test cases](https://github.com/trufflesecurity/trufflehog/blob/6f9065b0aae981133a7fa3431c17a5c6213be226/pkg/detectors/browserstack/browserstack_test.go) + +Now run the tests! +```bash + go test ./pkg/detectors/ -tags=detectors + ``` -Now, the detector test should attempt to load the given env key from that file. +If the tests are passing, feel free to open a PR! + + + + +## Addendum + +### Verification indeterminacy + +There are two types of reasons that secret verification can fail: +* The candidate secret is not actually a valid secret. +* Something went wrong in the process unrelated to the candidate secret, such as a transient network error or an unexpected API response. + +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, consider a hypothetical authentication endpoint that returns `200 OK` for valid credentials and `403 Forbidden` for invalid credentials. The verifier for this endpoint could make an HTTP request and use the response status code to decide what to return: +* A `200` response would indicate that verification succeeded. (Or maybe any `2xx` response.) +* 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. ### Adding Protos in Windows