Skip to content

Commit

Permalink
resolve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
syywu committed Jun 22, 2024
1 parent 8696c51 commit 07b487c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 43 deletions.
49 changes: 19 additions & 30 deletions checks/hsts.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@ import (
"unicode"
)

const (
StrictTransportSecurity = "Strict-Transport-Security"
includeSubDomains = "includeSubDomains"
preload = "preload"
NilHeadersError = "Site does not serve any HSTS headers."
MaxAgeError = "HSTS max-age is less than 10886400."
SubdomainsError = "HSTS header does not include all subdomains."
PreloadError = "HSTS header does not contain the preload directive."
HstsSuccess = "Site is compatible with the HSTS preload list!"
)

type HSTSResponse struct {
Message string `json:"message"`
Compatible bool `json:"compatible"`
Expand All @@ -45,37 +34,41 @@ func (h *Hsts) Validate(ctx context.Context, url string) (*HSTSResponse, error)
}
defer resp.Body.Close()

hstsHeader := resp.Header.Get(StrictTransportSecurity)
hstsHeader := resp.Header.Get("Strict-Transport-Security")
if hstsHeader == "" {
return &HSTSResponse{
Message: NilHeadersError,
}, nil
return &HSTSResponse{Message: "Site does not serve any HSTS headers."}, nil
}

maxAge := extractMaxAgeFromHeader(hstsHeader)
if maxAge == "" {
return &HSTSResponse{Message: MaxAgeError}, nil
if !strings.Contains(hstsHeader, "max-age") {
return &HSTSResponse{Message: "HSTS max-age is less than 10886400."}, nil
}

maxAgeInt, err := convertMaxAgeStringToInt(maxAge)
var maxAgeString string
for _, h := range strings.Split(hstsHeader, " ") {
if strings.Contains(h, "max-age=") {
maxAgeString = extractMaxAgeFromHeader(h)
}
}

maxAge, err := strconv.Atoi(maxAgeString)
if err != nil {
return nil, err

Check warning on line 55 in checks/hsts.go

View check run for this annotation

Codecov / codecov/patch

checks/hsts.go#L55

Added line #L55 was not covered by tests
}

if maxAgeInt < 10886400 {
return &HSTSResponse{Message: MaxAgeError}, nil
if maxAge < 10886400 {
return &HSTSResponse{Message: "HSTS max-age is less than 10886400."}, nil
}

if !strings.Contains(hstsHeader, includeSubDomains) {
return &HSTSResponse{Message: SubdomainsError}, nil
if !strings.Contains(hstsHeader, "includeSubDomains") {
return &HSTSResponse{Message: "HSTS header does not include all subdomains."}, nil
}

if !strings.Contains(hstsHeader, preload) {
return &HSTSResponse{Message: PreloadError}, nil
if !strings.Contains(hstsHeader, "preload") {
return &HSTSResponse{Message: "HSTS header does not contain the preload directive."}, nil
}

return &HSTSResponse{
Message: HstsSuccess,
Message: "Site is compatible with the HSTS preload list!",
Compatible: true,
HSTSHeader: hstsHeader,
}, nil
Expand All @@ -92,7 +85,3 @@ func extractMaxAgeFromHeader(header string) string {

return maxAge.String()
}

func convertMaxAgeStringToInt(maxAge string) (int, error) {
return strconv.Atoi(maxAge)
}
26 changes: 13 additions & 13 deletions checks/hsts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ func TestValidate(t *testing.T) {
t.Parallel()

client := testutils.MockClient(&http.Response{
Header: http.Header{StrictTransportSecurity: []string{""}}})
Header: http.Header{"Strict-Transport-Security": []string{""}}})
h := NewHsts(client)

actual, err := h.Validate(context.Background(), "test.com")
assert.NoError(t, err)

assert.Equal(t, NilHeadersError, actual.Message)
assert.Equal(t, "Site does not serve any HSTS headers.", actual.Message)
assert.False(t, actual.Compatible)
assert.Empty(t, actual.HSTSHeader)
})
Expand All @@ -31,13 +31,13 @@ func TestValidate(t *testing.T) {
t.Parallel()

client := testutils.MockClient(&http.Response{
Header: http.Header{StrictTransportSecurity: []string{"includeSubDomains; preload"}}})
Header: http.Header{"Strict-Transport-Security": []string{"includeSubDomains; preload"}}})
h := NewHsts(client)

