Skip to content

Commit 885c603

Browse files
Merge pull request #2371 from projectdiscovery/feature/secret-file-auth
feat: add secret file authentication support (-sf flag)
2 parents d66ff35 + 93633d2 commit 885c603

17 files changed

Lines changed: 1611 additions & 1 deletion

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ CONFIGURATIONS:
234234
-tlsi, -tls-impersonate enable experimental client hello (ja3) tls randomization
235235
-no-stdin Disable Stdin processing
236236
-hae, -http-api-endpoint string experimental http api endpoint
237+
-sf, -secret-file string path to secret file for authentication
237238

238239
DEBUG:
239240
-health-check, -hc run diagnostic check up
@@ -284,6 +285,24 @@ For details about running httpx, see https://docs.projectdiscovery.io/tools/http
284285
- The `-no-fallback` flag can be used to probe and display both **HTTP** and **HTTPS** result.
285286
- Custom scheme for ports can be defined, for example `-ports http:443,http:80,https:8443`
286287
- Custom resolver supports multiple protocol (**doh|tcp|udp**) in form of `protocol:resolver:port` (e.g. `udp:127.0.0.1:53`)
288+
- Secret files can be used for domain-based authentication via `-sf secrets.yaml`. Supported auth types: `BasicAuth`, `BearerToken`, `Header`, `Cookie`, `Query`. Example:
289+
```yaml
290+
id: example-auth
291+
info:
292+
name: Example Auth Config
293+
static:
294+
- type: Header
295+
domains:
296+
- api.example.com
297+
headers:
298+
- key: X-API-Key
299+
value: secret-key-here
300+
- type: BasicAuth
301+
domains-regex:
302+
- ".*\\.internal\\.com$"
303+
username: admin
304+
password: secret
305+
```
287306
- The following flags should be used for specific use cases instead of running them as default with other probes:
288307
- `-ports`
289308
- `-path`
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package authx
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/projectdiscovery/retryablehttp-go"
7+
)
8+
9+
var (
10+
_ AuthStrategy = &BasicAuthStrategy{}
11+
)
12+
13+
// BasicAuthStrategy is a strategy for basic auth
14+
type BasicAuthStrategy struct {
15+
Data *Secret
16+
}
17+
18+
// NewBasicAuthStrategy creates a new basic auth strategy
19+
func NewBasicAuthStrategy(data *Secret) *BasicAuthStrategy {
20+
return &BasicAuthStrategy{Data: data}
21+
}
22+
23+
// Apply applies the basic auth strategy to the request
24+
func (s *BasicAuthStrategy) Apply(req *http.Request) {
25+
req.SetBasicAuth(s.Data.Username, s.Data.Password)
26+
}
27+
28+
// ApplyOnRR applies the basic auth strategy to the retryable request
29+
func (s *BasicAuthStrategy) ApplyOnRR(req *retryablehttp.Request) {
30+
req.SetBasicAuth(s.Data.Username, s.Data.Password)
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package authx
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/projectdiscovery/retryablehttp-go"
7+
)
8+
9+
var (
10+
_ AuthStrategy = &BearerTokenAuthStrategy{}
11+
)
12+
13+
// BearerTokenAuthStrategy is a strategy for bearer token auth
14+
type BearerTokenAuthStrategy struct {
15+
Data *Secret
16+
}
17+
18+
// NewBearerTokenAuthStrategy creates a new bearer token auth strategy
19+
func NewBearerTokenAuthStrategy(data *Secret) *BearerTokenAuthStrategy {
20+
return &BearerTokenAuthStrategy{Data: data}
21+
}
22+
23+
// Apply applies the bearer token auth strategy to the request
24+
func (s *BearerTokenAuthStrategy) Apply(req *http.Request) {
25+
req.Header.Set("Authorization", "Bearer "+s.Data.Token)
26+
}
27+
28+
// ApplyOnRR applies the bearer token auth strategy to the retryable request
29+
func (s *BearerTokenAuthStrategy) ApplyOnRR(req *retryablehttp.Request) {
30+
req.Header.Set("Authorization", "Bearer "+s.Data.Token)
31+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package authx
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/projectdiscovery/retryablehttp-go"
7+
)
8+
9+
var (
10+
_ AuthStrategy = &CookiesAuthStrategy{}
11+
)
12+
13+
// CookiesAuthStrategy is a strategy for cookies auth
14+
type CookiesAuthStrategy struct {
15+
Data *Secret
16+
}
17+
18+
// NewCookiesAuthStrategy creates a new cookies auth strategy
19+
func NewCookiesAuthStrategy(data *Secret) *CookiesAuthStrategy {
20+
return &CookiesAuthStrategy{Data: data}
21+
}
22+
23+
// Apply applies the cookies auth strategy to the request
24+
func (s *CookiesAuthStrategy) Apply(req *http.Request) {
25+
for _, cookie := range s.Data.Cookies {
26+
req.AddCookie(&http.Cookie{
27+
Name: cookie.Key,
28+
Value: cookie.Value,
29+
})
30+
}
31+
}
32+
33+
// ApplyOnRR applies the cookies auth strategy to the retryable request
34+
func (s *CookiesAuthStrategy) ApplyOnRR(req *retryablehttp.Request) {
35+
// Build a set of cookie names to replace
36+
newCookieNames := make(map[string]struct{}, len(s.Data.Cookies))
37+
for _, cookie := range s.Data.Cookies {
38+
newCookieNames[cookie.Key] = struct{}{}
39+
}
40+
41+
// Filter existing cookies, keeping only those not being replaced
42+
existingCookies := req.Cookies()
43+
filteredCookies := make([]*http.Cookie, 0, len(existingCookies))
44+
for _, cookie := range existingCookies {
45+
if _, shouldReplace := newCookieNames[cookie.Name]; !shouldReplace {
46+
filteredCookies = append(filteredCookies, cookie)
47+
}
48+
}
49+
50+
// Clear and reset cookies
51+
req.Header.Del("Cookie")
52+
for _, cookie := range filteredCookies {
53+
req.AddCookie(cookie)
54+
}
55+
// Add new cookies
56+
for _, cookie := range s.Data.Cookies {
57+
req.AddCookie(&http.Cookie{
58+
Name: cookie.Key,
59+
Value: cookie.Value,
60+
})
61+
}
62+
}

0 commit comments

Comments
 (0)