Skip to content

Commit

Permalink
Removing HPKP and Expect-CT (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
unrolled authored Dec 27, 2023
1 parent 1b1c685 commit 58f2e47
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 150 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Content-Security-Policy: script-src 'nonce-a2ZobGFoZg=='
~~~

### Set the `IsDevelopment` option to `true` when developing!
When `IsDevelopment` is true, the AllowedHosts, SSLRedirect, STS header, and HPKP header will not be in effect. This allows you to work in development/test mode and not have any annoying redirects to HTTPS (ie. development can happen on HTTP), or block `localhost` has a bad host.
When `IsDevelopment` is true, the AllowedHosts, SSLRedirect, and STS header will not be in effect. This allows you to work in development/test mode and not have any annoying redirects to HTTPS (ie. development can happen on HTTP), or block `localhost` has a bad host.

### Available options
Secure comes with a variety of configuration options (Note: these are not the default option values. See the defaults below.):
Expand All @@ -80,12 +80,10 @@ s := secure.New(secure.Options{
BrowserXssFilter: true, // If BrowserXssFilter is true, adds the X-XSS-Protection header with the value `1; mode=block`. Default is false.
CustomBrowserXssValue: "1; report=https://example.com/xss-report", // CustomBrowserXssValue allows the X-XSS-Protection header value to be set with a custom value. This overrides the BrowserXssFilter option. Default is "".
ContentSecurityPolicy: "default-src 'self'", // ContentSecurityPolicy allows the Content-Security-Policy header value to be set with a custom value. Default is "". Passing a template string will replace `$NONCE` with a dynamic nonce value of 16 bytes for each request which can be later retrieved using the Nonce function.
PublicKey: `pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubdomains; report-uri="https://www.example.com/hpkp-report"`, // Deprecated: This feature is no longer recommended. PublicKey implements HPKP to prevent MITM attacks with forged certificates. Default is "".
ReferrerPolicy: "same-origin", // ReferrerPolicy allows the Referrer-Policy header with the value to be set with a custom value. Default is "".
FeaturePolicy: "vibrate 'none';", // Deprecated: this header has been renamed to PermissionsPolicy. FeaturePolicy allows the Feature-Policy header with the value to be set with a custom value. Default is "".
PermissionsPolicy: "fullscreen=(), geolocation=()", // PermissionsPolicy allows the Permissions-Policy header with the value to be set with a custom value. Default is "".
CrossOriginOpenerPolicy: "same-origin", // CrossOriginOpenerPolicy allows the Cross-Origin-Opener-Policy header with the value to be set with a custom value. Default is "".
ExpectCTHeader: `enforce, max-age=30, report-uri="https://www.example.com/ct-report"`,

IsDevelopment: true, // This will cause the AllowedHosts, SSLRedirect, and STSSeconds/STSIncludeSubdomains options to be ignored during development. When deploying to production, be sure to set this to false.
})
Expand Down Expand Up @@ -123,7 +121,6 @@ l := secure.New(secure.Options{
FeaturePolicy: "",
PermissionsPolicy: "",
CrossOriginOpenerPolicy: "",
ExpectCTHeader: "",
IsDevelopment: false,
})
~~~
Expand Down
16 changes: 0 additions & 16 deletions secure.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const (
referrerPolicyHeader = "Referrer-Policy"
featurePolicyHeader = "Feature-Policy"
permissionsPolicyHeader = "Permissions-Policy"
expectCTHeader = "Expect-CT"
coopHeader = "Cross-Origin-Opener-Policy"

ctxDefaultSecureHeaderKey = secureCtxKey("SecureResponseHeader")
Expand Down Expand Up @@ -82,9 +81,6 @@ type Options struct {
// Eg: script-src $NONCE -> script-src 'nonce-a2ZobGFoZg=='
// CustomFrameOptionsValue allows the X-Frame-Options header value to be set with a custom value. This overrides the FrameDeny option. Default is "".
CustomFrameOptionsValue string
// PublicKey implements HPKP to prevent MITM attacks with forged certificates. Default is "".
// Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible.
PublicKey string
// ReferrerPolicy allows sites to control when browsers will pass the Referer header to other sites. Default is "".
ReferrerPolicy string
// FeaturePolicy allows to selectively enable and disable use of various browser features and APIs. Default is "".
Expand Down Expand Up @@ -112,8 +108,6 @@ type Options struct {
SSLProxyHeaders map[string]string
// STSSeconds is the max-age of the Strict-Transport-Security header. Default is 0, which would NOT include the header.
STSSeconds int64
// ExpectCTHeader allows the Expect-CT header value to be set with a custom value. Default is "".
ExpectCTHeader string
// SecureContextKey allows a custom key to be specified for context storage.
SecureContextKey string
}
Expand Down Expand Up @@ -434,11 +428,6 @@ func (s *Secure) processRequest(w http.ResponseWriter, r *http.Request) (http.He
responseHeader.Set(xssProtectionHeader, xssProtectionValue)
}

// HPKP header.
if len(s.opt.PublicKey) > 0 && ssl && !s.opt.IsDevelopment {
responseHeader.Set(hpkpHeader, s.opt.PublicKey)
}

// Content Security Policy header.
if len(s.opt.ContentSecurityPolicy) > 0 {
if s.opt.nonceEnabled {
Expand Down Expand Up @@ -477,11 +466,6 @@ func (s *Secure) processRequest(w http.ResponseWriter, r *http.Request) (http.He
responseHeader.Set(coopHeader, s.opt.CrossOriginOpenerPolicy)
}

// Expect-CT header.
if len(s.opt.ExpectCTHeader) > 0 {
responseHeader.Set(expectCTHeader, s.opt.ExpectCTHeader)
}

return responseHeader, r, nil
}

Expand Down
130 changes: 0 additions & 130 deletions secure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -969,121 +969,6 @@ func TestInlineSecureForRequestOnly(t *testing.T) {
expect(t, res.Header().Get("X-Frame-Options"), "")
}

// https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning
const hpkp = `pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs="; pin-sha256="M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="; max-age=5184000; includeSubdomains; report-uri="https://www.example.net/hpkp-report"`

func TestHPKP(t *testing.T) {
s := New(Options{
PublicKey: hpkp,
})

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)
req.URL.Scheme = "https"

s.Handler(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), hpkp)
}

func TestHPKPForRequestOnly(t *testing.T) {
s := New(Options{
PublicKey: hpkp,
})

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)
req.URL.Scheme = "https"

s.HandlerForRequestOnly(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), "")
}

