profile
viewpoint

google/go-safeweb 330

Secure-by-default HTTP servers in Go.

mattiasgrenfeldt/writeups 2

CTF writeups

Kodsport/sakerhetssm-2020-solutions 1

Lösningar till Säkerhets-SM 2020

Kodsport/sakerhetssm-monthly-solutions 1

Lösningar till Månadens Problem

datasektionen/d-nfc 0

Python NFC-reader utility library

Kodsport/sakerhetssm-2019-solutions 0

Lösningar till Säkerhets-SM 2019

maramihali/Attempts_On_Go 0

Implementation of a simple dummy server and a test harness that mocks the network stack. The mini-projects were done in order to gain familiarity with Golang

push eventsakerhetssm/sakerhetssm.github.io

Mattias Grenfeldt

commit sha 791205ecdb68bbbc55cd1e02726da5bfcfab19d9

Added files and hosting for spooktober mini-CTF tasks

view details

push time in 14 hours

startedincompl/csslayoutsite

started time in 14 hours

startedKariaro/AmpleProgrammingLanguage

started time in 15 hours

push eventsakerhetssm/sakerhetssm.github.io

Mattias Grenfeldt

commit sha 879a26aebdeda6dceb98fae72ee7079ef759b5a4

updated ip

view details

push time in 24 days

issue openedmrpasta/coolwebsite

yo

yo @mrpasta

created time in 24 days

push eventsakerhetssm/sakerhetssm.github.io

Mattias Grenfeldt

commit sha 3e350573f853b403e4928b1c954d935b99895c6d

fixed jul-2019

view details

push time in 24 days

push eventKodsport/sakerhetssm-monthly-solutions

mattiasgrenfeldt

commit sha c8008af7d36baaa961e3552787db1f75c17e2671

sep-2020 solution

view details

push time in a month

issue closedsakerhetssm/sakerhetssm.github.io

xxx

@sakerhetssm

closed time in a month

mattiasgrenfeldt

issue openedsakerhetssm/sakerhetssm.github.io

xxx

@sakerhetssm

created time in a month

fork mattiasgrenfeldt/hodis

User lookup and information management system

fork in a month

push eventsakerhetssm/sakerhetssm.github.io

Mattias Grenfeldt

commit sha 9e0b0d0337699ad674f5fb95c39df4efd8df70f7

hint2 sep-2020

view details

push time in a month

delete branch google/go-safeweb

delete branch : grenfeldt-fix-interceptor-signatures

delete time in a month

PR opened google/go-safeweb

Reviewers
Ensure that all interceptors fullfill the safehttp.Interceptor interface bug

Fixes #169

Fixed by adding type assertion in each interceptor package like this:

var _ safehttp.Interceptor = Interceptor{}
+42 -24

0 comment

9 changed files

pr created time in a month

create barnchgoogle/go-safeweb

branch : grenfeldt-fix-interceptor-signatures

created branch time in a month

push eventsakerhetssm/sakerhetssm.github.io

Mattias Grenfeldt

commit sha 29b4e60aa995e2e16c3498389aae27d7a0819f28

hint sep-2020

view details

push time in a month

delete branch google/go-safeweb

delete branch : maramihali-linters-comments

delete time in a month

Pull request review commentgoogle/go-safeweb

Address linter comments in the safehttp package

 func TestRequestSetNilContext(t *testing.T) { 			t.Errorf(`ir.SetContext(nil): expected panic`) 		} 	}()--	ir.SetContext(nil)+	var nilContext context.Context+	ir.SetContext(nilContext)

Add a comment explaining why this is done.

maramihali

comment created time in a month

PullRequestReviewEvent
PullRequestReviewEvent

delete branch google/go-safeweb

delete branch : maramihali-test-dispatcher-cleanup

delete time in a month

delete branch google/go-safeweb

delete branch : maramihali-dispatcher

delete time in a month

delete branch google/go-safeweb

delete branch : maramihali-package-comments

delete time in a month

push eventmattiasgrenfeldt/go-director

Mattias Grenfeldt

commit sha c25581421488284c14a9381348e2d5d1d770942d

imap chunk added, changed parsing style to use encoding/binary.Read

view details

push time in 2 months

push eventmattiasgrenfeldt/go-director

Mattias Grenfeldt

commit sha ad15a06ac5117ce87f9fc59c475ba54e6a4d6fb5

Basic RIFX parsing

view details

push time in 2 months

startedjsannemo/spooky-vm

started time in 2 months

delete branch google/go-safeweb

delete branch : grenfeldt-mihalimara22-fix-todos-in-godocs

delete time in 2 months

pull request commentgoogle/go-safeweb

Rewrite email in commits from personal email to google email.

I realized that this can't be done using a PR but must be done by force pushing to master.

mattiasgrenfeldt

comment created time in 2 months

delete branch google/go-safeweb

delete branch : grenfeldt-package-level-godocs

delete time in 2 months

delete branch google/go-safeweb

delete branch : grenfeldt-rewrite-email

delete time in 2 months

PR closed google/go-safeweb

Reviewers
Rewrite email in commits from personal email to google email.

I discovered that I had accidentally used my personal email for most of the commits during this project. These commits should instead be made using my @google.com email. I have rewritten history so that the @google.com email is used everywhere.

+11272 -13

1 comment

70 changed files

mattiasgrenfeldt

pr closed time in 2 months

PR opened google/go-safeweb

Reviewers
Rewrite email in commits from personal email to google email.

I discovered that I had accidentally used my personal email for most of the commits during this project. These commits should instead be made using my @google.com email.

+11272 -13

