Skip to content

Commit

Permalink
Merge pull request #43 from cerberauth/trace-method-scan
Browse files Browse the repository at this point in the history
feat: add http trace method scan
  • Loading branch information
emmanuelgautier authored Feb 12, 2024
2 parents 7ee8287 + c4f391c commit ea3bb5c
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1 deletion.
17 changes: 17 additions & 0 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,20 @@ type Operation struct {

SecuritySchemes []SecurityScheme
}

func (o Operation) Clone() Operation {
clonedHeaders := make(http.Header)
if o.Headers != nil {
clonedHeaders = o.Headers.Clone()
}

clonedCookies := make([]http.Cookie, len(o.Cookies))
copy(clonedCookies, o.Cookies)

return Operation{
Url: o.Url,
Method: o.Method,
Headers: &clonedHeaders,
Cookies: clonedCookies,
}
}
6 changes: 5 additions & 1 deletion scan/best_practices.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ func (s *Scan) WithHTTPHeadersBestPracticesScan() *Scan {
return s.AddScanHandler(bestpractices.HTTPHeadersBestPracticesScanHandler)
}

func (s *Scan) WithHTTPTraceMethodBestPracticesScan() *Scan {
return s.AddScanHandler(bestpractices.HTTPTraceMethodScanHandler)
}

func (s *Scan) WithAllBestPracticesScans() *Scan {
return s.WithHTTPHeadersBestPracticesScan()
return s.WithHTTPHeadersBestPracticesScan().WithHTTPTraceMethodBestPracticesScan()
}
35 changes: 35 additions & 0 deletions scan/best_practices/http_trace_method.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package bestpractices

import (
"github.com/cerberauth/vulnapi/internal/auth"
restapi "github.com/cerberauth/vulnapi/internal/rest_api"
"github.com/cerberauth/vulnapi/report"
)

const (
HTTPTraceMethodSeverityLevel = 1
HTTPTraceMethodVulnerabilityName = "HTTP Trace Method enabled"
HTTPTraceMethodVulnerabilityDescription = "HTTP Trace method seems enabled for this request."
)

func HTTPTraceMethodScanHandler(o *auth.Operation, ss auth.SecurityScheme) (*report.ScanReport, error) {
r := report.NewScanReport()
newOperation := o.Clone()
newOperation.Method = "TRACE"

token := ss.GetValidValue().(string)
ss.SetAttackValue(token)
vsa := restapi.ScanRestAPI(&newOperation, ss)
r.AddScanAttempt(vsa).End()

if vsa.Response.StatusCode < 300 {
r.AddVulnerabilityReport(&report.VulnerabilityReport{
SeverityLevel: HTTPTraceMethodSeverityLevel,
Name: HTTPTraceMethodVulnerabilityName,
Description: HTTPTraceMethodVulnerabilityDescription,
Url: o.Url,
})
}

return r, nil
}
59 changes: 59 additions & 0 deletions scan/best_practices/http_trace_method_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package bestpractices_test

import (
"testing"

"github.com/cerberauth/vulnapi/internal/auth"
"github.com/cerberauth/vulnapi/report"
bestpractices "github.com/cerberauth/vulnapi/scan/best_practices"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestHTTPTraceMethodScanHandler(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

token := "token"
securityScheme := auth.NewAuthorizationBearerSecurityScheme("default", &token)
o := auth.Operation{
Method: "GET",
Url: "http://localhost:8080/",
}

httpmock.RegisterResponder("TRACE", o.Url, httpmock.NewBytesResponder(405, nil))

report, err := bestpractices.HTTPTraceMethodScanHandler(&o, securityScheme)

require.NoError(t, err)
assert.Equal(t, 1, httpmock.GetTotalCallCount())
assert.False(t, report.HasVulnerabilityReport())
}

func TestHTTPTraceMethodWhenTraceIsEnabledScanHandler(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

token := "token"
securityScheme := auth.NewAuthorizationBearerSecurityScheme("default", &token)
o := auth.Operation{
Method: "GET",
Url: "http://localhost:8080/",
}
vulnerabilityReport := report.VulnerabilityReport{
SeverityLevel: bestpractices.HTTPTraceMethodSeverityLevel,
Name: bestpractices.HTTPTraceMethodVulnerabilityName,
Description: bestpractices.HTTPTraceMethodVulnerabilityDescription,
Url: o.Url,
}

httpmock.RegisterResponder("TRACE", o.Url, httpmock.NewBytesResponder(204, nil))

report, err := bestpractices.HTTPTraceMethodScanHandler(&o, securityScheme)

require.NoError(t, err)
assert.Equal(t, 1, httpmock.GetTotalCallCount())
assert.True(t, report.HasVulnerabilityReport())
assert.Equal(t, report.GetVulnerabilityReports()[0], &vulnerabilityReport)
}

0 comments on commit ea3bb5c

Please sign in to comment.