func TestHPKPNotSet(t *testing.T) {
s := New()

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)

s.Handler(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), "")
}

func TestHPKPNotSetForRequestOnly(t *testing.T) {
s := New()

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)

s.HandlerForRequestOnly(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), "")
}

func TestHPKPInDevMode(t *testing.T) {
s := New(Options{
PublicKey: hpkp,
IsDevelopment: true,
})

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)

s.Handler(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), "")
}

func TestHPKPInDevModeForRequestOnly(t *testing.T) {
s := New(Options{
PublicKey: hpkp,
IsDevelopment: true,
})

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)

s.HandlerForRequestOnly(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), "")
}

func TestHPKPNonSSL(t *testing.T) {
s := New(Options{
PublicKey: hpkp,
})

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)

s.Handler(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), "")
}

func TestHPKPNonSSLForRequestOnly(t *testing.T) {
s := New(Options{
PublicKey: hpkp,
})

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)

s.HandlerForRequestOnly(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Public-Key-Pins"), "")
}

func TestReferrer(t *testing.T) {
s := New(Options{
ReferrerPolicy: "same-origin",
Expand Down Expand Up @@ -1154,21 +1039,6 @@ func TestCrossOriginOpenerPolicy(t *testing.T) {
expect(t, res.Header().Get("Cross-Origin-Opener-Policy"), "same-origin")
}

func TestExpectCT(t *testing.T) {
s := New(Options{
ExpectCTHeader: `enforce, max-age=30, report-uri="https://www.example.com/ct-report"`,
})

res := httptest.NewRecorder()
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/foo", nil)
req.Host = "www.example.com"

s.Handler(myHandler).ServeHTTP(res, req)

expect(t, res.Code, http.StatusOK)
expect(t, res.Header().Get("Expect-CT"), `enforce, max-age=30, report-uri="https://www.example.com/ct-report"`)
}

func TestIsSSL(t *testing.T) {
s := New(Options{
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
Expand Down

0 comments on commit 58f2e47

Please sign in to comment.