Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 163b2f8

Browse files
authoredMar 25, 2024
Merge pull request #72 from cerberauth/fix-validate-operation
fix: validation operation properly before scanning url
2 parents 212e0f5 + a1e80f2 commit 163b2f8

File tree

5 files changed

+68
-8
lines changed

5 files changed

+68
-8
lines changed
 

‎internal/auth/bearer.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ func NewAuthorizationBearerSecurityScheme(name string, value *string) *BearerSec
4444

4545
func (ss *BearerSecurityScheme) GetHeaders() http.Header {
4646
header := http.Header{}
47-
if ss.ValidValue != nil {
48-
header.Set(AuthorizationHeader, fmt.Sprintf("%s %s", BearerPrefix, ss.GetAttackValue().(string)))
47+
attackValue := ss.GetAttackValue().(string)
48+
if attackValue == "" && ss.ValidValue != nil {
49+
attackValue = *ss.ValidValue
4950
}
5051

52+
header.Set(AuthorizationHeader, fmt.Sprintf("%s %s", BearerPrefix, attackValue))
53+
5154
return header
5255
}
5356

‎scan/jwt/not_verified.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,26 @@ func NotVerifiedScanHandler(operation *request.Operation, ss auth.SecurityScheme
3232
}
3333

3434
ss.SetAttackValue(ss.GetValidValue())
35-
vsa1, err := scan.ScanURL(operation, &ss)
35+
attemptOne, err := scan.ScanURL(operation, &ss)
3636
if err != nil {
3737
return r, err
3838
}
39-
r.AddScanAttempt(vsa1)
39+
r.AddScanAttempt(attemptOne)
40+
41+
if scan.DetectNotExpectedResponse(attemptOne.Response) == nil {
42+
return r, nil
43+
}
4044

4145
ss.SetAttackValue(newToken)
42-
vsa2, err := scan.ScanURL(operation, &ss)
46+
attemptTwo, err := scan.ScanURL(operation, &ss)
4347
if err != nil {
4448
return r, err
4549
}
4650

47-
r.AddScanAttempt(vsa2)
51+
r.AddScanAttempt(attemptTwo)
4852
r.End()
4953

50-
if vsa1.Response.StatusCode == vsa2.Response.StatusCode {
54+
if attemptOne.Response.StatusCode == attemptTwo.Response.StatusCode {
5155
r.AddVulnerabilityReport(&report.VulnerabilityReport{
5256
SeverityLevel: NotVerifiedVulnerabilitySeverityLevel,
5357
Name: NotVerifiedVulnerabilityName,

‎scan/jwt/not_verified_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,24 @@ func TestNotVerifiedScanHandlerWithNotVerifiedJWT(t *testing.T) {
6868
assert.Equal(t, 2, httpmock.GetTotalCallCount())
6969
assert.True(t, report.HasVulnerabilityReport())
7070
}
71+
72+
func TestNotVerifiedScanHandlerWhenHTTPCodeIs401(t *testing.T) {
73+
httpmock.Activate()
74+
defer httpmock.DeactivateAndReset()
75+
76+
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
77+
securityScheme := auth.NewAuthorizationBearerSecurityScheme("token", &token)
78+
operation := request.NewOperation("http://localhost:8080/", "GET", nil, nil, nil)
79+
80+
httpmock.RegisterResponder(operation.Method, operation.Request.URL.String(), httpmock.ResponderFromMultipleResponses(
81+
[]*http.Response{
82+
httpmock.NewBytesResponse(401, nil),
83+
httpmock.NewBytesResponse(401, nil),
84+
}, t.Log),
85+
)
86+
report, err := jwt.NotVerifiedScanHandler(operation, securityScheme)
87+
88+
assert.NoError(t, err)
89+
assert.Equal(t, 1, httpmock.GetTotalCallCount())
90+
assert.False(t, report.HasVulnerabilityReport())
91+
}

‎scan/scan.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ func (s *Scan) Execute() (*report.Reporter, []error, error) {
8888
}
8989

9090
func (s *Scan) ValidateOperation(operation *request.Operation) error {
91-
attempt, err := scan.ScanURL(operation, &operation.SecuritySchemes[0])
91+
securityScheme := operation.SecuritySchemes[0] // TODO: handle multiple security schemes
92+
attempt, err := scan.ScanURL(operation, &securityScheme)
9293
if err != nil {
9394
return err
9495
}
@@ -97,6 +98,10 @@ func (s *Scan) ValidateOperation(operation *request.Operation) error {
9798
return attempt.Err
9899
}
99100

101+
if scan.DetectNotExpectedResponse(attempt.Response) == nil {
102+
return fmt.Errorf("operation validation failed because of unexpected response: %d", attempt.Response.StatusCode)
103+
}
104+
100105
return nil
101106
}
102107

‎scan/scan_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/cerberauth/vulnapi/internal/request"
1010
"github.com/cerberauth/vulnapi/report"
1111
"github.com/cerberauth/vulnapi/scan"
12+
"github.com/jarcoal/httpmock"
1213
"github.com/stretchr/testify/assert"
1314
"github.com/stretchr/testify/require"
1415
)
@@ -61,3 +62,29 @@ func TestNewScanWithReporter(t *testing.T) {
6162
Reporter: reporter,
6263
}, s)
6364
}
65+
66+
func TestScanValidateOperation(t *testing.T) {
67+
httpmock.Activate()
68+
defer httpmock.DeactivateAndReset()
69+
70+
operation := request.NewOperation("http://localhost:8080/", "GET", nil, nil, nil)
71+
httpmock.RegisterResponder(operation.Method, operation.Request.URL.String(), httpmock.ResponderFromResponse(httpmock.NewStringResponse(200, "OK")))
72+
73+
s, err := scan.NewURLScan(operation.Method, operation.RequestURI, nil, nil, nil)
74+
75+
err = s.ValidateOperation(operation)
76+
assert.NoError(t, err)
77+
}
78+
79+
func TestScanValidateOperationWhenRequestHasInternalServerError(t *testing.T) {
80+
httpmock.Activate()
81+
defer httpmock.DeactivateAndReset()
82+
83+
operation := request.NewOperation("http://localhost:8080/", "GET", nil, nil, nil)
84+
httpmock.RegisterResponder(operation.Method, operation.Request.URL.String(), httpmock.ResponderFromResponse(httpmock.NewStringResponse(500, "Internal Server Error")))
85+
86+
s, err := scan.NewURLScan(operation.Method, operation.RequestURI, nil, nil, nil)
87+
88+
err = s.ValidateOperation(operation)
89+
assert.Error(t, err)
90+
}

0 commit comments

Comments
 (0)
Please sign in to comment.