0 comment

70 changed files

pr created time in 2 months

create barnchgoogle/go-safeweb

branch : grenfeldt-rewrite-email

created branch time in 2 months

pull request commentgoogle/go-safeweb

Completed the framework's godoc

@googlebot I consent.

maramihali

comment created time in 2 months

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha 64a10ad7193045b52ca029c8e62cce760650be65

Updated godocs according to review comments

view details

push time in 2 months

Pull request review commentgoogle/go-safeweb

Completed the framework's godoc

  package safehttp -// Handler TODO+// Handler responds to an HTTP request.+//+// ServeHTTP should set headers, call one of the writing functions on the ResponseWriter+// to write the body of the response and then return the Result received from writing+// to the ResponseWriter.+//+// It is not valid to use the ResponseWriter or read from the body of the IncomingRequest+// after or concurrently with the completion of the ServeHTTP call.

We copied this pretty much straight off from the godoc of net/http.Handler. I agree it's pretty confusing so I'll remove it.

maramihali

comment created time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Added package level godocs to Collector, CORS, CSP, HSTS, staticheaders and safehttptest.

 var disallowedContentTypes = map[string]bool{ // // Each CORS request must contain the header "X-Cors: 1". //+// The HEAD request method is disallowed.+// // All of this is to prevent XSRF. type Interceptor struct { 	// AllowedOrigins determines which origins should be allowed in the 	// Access-Control-Allow-Origin header. 	AllowedOrigins map[string]bool-	allowedHeaders map[string]bool

This move is to make the godoc look better. If this is placed here then there will be an empty line in the godoc between AllowedOrigins and ExposedHeaders. Like this:

// AllowedOrigins determines which origins should be allowed in the
// Access-Control-Allow-Origin header.
AllowedOrigins map[string]bool

// ExposedHeaders ...

But if this is moved to be below all of the exported fields then the empty line is removed.

mattiasgrenfeldt

comment created time in 2 months

PR opened google/go-safeweb

Reviewers
Added package level godocs to Collector, CORS, CSP, HSTS, staticheaders and safehttptest. documentation

As part of improving the documentation of the project ( #132 ) I've added package level godocs for the following packages:

  • safehttp/plugins/collector
  • safehttp/plugins/cors
  • safehttp/plugins/csp
  • safehttp/plugins/hsts
  • safehttp/plugins/staticheaders
  • safehttp/safehttptest

Package level comments left to write are for:

  • safehttp/plugins/xsrf
  • safehttp/plugins/fetch_metadata

I'll let @maramihali write those since she wrote those packages.

+36 -2

0 comment

6 changed files

pr created time in 2 months

create barnchgoogle/go-safeweb

branch : grenfeldt-package-level-godocs

created branch time in 2 months

delete branch google/go-safeweb

delete branch : grenfeldt-mihalimara22-commit-phase

delete time in 2 months

delete branch google/go-safeweb

delete branch : csp-config

delete time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func TestResponseWriterWriteTwicePanic(t *testing.T) { 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>")) 			}, 		},+		{+			name: "Call WriteJSON twice",+			write: func(w *safehttp.ResponseWriter) {+				obj := struct{ Field string }{Field: "myField"}+				w.WriteJSON(obj)+				w.WriteJSON(obj)+			},

I opened an issue for testing every combination and ordering of writing methods. #157

maramihali

comment created time in 2 months

PullRequestReviewEvent

issue openedgoogle/go-safeweb

Make sure that writing twice to the ResponseWriter using any writing methods in any order causes a panic by refactoring test.

The TestResponseWriterWriteTwicePanic test in response_writer_test.go tests whether writing twice to ResponseWriter will cause a panic. But it only checks whether calling the same method twice causes a panic. For example:

w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))

or

w.NoContent()
w.NoContent()

It should be refactored to check every combination and ordering of calling two writing methods.

created time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func NotWritten() Result { 	return Result{} } -// Write TODO+// Write dispatches the response to the Dispatcher, setting the Content-Type to+// text/html; charset=utf-8 and response status to 200 OK if resp is a safe+// response. The Dispatcher will then write the response to the underlying+// Response Writer.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails. func (w *ResponseWriter) Write(resp Response) Result {-	w.markWritten()+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.WriteHeader(int(StatusOK))+	w.rw.Header().Set("Content-Type", ct)

I agree that we need a better error strategy for the dispatcher, but as you said, that's not V0.

To detect these kinds of errors in tests we need thorough integration tests between the ServeMux, the ResponseWriter and a Dispatcher.

But I still think that the ResponseWriter should not call WriteHeader. The Dispatcher should start doing the actual writing to the network connection.

maramihali

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func NotWritten() Result { 	return Result{} } -// Write TODO+// Write dispatches the response to the Dispatcher, setting the Content-Type to+// text/html; charset=utf-8 and response status to 200 OK if resp is a safe+// response. The Dispatcher will then write the response to the underlying+// Response Writer.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails. func (w *ResponseWriter) Write(resp Response) Result { 	w.markWritten()+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.Header().Set("Content-Type", ct)+	w.rw.WriteHeader(int(StatusOK)) 	if err := w.d.Write(w.rw, resp); err != nil {-		panic("error")+		panic(err) 	} 	return Result{} } -// WriteTemplate TODO+// WriteJSON encapsulates data into a JSON response and dispatches it to the+// Dispatcher, to be serialised and written to the ResponseWriter. It will also+// set the Content-Type to application/json; charset=utf-8 and the response+// status to 200 OK.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails.+func (w *ResponseWriter) WriteJSON(data interface{}) Result {+	w.markWritten()+	resp := JSONResponse{Data: data}+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.Header().Set("Content-Type", ct)+	w.rw.WriteHeader(int(StatusOK))+	if err := w.d.WriteJSON(w.rw, resp); err != nil {+		panic(err)+	}+	return Result{}+}++// WriteTemplate dispatches a parsed template and a data object to the+// Dispatcher to be executed and written to the underlying Response Writer, in+// case the template is a safe HTML template. If t is a safe HTML Template, the+// Content-Type will also be set to text/html; charset=utf-8 and the response+// status to 200 OK.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails.

The Content-Type for safe html templates depends on the Dispatcher implementation and should be left out of this comment.

maramihali

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func NotWritten() Result { 	return Result{} } -// Write TODO+// Write dispatches the response to the Dispatcher, setting the Content-Type to+// text/html; charset=utf-8 and response status to 200 OK if resp is a safe+// response. The Dispatcher will then write the response to the underlying+// Response Writer.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails. func (w *ResponseWriter) Write(resp Response) Result { 	w.markWritten()+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.Header().Set("Content-Type", ct)+	w.rw.WriteHeader(int(StatusOK)) 	if err := w.d.Write(w.rw, resp); err != nil {-		panic("error")+		panic(err) 	} 	return Result{} } -// WriteTemplate TODO+// WriteJSON encapsulates data into a JSON response and dispatches it to the+// Dispatcher, to be serialised and written to the ResponseWriter. It will also+// set the Content-Type to application/json; charset=utf-8 and the response+// status to 200 OK.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails.+func (w *ResponseWriter) WriteJSON(data interface{}) Result {+	w.markWritten()+	resp := JSONResponse{Data: data}+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.Header().Set("Content-Type", ct)

Shouldn't this method always set the Content-Type to application/json? Then it doesn't need to interrogate the Dispatcher

maramihali

comment created time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func NotWritten() Result { 	return Result{} } -// Write TODO+// Write dispatches the response to the Dispatcher, setting the Content-Type to+// text/html; charset=utf-8 and response status to 200 OK if resp is a safe

This sets the Content-Type to whatever the dispatcher tells it to. Not necessarily text/html

maramihali

comment created time in 2 months

PullRequestReviewEvent
PullRequestReviewEvent

issue commentgoogle/go-safeweb

Consider removing WriteTemplate and WriteJSON, implement helpers to just rely on Write

This relates to #85 (Just adding so we don't forget)

empijei

comment created time in 2 months

create barnchgoogle/go-safeweb

branch : grenfeldt-mihalimara22-fix-todos-in-godocs

created branch time in 2 months

issue openedgoogle/go-safeweb

ResponseWriter.Redirect checks whether the given status is in the right range (300-399), this should be removed to be consistent with WriteError

Currently the ReponseWriter.Redirect method still checks whether the given status code is in the right range. We have removed this check for WriteError and should remove it for Redirect to.

created time in 2 months

Pull request review commentgoogle/go-safeweb

Added a safehttp.NotWritten result so that safehttp.Result{} can stop being used.

 func (m methodHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 		} 	} -	h.ServeHTTP(rw, ir)+	if res := h.ServeHTTP(rw, ir); !res.written {+		rw.NoContent()

Sorry, I missed your response. But I opened #153 so this won't be forgotten.

mattiasgrenfeldt

comment created time in 2 months

PullRequestReviewEvent

issue openedgoogle/go-safeweb

Change ServeMux to write a 200 Ok response instead of 204 No Content when handler doesn't write any response to be in line with net/http.

In #120 @empijei suggested that we should respond with 200 Ok with an empty body if a handler never writes a response instead of 204 No Content. Responding with 200 Ok is what net/http does. I missed to implement this in that PR, so I'm opening this issue.

created time in 2 months

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha b435fb6a90759c7b315a2671079c1e2df4c412fd

Added first version of CORS plugin A CORS interceptor is implemented that handles preflights and applies the specified CORS rules on incoming requests. The request methods GET, HEAD and POST are banned. The Content-Types application/x-www-form-urlencoded, multipart/form-data and text/plain are also banned. Each request must also contain either 'X-Cors: 1' or 'Sec-Fetch-Mode: cors'. All of this is to prevent XSRF on CORS requests.

view details

Mattias Grenfeldt

commit sha 4d0042ad881c15fbbef2198c9a1b8579d489bddf

Rephrased comments according to code review comments.

view details

Mattias Grenfeldt

commit sha 2e56833fdd8b5180167363120521d71fc6d618c3

Added check if Access-Control-Request-Method is empty or missing.

view details

Mattias Grenfeldt

commit sha 3c1acb99924d769b0c79113a225fdf37bf51a420

Renamed actualRequest to just request.

view details

Mattias Grenfeldt

commit sha a1b05a20cccd3526c60682a083e3a08cb00ab16f

Removed setHeaders closure in Before.

view details

Mattias Grenfeldt

commit sha 567cf19888098a193b028de39445ca5244ecc540

Removed Sec-Fetch-Mode: cors as a valid header, now X-Cors: 1 is required.

view details

Mattias Grenfeldt

commit sha 3dcbb083476c4e1f93b812883b9864a7bb3c7a6e

Make sure that requests with no Origin header are allowed.

view details

Mattias Grenfeldt

commit sha 0cd8b8ae4e93f4fe999ccf6634c1e88fdf47862c

Make sure that a non-standard Content-Type is required on every request

view details

Mattias Grenfeldt

commit sha d7fcfe907c8dd11c9efe710246e463824d71f407

Removed disallowed request methods.

view details

Mattias Grenfeldt

commit sha 5a7843f749f1616f42178eca13fbf14a248db274

Improved comments

view details

Mattias Grenfeldt

commit sha 4cb65c2bc114e3a30f996494e80103d90ef7e8e8

Ban "*" from being set as an allowed header

view details

Mattias Grenfeldt

commit sha bfa142c5dbd0ad5d47a538a086946e3f11440862

Renamed customHeader to requiredHeader

view details

Mattias Grenfeldt

commit sha d30b5ed11590daa0d5b5aac075c3e6b06845014d

Removed check disallowing requests with cookies when AllowCredentials is false, this should happen in the browser.

view details

Mattias Grenfeldt

commit sha 190afca731fe9dedb4624c8c546c4873af348e10

Updated comments to reflect allowing GET/HEAD/POST etc. and fixed godoc formatting issues.

view details

Mattias Grenfeldt

commit sha dbc0625452e8479554c61e52450e34535465f75f

Clarified godoc for MaxAge that it is specified in seconds

view details

Mattias Grenfeldt

commit sha 95e88e8be9612b15825a94d52e5bec5a29a86bb5

Improved godoc

view details

Mattias Grenfeldt

commit sha b1c2f247a395e3bf8e7529bf3630a0bd8d0c7a60

Mentioned in godoc that the wildcard * is disallowed from ACAH header

view details

Mattias Grenfeldt

commit sha bce23a4440ef02b33cffda0313e3642c61e65317

Refactored CORS plugin to use WriteError and new Header API

view details

Mattias Grenfeldt

commit sha a3a3ec535c64348e7e168c5e4bb9ed523828725f

Append to the Vary header and don't claim it.

view details

Mattias Grenfeldt

commit sha 150dd35b0fa19eef0510f3e7e23b0d6a0382fbfc

Head method is forbidden in Access-Control-Request-Method

view details

push time in 2 months

delete branch google/go-safeweb

delete branch : grenfeldt-cors-plugin-first-version

delete time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func NotWritten() Result { 	return Result{} } -// Write TODO+// Write dispatches the response to the Dispatcher, setting the Content-Type to+// text/html; charset=utf-8 and response status to 200 OK if resp is a safe+// response. The Dispatcher will then write the response to the underlying+// Response Writer.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails. func (w *ResponseWriter) Write(resp Response) Result {-	w.markWritten()+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.WriteHeader(int(StatusOK))+	w.rw.Header().Set("Content-Type", ct)

I am not sure what to do here.

maramihali

comment created time in 2 months

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha a9dd4edb5ed4336446c83b79e36820321967cbe9

Empty Origin header on preflight requests disallowed.

view details

push time in 2 months

Pull request review commentgoogle/go-safeweb

Added the Commit phase

 func TestMuxInterceptors(t *testing.T) { }  type setHeaderConfig struct {-	name  string-	value string

Fixed!

mattiasgrenfeldt

comment created time in 2 months

PullRequestReviewEvent

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha cf31c312d2b50f8447358a12da06ba5dd61f84d5

Removed unrelated changes to tests to make code reviewing easier

view details

push time in 2 months

Pull request review commentgoogle/go-safeweb

Added the Commit phase

 func (setHeaderConfig) Match(i safehttp.Interceptor) bool { type setHeaderConfigInterceptor struct{}  func (p setHeaderConfigInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg interface{}) safehttp.Result {-	name := "Pizza" 	value := "Hawaii" 	if c, ok := cfg.(setHeaderConfig); ok {-		name = c.name-		value = c.value+		value = c.pizzaValue 	}-	w.Header().Set(name, value)+	w.Header().Set("Pizza", value) 	return safehttp.Result{} } +func (p setHeaderConfigInterceptor) Commit(w *safehttp.CommitResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg interface{}) safehttp.Result {+	value := "Fusili"+	if c, ok := cfg.(setHeaderConfig); ok {+		value = c.pastaValue+	}

Ah, yes, this check was to check if a valid config was passed. If there was no valid config passed then the default values would be used.

mattiasgrenfeldt

comment created time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Added first version of CORS plugin

+// Copyright 2020 Google LLC+//+// Licensed under the Apache License, Version 2.0 (the "License");+// you may not use this file except in compliance with the License.+// You may obtain a copy of the License at+//+// 	https://www.apache.org/licenses/LICENSE-2.0+//+// Unless required by applicable law or agreed to in writing, software+// distributed under the License is distributed on an "AS IS" BASIS,+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+// See the License for the specific language governing permissions and+// limitations under the License.++package cors_test++import (+	"testing"++	"github.com/google/go-cmp/cmp"+	"github.com/google/go-safeweb/safehttp"+	"github.com/google/go-safeweb/safehttp/plugins/cors"+	"github.com/google/go-safeweb/safehttp/safehttptest"+)++func TestRequest(t *testing.T) {+	tests := []struct {+		name             string+		req              *safehttp.IncomingRequest+		allowCredentials bool+		exposedHeaders   []string+		want             map[string][]string+	}{+		{+			name: "Basic GET",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodGet, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			want: map[string][]string{+				"Access-Control-Allow-Origin": {"https://foo.com"},+				"Vary":                        {"Origin"},+			},+		},+		{+			name: "Basic PUT",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodPut, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			want: map[string][]string{+				"Access-Control-Allow-Origin": {"https://foo.com"},+				"Vary":                        {"Origin"},+			},+		},+		{+			name: "Basic POST",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodPost, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			want: map[string][]string{+				"Access-Control-Allow-Origin": {"https://foo.com"},+				"Vary":                        {"Origin"},+			},+		},+		{+			name: "Basic HEAD",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodHead, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			want: map[string][]string{+				"Access-Control-Allow-Origin": {"https://foo.com"},+				"Vary":                        {"Origin"},+			},+		},+		{+			name: "No Origin header",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodPut, "http://bar.com", nil)+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			want: map[string][]string{},+		},+		{+			name: "AllowCredentials but no cookies",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodPut, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			allowCredentials: true,+			want: map[string][]string{+				"Access-Control-Allow-Origin": {"https://foo.com"},+				"Vary":                        {"Origin"},+			},+		},+		{+			name: "AllowCredentials with cookies",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodPut, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				r.Header.Set("Cookie", "a=b")+				return r+			}(),+			allowCredentials: true,+			want: map[string][]string{+				"Access-Control-Allow-Credentials": {"true"},+				"Access-Control-Allow-Origin":      {"https://foo.com"},+				"Vary":                             {"Origin"},+			},+		},+		{+			name: "Expose one header",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodPut, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			exposedHeaders: []string{"Aaaa"},+			want: map[string][]string{+				"Access-Control-Expose-Headers": {"Aaaa"},+				"Access-Control-Allow-Origin":   {"https://foo.com"},+				"Vary":                          {"Origin"},+			},+		},+		{+			name: "Expose multiple headers",+			req: func() *safehttp.IncomingRequest {+				r := safehttptest.NewRequest(safehttp.MethodPut, "http://bar.com", nil)+				r.Header.Set("Origin", "https://foo.com")+				r.Header.Set("X-Cors", "1")+				r.Header.Set("Content-Type", "application/json")+				return r+			}(),+			exposedHeaders: []string{"Aaaa", "Bbbb", "Cccc"},+			want: map[string][]string{+				"Access-Control-Expose-Headers": {"Aaaa, Bbbb, Cccc"},+				"Access-Control-Allow-Origin":   {"https://foo.com"},+				"Vary":                          {"Origin"},+			},+		},+	}++	for _, tt := range tests {+		t.Run(tt.name, func(t *testing.T) {+			rr := safehttptest.NewResponseRecorder()++			it := cors.Default("https://foo.com")+			it.AllowCredentials = tt.allowCredentials+			it.ExposedHeaders = tt.exposedHeaders+			it.Before(rr.ResponseWriter, tt.req)+

Opened #152

mattiasgrenfeldt

comment created time in 2 months

PullRequestReviewEvent

issue openedgoogle/go-safeweb

Status code in safehttptest.ResponseRecorder should be 0 by default instead of 200 so that interceptors that don't set it can be tested properly.

Currently the ResponseRecorder in safehttptest sets the status code to 200 if no status code has been set yet. This should be changed to 0 so that interceptors that don't set a status code and leave it up to the handler can be tested properly.

created time in 2 months

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha 88e9f0190041facdc35d4b02c382e338a343270c

Refactored big if-else chain into switch statement

view details

push time in 2 months

delete branch google/go-safeweb

delete branch : mara-broken-xsrf

delete time in 2 months

delete branch google/go-safeweb

delete branch : grenfeldt-dispatcher-wrapper

delete time in 2 months

push eventgoogle/go-safeweb

mattiasgrenfeldt

commit sha d7995fb291a191a6db41098bdfceb34385c85120

Fixed phrasing in comment Co-authored-by: maramihali <maramihali@google.com>

view details

push time in 2 months

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha f448ddce7b81e785f1ebbef6e8886cd7443c7f6c

commitPhase moved to handlerWithInterceptors from ResponseWriter.

view details

Mattias Grenfeldt

commit sha b3846b4daf05f9bed1e308033a801a2f184d7e2f

Unexported appliedInterceptors again and fixed TODO godocs

view details

push time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Added the Commit phase

 func TestMuxInterceptors(t *testing.T) { }  type setHeaderConfig struct {-	name  string-	value string

What do you mean with unrelated changes? We have updated the SetHeaderInterceptor with config and the SetHeaderInterceptor with mismatching config tests to also test the commit phase. Earlier they only tested the Before phase. How is this unrelated from the PR introducing the commit phase?

I looked through all our changes and found one unrelated change in mux_test.go in TestMuxInterceptors:

- wantStatus: 500,
+ wantStatus: safehttp.StatusInternalServerError,

We have in an earlier PR replaced all numeric status codes with constants and apparently I had missed this instance. How could it not be ok to fix these kinds of tiny nits when they are discovered? The other option would be to open a new issue and PR to just change this little thing.

mattiasgrenfeldt

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Added the Commit phase

 func NewServeMux(d Dispatcher, domains ...string) *ServeMux { 	} } -type appliedInterceptor struct {+// AppliedInterceptor TODO+type AppliedInterceptor struct {

It was part of the public API since we wanted to pass it as part of the ResponseWriter constructor and for that it needs to be exported, so that the constructor doesn't become unusable outside the package.

mattiasgrenfeldt

comment created time in 2 months

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Added the Commit phase

 type ResponseWriter struct {  	// Having this field unexported is essential for security. Otherwise one can 	// easily overwrite the struct bypassing all our safety guarantees.-	header  Header-	written bool+	header           Header+	appliedInterceps []AppliedInterceptor+	req              *IncomingRequest

Well, both appliedInterceps and req needed to be part of the ResponseWriter for our design where the ResponseWriter would run the commitPhase. In the newer design I'm working on now the ResponseWriter still needs to own the req but instead of appliedInterceps it has a reference to the handlerWithInterceptors and the commitPhase is moved to the handlerWithInterceptors.

mattiasgrenfeldt

comment created time in 2 months

pull request commentgoogle/go-safeweb

Added first version of CORS plugin

@empijei I fixed the two most recent comments you left about appending Vary and disallowing HEAD.

mattiasgrenfeldt

comment created time in 2 months

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha d01703e410a53b2ada5a41ee09e528229c57fd4d

Removed error return values from Add, Set, Claim and del in Header and panic instead.

view details

Mattias Grenfeldt

commit sha fdcfcb443a5f2dd71d4c2ad3f21a695b64d2a114

Added IsClaimed method to Header type

view details

Mattias Grenfeldt

commit sha 7b590e3f36a44c512a9eb74c10c2f24b1e8259d1

Improved godoc for Header type methods

view details

Mattias Grenfeldt

commit sha 06c0696df68349adc017c7e4388fcfbe6bd76691

Replaced ClientError and ServerError with WriteError in ResponseWriter

view details

Mattias Grenfeldt

commit sha 2ec19976fb0a5a1758ebb2c4eb12e15a499b6391

Make it more clear that error responses are in the range 400-599

view details

Mattias Grenfeldt

commit sha 3930a0f6b435c4ba7f803b5fd21f2ffe249154b1

Removed unused safehttp.HandleFunc

view details

Mattias Grenfeldt

commit sha 450a41597a7efcddb8f45b637cf3f1c48e313087

Removed interceptor keys from multiplexer. Now Interceptors are stored in slices instead of maps. To interact with an interceptor from the handler that interceptor needs to implement package level functions which take ResponseWriters and IncomingRequests and do things. State can be stored in the context of the request.

view details

Mattias Grenfeldt

commit sha 16d085d22036bad318e812d3bc35a686a3031134

Fixed nit in godoc and renamed appliedInterceps to just interceps

view details

Mattias Grenfeldt

commit sha 06e2a04f5958ccfdc9aab7d6920177997a7b6700

Renamed ai to interceptor

view details

Mara Mihali

commit sha 2a1bb79b5e3f671cb4ce8cc1c3adacb5d6fcdbc7

Added pre-login XSRF protection to the XSRF plugin and tests to verify the functionality

view details

Mara Mihali

commit sha bd5c56b0c83d4fb12b0fc2ab9a6342cbba15cdea

switch from checking whether the cookie is nil to checking whether the error is non-nil in call to IncomingRequest.Cookie

view details

Mara Mihali

commit sha bc15e1a94ce14d25f24d3dab630b557988e021f5

Improve naming and documentation

view details

Mara Mihali

commit sha 98bc621a460174b78177bf16ae40ef124dff7472

Return an error instead of panicking if rand.Read fails

view details

Mattias Grenfeldt

commit sha 7533ec91e55da464b82c82be04f808f717302ffd

Added first version of CORS plugin A CORS interceptor is implemented that handles preflights and applies the specified CORS rules on incoming requests. The request methods GET, HEAD and POST are banned. The Content-Types application/x-www-form-urlencoded, multipart/form-data and text/plain are also banned. Each request must also contain either 'X-Cors: 1' or 'Sec-Fetch-Mode: cors'. All of this is to prevent XSRF on CORS requests.

view details

Mattias Grenfeldt

commit sha ef28686ed7626d8ae053f40a9bd4f862fb433e84

Rephrased comments according to code review comments.

view details

Mattias Grenfeldt

commit sha b210eb5249c477321277eecc048bfb0eb914478a

Added check if Access-Control-Request-Method is empty or missing.

view details

Mattias Grenfeldt

commit sha 42e0477ea0c747bfbd9415d8a6eb3765770dbe10

Renamed actualRequest to just request.

view details

Mattias Grenfeldt

commit sha 902410bdb24101de57d29e8d22ab5a662d17dd7e

Removed setHeaders closure in Before.

view details

Mattias Grenfeldt

commit sha 176fb7b9a6c844125f4153612459bbd2e7b43ea3

Removed Sec-Fetch-Mode: cors as a valid header, now X-Cors: 1 is required.

view details

Mattias Grenfeldt

commit sha 120ebb43c7810da344699f30820457a0f4c89ad8

Make sure that requests with no Origin header are allowed.

view details

push time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func NotWritten() Result { 	return Result{} } -// Write TODO+// Write dispatches the response to the Dispatcher, setting the Content-Type to+// text/html; charset=utf-8 and response status to 200 OK if resp is a safe+// response. The Dispatcher will then write the response to the underlying+// Response Writer.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails. func (w *ResponseWriter) Write(resp Response) Result {-	w.markWritten()+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.WriteHeader(int(StatusOK))+	w.rw.Header().Set("Content-Type", ct)

Imagine that w.d.Write panics or returns an error, in which case ResponseWriter.Write will panic. This panic will be recovered by the framework (ServeMux) and a 500 Internal Server Error response will be written to the ResponseWriter. But the status code and the headers have already been written, so things will break.

We need to remove the call to WriteHeader.

maramihali

comment created time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Added first version of CORS plugin

+// Copyright 2020 Google LLC+//+// Licensed under the Apache License, Version 2.0 (the "License");+// you may not use this file except in compliance with the License.+// You may obtain a copy of the License at+//+// 	https://www.apache.org/licenses/LICENSE-2.0+//+// Unless required by applicable law or agreed to in writing, software+// distributed under the License is distributed on an "AS IS" BASIS,+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+// See the License for the specific language governing permissions and+// limitations under the License.++package cors++import (+	"net/textproto"+	"strconv"+	"strings"++	"github.com/google/go-safeweb/safehttp"+)++const customHeader string = "X-Cors"++var disallowedMethods = map[string]bool{+	safehttp.MethodHead: true,+	safehttp.MethodGet:  true,+	safehttp.MethodPost: true,+}++var disallowedContentTypes = map[string]bool{+	"application/x-www-form-urlencoded": true,+	"multipart/form-data":               true,+	"text/plain":                        true,+}++// Interceptor handles CORS requests based on its settings.+//+// For more info about CORS, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS+//+// Constraints+//+// - The request methods GET, HEAD and POST are banned and will result in a 405+//   Method Not Allowed response.+// - The content types "application/x-www-form-urlencoded", "multipart/form-data"+//   and "text/plain" are also banned and will result in a  415 Unsupported Media+//   Type response.+// - Each CORS request must contain the header "X-Cors: 1" or "Sec-Fetch-Mode: cors".+// All of this is to prevent XSRF.+type Interceptor struct {+	// AllowedOrigins determines which origins should be allowed in the+	// Access-Control-Allow-Origin header.+	AllowedOrigins map[string]bool+	allowedHeaders map[string]bool+	// ExposedHeaders determines which headers should be set in the+	// Access-Control-Expose-Headers header. If ExposedHeaders is nil, then the+	// header is not set.+	ExposedHeaders []string+	// AllowCredentials determines if Access-Control-Allow-Credentials should be+	// set to true when requests containing Cookie headers arrive.+	AllowCredentials bool+	// MaxAge sets the Access-Control-Max-Age header.+	// MaxAge=0 results in MaxAge: 5.+	MaxAge int+}++// Default creates a CORS Interceptor with default settings.+// Those defaults are:+//   - No Exposed Headers+//   - No Allowed Headers+//   - AllowCredentials: false+//   - MaxAge: 5 seconds+func Default(allowedOrigins ...string) *Interceptor {+	ao := map[string]bool{}+	for _, o := range allowedOrigins {+		ao[o] = true+	}+	return &Interceptor{+		AllowedOrigins: ao,+		allowedHeaders: map[string]bool{},+	}+}++// SetAllowedHeaders sets which headers should be allowed in the Access-Control-Allow-Headers+// header. The headers are first canonicalized using textproto.CanonicalMIMEHeaderKey.+func (it *Interceptor) SetAllowedHeaders(headers ...string) {+	it.allowedHeaders = map[string]bool{}+	for _, h := range headers {+		it.allowedHeaders[textproto.CanonicalMIMEHeaderKey(h)] = true+	}+}++// Before handles the incoming request and sets headers or responds with an error+// accordingly.+func (it *Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {+	origin := r.Header.Get("Origin")+	if !it.AllowedOrigins[origin] {+		return w.ClientError(safehttp.StatusForbidden)+	}+	h := w.Header()+	allowOrigin, err := h.Claim("Access-Control-Allow-Origin")+	if err != nil {+		return w.ServerError(safehttp.StatusInternalServerError)+	}+	vary, err := h.Claim("Vary")

No, so I will fix it

mattiasgrenfeldt

comment created time in 2 months

PullRequestReviewEvent

delete branch google/go-safeweb

delete branch : mihalimara22-xsrf-login

delete time in 2 months

delete branch google/go-safeweb

delete branch : grenfeldt-remove-plugin-keys

delete time in 2 months

issue openedgoogle/go-safeweb

Feature Request: Ban multiple configs for the same interceptor.

Currently it is possible to send multiple different configs for the same Interceptor when calling ServeMux.Handle. This should be banned. Instead the method should probably panic if this occurs.

created time in 2 months

push eventgoogle/go-safeweb

Mattias Grenfeldt

commit sha 5c0f4324171d8b49da941eaf77cd9079359db5c0

Renamed ai to interceptor

view details

push time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

+// Copyright 2020 Google LLC+//+// Licensed under the Apache License, Version 2.0 (the "License");+// you may not use this file except in compliance with the License.+// You may obtain a copy of the License at+//+// 	https://www.apache.org/licenses/LICENSE-2.0+//+// Unless required by applicable law or agreed to in writing, software+// distributed under the License is distributed on an "AS IS" BASIS,+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+// See the License for the specific language governing permissions and+// limitations under the License.++package safehttp_test++import (+	"github.com/google/go-safeweb/safehttp"+	"github.com/google/safehtml"+	safetemplate "github.com/google/safehtml/template"+	"html/template"+	"math"+	"net/http"+	"strings"+	"testing"+)++func TestDefaultDispatcherValidResponse(t *testing.T) {+	tests := []struct {+		name        string+		write       func(w http.ResponseWriter) error+		wantStatus  safehttp.StatusCode+		wantHeaders map[string][]string+		wantBody    string+	}{+		{+			name: "Safe HTML Response",+			write: func(w http.ResponseWriter) error {+				d := &safehttp.DefaultDispatcher{}+				return d.Write(w, safehtml.HTMLEscaped("<h1>Hello World!</h1>"))+			},+			wantBody: "&lt;h1&gt;Hello World!&lt;/h1&gt;",+		},+		{+			name: "Safe HTML Template Response",+			write: func(w http.ResponseWriter) error {+				d := &safehttp.DefaultDispatcher{}+				return d.ExecuteTemplate(w, safetemplate.Must(safetemplate.New("name").Parse("<h1>{{ . }}</h1>")), "This is an actual heading, though.")+			},+			wantBody: "<h1>This is an actual heading, though.</h1>",+		},+		{+			name: "Valid JSON Response",+			write: func(w http.ResponseWriter) error {+				d := &safehttp.DefaultDispatcher{}+				data := struct {+					Field string `json:"field"`+				}{Field: "myField"}+				return d.WriteJSON(w, safehttp.JSONResponse{Data: data})+			},+			wantBody: `{"field":"myField"}`,+		},+	}+	for _, tt := range tests {+		t.Run(tt.name, func(t *testing.T) {+			b := &strings.Builder{}+			rw := newResponseRecorder(b)++			err := tt.write(rw)++			if err != nil {+				t.Errorf("tt.write(rw): got error %v, want nil", err)+			}++			if gotBody := b.String(); tt.wantBody != gotBody {+				t.Errorf("response body: got %q, want %q", gotBody, tt.wantBody)+			}+		})+	}+}++func TestDefaultDispatcherInvalidResponse(t *testing.T) {+	tests := []struct {+		name  string+		write func(w http.ResponseWriter) error+	}{+		{+			name: "Unsafe HTML Response",+			write: func(w http.ResponseWriter) error {+				d := &safehttp.DefaultDispatcher{}+				return d.Write(w, "<h1>Hello World!</h1>")+			},+		},+

Remove empty line

maramihali

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func TestResponseWriterWriteTwicePanic(t *testing.T) { 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>")) 			}, 		},+		{+			name: "Call WriteJSON twice",+			write: func(w *safehttp.ResponseWriter) {+				data := struct{ Field string }{Field: "myField"}+				jsonObj, err := json.Marshal(data)+				if err != nil {+					t.Fatalf("invalid json object")+				}+				w.WriteJSON(jsonObj)+				w.WriteJSON(jsonObj)+			},

When you use WriteJSON you send the actual struct, right? The dispatcher will marshal it for you so that isn't needed here. Now you are sending just a string.

maramihali

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func (w *ResponseWriter) Interceptor(key string) Interceptor { }  // Result TODO-type Result struct{}+type Result struct {+	err error+}

Is this field used anywhere? If it isn't, remove it for now.

maramihali

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func NotWritten() Result { 	return Result{} } -// Write TODO+// Write dispatches the response to the Dispatcher, setting the Content-Type to+// text/html; charset=utf-8 and response status to 200 OK if resp is a safe+// response. The Dispatcher will then write the response to the underlying+// Response Writer.+//+// TODO: replace panics with proper error handling when getting the response+// Content-Type or writing the response fails. func (w *ResponseWriter) Write(resp Response) Result {-	w.markWritten()+	ct, err := w.d.ContentType(resp)+	if err != nil {+		panic(err)+	}+	w.rw.WriteHeader(int(StatusOK))+	w.rw.Header().Set("Content-Type", ct)

You need to set the ct header before calling WriteHeader. The headers of the response are written when you call WriteHeader, so they must be modified first.

The underlying responsewriter will write a 200 OK response if WriteHeader was never called, so you can remove the call to WriteHeader. And if there is a error during w.d.Write which results in a panic then something else will try to write to the responsewriter and in that case it would be bad if the response code is already set.

So remove the call to WriteHeader here, in WriteJSON and in WriteTemplate.

maramihali

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

+// Copyright 2020 Google LLC+//+// Licensed under the Apache License, Version 2.0 (the "License");+// you may not use this file except in compliance with the License.+// You may obtain a copy of the License at+//+// 	https://www.apache.org/licenses/LICENSE-2.0+//+// Unless required by applicable law or agreed to in writing, software+// distributed under the License is distributed on an "AS IS" BASIS,+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+// See the License for the specific language governing permissions and+// limitations under the License.++package safehttp++import (+	"encoding/json"+	"errors"+	"github.com/google/safehtml"+	"github.com/google/safehtml/template"+	"net/http"+)++// DefaultDispatcher is responsible of writing the body of a response to an+// Response Writer if it's of a safe type.+type DefaultDispatcher struct{}++// ContentType returns the Content-Type of a safe respons if it's of a safe-type+// and a non-nil error otherwise.

and an error otherwise

maramihali

comment created time in 2 months

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

 func TestMuxHandlerReturnsNotWritten(t *testing.T) { 		t.Errorf(`response body got: %q want: ""`, got) 	} }++func TestMuxNilDispatcher(t *testing.T) {+	defer func() {+		if r := recover(); r == nil {+			t.Errorf(`mux.NewServeMux(nil): expected panic`)+		}+	}()+	_ = safehttp.NewServeMux(nil)

You can remove the _ =

maramihali

comment created time in 2 months

PullRequestReviewEvent

Pull request review commentgoogle/go-safeweb

Extended the Dispatcher interface to support writing JSON and retrieving the response Content-Type and created a safe default Dispatcher.

+// Copyright 2020 Google LLC+//+// Licensed under the Apache License, Version 2.0 (the "License");+// you may not use this file except in compliance with the License.+// You may obtain a copy of the License at+//+// 	https://www.apache.org/licenses/LICENSE-2.0+//+// Unless required by applicable law or agreed to in writing, software+// distributed under the License is distributed on an "AS IS" BASIS,+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+// See the License for the specific language governing permissions and+// limitations under the License.++package safehttp++import (+	"encoding/json"+	"errors"+	"github.com/google/safehtml"+	"github.com/google/safehtml/template"+	"net/http"+)++// DefaultDispatcher is responsible of writing the body of a response to an+// Response Writer if it's of a safe type.+type DefaultDispatcher struct{}++// ContentType returns the Content-Type of a safe respons if it's of a safe-type

response with an e

maramihali

comment created time in 2 months

more