added tunnel authtoken detection in ngrok detector (#4115)

This commit is contained in:
Nabeel Alam
2025-05-02 11:19:29 -05:00
committed by GitHub
parent afbf580a6e
commit 869df44e20
2 changed files with 39 additions and 6 deletions
+18 -3
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
regexp "github.com/wasilibs/go-re2"
@@ -31,6 +32,11 @@ func (s Scanner) Keywords() []string {
return []string{"ngrok"}
}
const (
ngrokVerificationURL = "https://api.ngrok.com/agent_ingresses"
tunnelCredentialErrorCode = "ERR_NGROK_206"
)
var (
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"ngrok"}) + `\b(2[a-zA-Z0-9]{26}_\d[a-zA-Z0-9]{20})\b`)
)
@@ -69,7 +75,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
func verifyMatch(ctx context.Context, client *http.Client, token string) (bool, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.ngrok.com/agent_ingresses", nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, ngrokVerificationURL, nil)
if err != nil {
return false, err
}
@@ -90,7 +96,16 @@ func verifyMatch(ctx context.Context, client *http.Client, token string) (bool,
return true, nil
case http.StatusUnauthorized:
return false, nil
default:
return false, fmt.Errorf("ngrok: unexpected status code: %d", res.StatusCode)
case http.StatusBadRequest:
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
return false, err
}
// Check if the error code is "ERR_NGROK_206" which indicates that
// the credential is a valid tunnel Authtoken rather than an API key.
if strings.Contains(string(bodyBytes), tunnelCredentialErrorCode) {
return true, nil
}
}
return false, fmt.Errorf("ngrok: unexpected status code: %d", res.StatusCode)
}
+21 -3
View File
@@ -25,7 +25,8 @@ func TestNgrok_FromChunk(t *testing.T) {
if err != nil {
t.Fatalf("could not get test secrets from GCP: %s", err)
}
secret := testSecrets.MustGetField("NGROK")
secretAPIKey := testSecrets.MustGetField("NGROK")
secretAuthtoken := testSecrets.MustGetField("NGROK_AUTHTOKEN")
inactiveSecret := testSecrets.MustGetField("NGROK_INACTIVE")
type args struct {
@@ -42,11 +43,28 @@ func TestNgrok_FromChunk(t *testing.T) {
wantVerificationErr bool
}{
{
name: "found, verified",
name: "found, API key, verified",
s: Scanner{},
args: args{
ctx: context.Background(),
data: []byte(fmt.Sprintf("You can find a ngrok secret %s within", secret)),
data: []byte(fmt.Sprintf("You can find a ngrok secret API key %s within", secretAPIKey)),
verify: true,
},
want: []detectors.Result{
{
DetectorType: detectorspb.DetectorType_Ngrok,
Verified: true,
},
},
wantErr: false,
wantVerificationErr: false,
},
{
name: "found, tunnel authtoken, verified",
s: Scanner{},
args: args{
ctx: context.Background(),
data: []byte(fmt.Sprintf("You can find a ngrok secret tunnel authtoken %s within", secretAuthtoken)),
verify: true,
},
want: []detectors.Result{