5
5
"fmt"
6
6
"io"
7
7
"net/http"
8
+ "strings"
8
9
9
10
regexp "github.com/wasilibs/go-re2"
10
11
@@ -31,6 +32,11 @@ func (s Scanner) Keywords() []string {
31
32
return []string {"ngrok" }
32
33
}
33
34
35
+ const (
36
+ ngrokVerificationURL = "https://api.ngrok.com/agent_ingresses"
37
+ tunnelCredentialErrorCode = "ERR_NGROK_206"
38
+ )
39
+
34
40
var (
35
41
keyPat = regexp .MustCompile (detectors .PrefixRegex ([]string {"ngrok" }) + `\b(2[a-zA-Z0-9]{26}_\d[a-zA-Z0-9]{20})\b` )
36
42
)
@@ -69,7 +75,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
69
75
}
70
76
71
77
func verifyMatch (ctx context.Context , client * http.Client , token string ) (bool , error ) {
72
- req , err := http .NewRequestWithContext (ctx , http .MethodGet , "https://api.ngrok.com/agent_ingresses" , nil )
78
+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , ngrokVerificationURL , nil )
73
79
if err != nil {
74
80
return false , err
75
81
}
@@ -90,7 +96,16 @@ func verifyMatch(ctx context.Context, client *http.Client, token string) (bool,
90
96
return true , nil
91
97
case http .StatusUnauthorized :
92
98
return false , nil
93
- default :
94
- return false , fmt .Errorf ("ngrok: unexpected status code: %d" , res .StatusCode )
99
+ case http .StatusBadRequest :
100
+ bodyBytes , err := io .ReadAll (res .Body )
101
+ if err != nil {
102
+ return false , err
103
+ }
104
+ // Check if the error code is "ERR_NGROK_206" which indicates that
105
+ // the credential is a valid tunnel Authtoken rather than an API key.
106
+ if strings .Contains (string (bodyBytes ), tunnelCredentialErrorCode ) {
107
+ return true , nil
108
+ }
95
109
}
110
+ return false , fmt .Errorf ("ngrok: unexpected status code: %d" , res .StatusCode )
96
111
}
0 commit comments