added tunnel authtoken detection in ngrok detector (#4115)
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user