actual, err := h.Validate(context.Background(), "test.com")
assert.NoError(t, err)

assert.Equal(t, MaxAgeError, actual.Message)
assert.Equal(t, "HSTS max-age is less than 10886400.", actual.Message)
assert.False(t, actual.Compatible)
assert.Empty(t, actual.HSTSHeader)
})
Expand All @@ -46,13 +46,13 @@ func TestValidate(t *testing.T) {
t.Parallel()

client := testutils.MockClient(&http.Response{
Header: http.Header{StrictTransportSecurity: []string{"max-age=47; includeSubDomains; preload"}}})
Header: http.Header{"Strict-Transport-Security": []string{"max-age=47; includeSubDomains; preload"}}})
h := NewHsts(client)

actual, err := h.Validate(context.Background(), "test.com")
assert.NoError(t, err)

assert.Equal(t, MaxAgeError, actual.Message)
assert.Equal(t, "HSTS max-age is less than 10886400.", actual.Message)
assert.False(t, actual.Compatible)
assert.Empty(t, actual.HSTSHeader)
})
Expand All @@ -61,13 +61,13 @@ func TestValidate(t *testing.T) {
t.Parallel()

client := testutils.MockClient(&http.Response{
Header: http.Header{StrictTransportSecurity: []string{"max-age=47474747; preload"}}})
Header: http.Header{"Strict-Transport-Security": []string{"max-age=47474747; preload"}}})
h := NewHsts(client)

actual, err := h.Validate(context.Background(), "test.com")
assert.NoError(t, err)

assert.Equal(t, SubdomainsError, actual.Message)
assert.Equal(t, "HSTS header does not include all subdomains.", actual.Message)
assert.False(t, actual.Compatible)
assert.Empty(t, actual.HSTSHeader)
})
Expand All @@ -76,13 +76,13 @@ func TestValidate(t *testing.T) {
t.Parallel()

client := testutils.MockClient(&http.Response{
Header: http.Header{StrictTransportSecurity: []string{"max-age=47474747; includeSubDomains"}}})
Header: http.Header{"Strict-Transport-Security": []string{"max-age=47474747; includeSubDomains"}}})
h := NewHsts(client)

actual, err := h.Validate(context.Background(), "test.com")
assert.NoError(t, err)

assert.Equal(t, PreloadError, actual.Message)
assert.Equal(t, "HSTS header does not contain the preload directive.", actual.Message)
assert.False(t, actual.Compatible)
assert.Empty(t, actual.HSTSHeader)
})
Expand All @@ -91,13 +91,13 @@ func TestValidate(t *testing.T) {
t.Parallel()

client := testutils.MockClient(&http.Response{
Header: http.Header{StrictTransportSecurity: []string{"max-age=47474747; includeSubDomains; preload"}}})
Header: http.Header{"Strict-Transport-Security": []string{"max-age=47474747; includeSubDomains; preload"}}})
h := NewHsts(client)

actual, err := h.Validate(context.Background(), "test.com")
assert.NoError(t, err)

assert.Equal(t, HstsSuccess, actual.Message)
assert.Equal(t, "Site is compatible with the HSTS preload list!", actual.Message)
assert.True(t, actual.Compatible)
assert.NotEmpty(t, actual.HSTSHeader)
})
Expand All @@ -111,7 +111,7 @@ func TestExtractMaxAgeFromHeader(t *testing.T) {
header string
expected string
}{
{"give valid header", "max-age=47474747; includeSubDomains; preload", "47474747"},
{"give valid header", "max-age=47474747;", "47474747"},
{"given an empty header", "", ""},
} {
tc := tc
Expand Down

0 comments on commit 07b487c

Please sign in to comment.