Problem with net/http(SOLVED)

I find this works as expected

“http.HandleFunc(”/@",startHandler)"

However if I replace the ‘@’ with ‘#’ I get a directory listing of the server account.

Just a thought that this might be a security issue.

Very useful for some no doubt.

Browsers don’t submit # and anything after it to the server. How your server then handles / is a routing detail of you.

There is no security issue involved at gos side.

Thanks for your response.

My clients is Firefox 68.5.0 ESR. The web page displays and then sends a websocket response to the server as is normal with websockets. I happened to send a ‘/’#’ and was surprised to get a directory listing displayed by firefox. It was done internally by net/http and was never touched by my handler which sets up the server end of the websocket.

This is clearly a backdoor. A hacker can easily spoof a browser and get a directory listing of my server which I regard as undesireable. The less a hacker knows about my host the better.

Rgds Bill

Again, you do not send /#, the browser wont sent “anchors”. The browser sends /, its up to your server, your reverse proxy and other parts how the react on this.

Your /# handler won’t be fired by /.

Websockets are not related to this.

With respect if a hacket can get a directory listing of a server based on go net/http, then it is a security hole.

It is not sufficient to rely on client protocol to never send a certain string. A hacker sending a forbidden string should not be rewarded with a directory listing from the server end. Those maintaining net/http should look into it as other sequences may be handled more maliceously.

I am well aware of how http routing works. I was using ‘/start’ to initiate websocket communication and decided to try ‘/#’. As I said ‘/@’ works fine for my porposes.

I do not think that the way net/http handles ‘/#’ is satisfactory.

Set your handler to /@ and send request /, do you see an index?

Please also provide a sscce that we can compile and run locally to verify your observations.

I owe you an apology as this was occuring during redirect from http to https, rather than websocket startup so maybe there is no security hole. Still it should not happen.

The following code snippet may help you reproduce the problem:

fune redirectToHttps(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, “https://xxxxxxxxxxxx.com:”+cfg.PortS+"/#", 307) // temporary for testing
}

Please show sscce, I doubt this is a golang problem, but related to your reverse proxy setup…

A bit more code

func main(){
go func (){
http.HandleFunc("/#",startHandler)
var err error
err=http.ListenAndServeTLS(":"+cfg.PortS,“chain.pem”,“key.pem”,nil)
time.Sleep(75*time.Millisecond)
if err!=nil{ml.LogFail(fmt.Sprint(err)) }
ml.Log(“HTTPS server has shutdown”)
os.Exit(2)
}()

go func (){
    http.ListenAndServe(":"+cfg.Port, http.HandlerFunc(redirectToHttps))
    ml.Log("MIPS HTTP server has shutdown")}()

}

fune redirectToHttps(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, “https://xxxxxxxxxxxx.com:”+cfg.PortS+"/#", 307) // temporary for testing
}

Hope this helps

Bill

That is not a sscce.

1 Like

For me, this works as expected and go serves a 404:

package main

import (
	"net/http"
)

func main() {
	http.HandleFunc("/#", f)
	err := http.ListenAndServe(":8080", nil)
	panic(err)
}

func f(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "http://example.com/", 307)
}
$ curl localhost:8080/#
404 page not found

If you can reproduce your problem based on this snippet, please report back.

1 Like

The problem occurs when I redirect to https and unless you have certificate and keys, you may not be able to test it…

I can easily selfsign for local testing.

Thanks for your help.

You were correct, the # was being ignored and so a ‘/’ was passed to the handlers.

This was processed by the http.FileSrver which was serving CSS files from serverRoot/css and favicon from serverRoot. Best to put them in a public directory.

So the fileServer should be started as:

fileServer:=http.FileServer(http.Dir("./public"))
http.Handle("/",fileServer)

So net/http was doing exactly what I asked it to do.

Thanks for your help and patience

Bill

1 Like