Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seeking information about redirecting HTTP to HTTPS #22

Closed
amankapoor opened this issue Sep 6, 2017 · 4 comments
Closed

Seeking information about redirecting HTTP to HTTPS #22

amankapoor opened this issue Sep 6, 2017 · 4 comments

Comments

@amankapoor
Copy link

Hi, I used your redirecting example and I am interested in knowing if it is SAFE to add more headers to secureMiddleware of your example or not? I am very new to security in Go. The thing is that your approach shows that we create one secureMiddleware and pass it to ListenAndServe go routine as well as ListenAndServeTLS.

What if, I do the same thing but add more header to that secureMiddleware? Is this a possibility that hackers somehow get to understand that we are redirected from http to https and therefore we can get into the http version of the server (because I am passing the main gorilla router to ListenAndServe). Does something like this happen?

And what about future links we visit on the site after first redirection? ListenAndServe was used only once when we typed url without https (I am on development right now). I still want to confirm as I am not sure.

Below is my current main function for your reference:

func main() {

	// HTTPS certificate files
	certPath := "server.pem"
	keyPath := "server.key"

	// secure middleware
	secureMiddleware := secure.New(secure.Options{
		AllowedHosts:         []string{"localhost"},
		HostsProxyHeaders:    []string{"X-Forwarded-Host"},
		SSLRedirect:          true,
		SSLHost:              "localhost:443",
		SSLProxyHeaders:      map[string]string{"X-Forwarded-Proto": "https"},
		STSSeconds:           63072000,
		STSIncludeSubdomains: true,
		STSPreload:           true,
		ForceSTSHeader:       false,
		FrameDeny:            true,
		ContentTypeNosniff:   true,
		BrowserXssFilter:     true,
		// I need to change it as Content-Security-Policy: default-src 'self' *.trusted.com if I want to load images from S3 bucket (See - https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
		// ContentSecurityPolicy: "default-src 'self'",
		PublicKey:      `pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubdomains; report-uri="https://www.example.com/hpkp-report"`,
		ReferrerPolicy: "same-origin",
		// IsDevelopment:         true,
	})

	// Setting up logging files in append mode
	common.SetupLogging()
	common.Log.Info("On line 35 certPath and keyPath")

	// Setting up mongodb
	mongodb, err := datastore.NewDatastore(datastore.MONGODB, "localhost:27017")
	if err != nil {
		common.Log.Warn(err.Error())
	}
	defer mongodb.Close()

	// Passing mongodb to environment variable
	env := common.Env{DB: mongodb}
	common.Log.Info("On line 44")

	// Router and routes
	r := mux.NewRouter()
	r.Handle("/", handlers.Handler{E: &env, H: handlers.Index}).Methods("GET")

	// Middleware and server
	commonMiddleware := handlers.RecoveryHandler(handlers.PrintRecoveryStack(true))(gh.CombinedLoggingHandler(common.TrafficLog, secureMiddleware.Handler(r)))
	common.Log.Info("On line 49")

	sTLS := &http.Server{
		Addr:           ":443",
		Handler:        commonMiddleware,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	common.Log.Info("Serving...")

	go func() {
		log.Fatal(http.ListenAndServe(":80", commonMiddleware))
	}()

	log.Fatal(sTLS.ListenAndServeTLS(certPath, keyPath))
}

Or, should we have one secureMiddleware and one redirectMiddleware; the redirectMiddleware will be exactly like the one in your HTTP to HTTPS redirection example in readme. And, pass this redirectMiddleware to ListenAndServe with the main router (in my case r).

Please clarify. And, if we can use same secureMiddleware then I would prefer we add comments stating something like "// you can have more headers here" in the secureMiddleware of redirection example.

@unrolled
Copy link
Owner

unrolled commented Sep 7, 2017

Hey @amankapoor, it's definitely safe to have a single middleware with all your additional options set. The http.ListenAndServe will always redirect to the HTTPS... check out the code in secure.go. The Process(w http.ResponseWriter, r *http.Request) function does the SSL check first and will exit early if the connection is NOT secure.

One suggestion I would make is to remove the SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"}, option from your implementation. That is used when nginx or a load balancer is in front of your app. But since you are setting up Go to handle the SSL termination, you won't need that line. This will also prevent outsiders from trying to include the X-Forwarded-Proto header in requests in an attempt to trick your app into thinking it is on a secure connection.

If you remove that one line, your implementation looks very close to what I use in production! Let me know if this helps!

@amankapoor
Copy link
Author

Hi, thank you very much for the information, it really helped. Also, I would like to share that I am new to deploying, and I want to deploy my small apps on one t2.micro. So my research taught me that I need a reverse proxy like nginx to do this job. Although I have not yet started using nginx because I am spending time writing the app, but I think if I will keep X-Forwarded-Proto header intact, then it won't harm.

@unrolled
Copy link
Owner

Sounds good! Should this issue be closed now?

@amankapoor
Copy link
Author

Yeah. Thank you for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants