The router now redirects requests to localhost domains with localhost equivalents in the host header which don't quite match the destination to the proper domain.
The router now rejects host headers with the wrong port for non-standard ports. The www. redirect now handles non-standard ports properly. The Site.Port configuration setting is now validated on start-up to ensure it's a valid integer. Quickly fixed up the grammar of the Port block in configuration.md
This commit is contained in:
parent
c8a8de95ae
commit
9d321e9f23
|
@ -795,6 +795,7 @@ func parseMediaString(data string) (media MediaEmbed, ok bool) {
|
|||
port := url.Port()
|
||||
query := url.Query()
|
||||
|
||||
// TODO: Treat 127.0.0.1 and [::1] as localhost too
|
||||
var samesite = hostname == "localhost" || hostname == Site.URL
|
||||
if samesite {
|
||||
hostname = strings.Split(Site.URL, ":")[0]
|
||||
|
|
|
@ -27,7 +27,9 @@ type site struct {
|
|||
Email string
|
||||
URL string
|
||||
Host string
|
||||
LocalHost bool // Used internally, do not modify as it will be overwritten
|
||||
Port string
|
||||
PortInt int // Alias for efficiency, do not modify, will be overwritten
|
||||
EnableSsl bool
|
||||
EnableEmails bool
|
||||
HasProxy bool
|
||||
|
@ -81,6 +83,8 @@ type config struct {
|
|||
DefaultForum int // The forum posts go in by default, this used to be covered by the Uncategorised Forum, but we want to replace it with a more robust solution. Make this a setting?
|
||||
MinifyTemplates bool
|
||||
BuildSlugs bool // TODO: Make this a setting?
|
||||
|
||||
PrimaryServer bool
|
||||
ServerCount int
|
||||
|
||||
DisableLiveTopicList bool
|
||||
|
@ -140,7 +144,12 @@ func ProcessConfig() (err error) {
|
|||
Config.Noavatar = strings.Replace(Config.Noavatar, "{site_url}", Site.URL, -1)
|
||||
guestAvatar = GuestAvatar{buildNoavatar(0, 200), buildNoavatar(0, 48)}
|
||||
Site.Host = Site.URL
|
||||
if Site.Port != "80" && Site.Port != "443" {
|
||||
Site.LocalHost = Site.Host == "localhost" || Site.Host == "127.0.0.1" || Site.Host == "::1"
|
||||
Site.PortInt, err = strconv.Atoi(Site.Port)
|
||||
if err != nil {
|
||||
return errors.New("The port must be a valid integer")
|
||||
}
|
||||
if Site.PortInt != 80 && Site.PortInt != 443 {
|
||||
Site.URL = strings.TrimSuffix(Site.URL, "/")
|
||||
Site.URL = strings.TrimSuffix(Site.URL, "\\")
|
||||
Site.URL = strings.TrimSuffix(Site.URL, ":")
|
||||
|
|
|
@ -18,7 +18,7 @@ Email - The email address you want to show up in the From: field when Gosora sen
|
|||
|
||||
URL - The URL for your site. Please leave out the `http://` or `https://` and the `/` at the end.
|
||||
|
||||
Port - The port you want Gosora to listen on. This will usually be 443 for HTTPS and 80 for HTTP. Gosora usually try to bind to both, if you're on HTTPS to redirect users from the HTTP site to the HTTPS one.
|
||||
Port - The port you want Gosora to listen on. This will usually be 443 for HTTPS and 80 for HTTP. Gosora will try to bind to both, if you're on HTTPS to redirect users from the HTTP site to the HTTPS one.
|
||||
|
||||
EnableSsl - Determines whether HTTPS is enabled.
|
||||
|
||||
|
|
|
@ -696,19 +696,61 @@ func (r *GenRouter) SuspiciousRequest(req *http.Request, prepend string) {
|
|||
counters.AgentViewCounter.Bump(28)
|
||||
}
|
||||
|
||||
func isLocalHost(host string) bool {
|
||||
return host=="localhost" || host=="127.0.0.1" || host=="::1"
|
||||
}
|
||||
|
||||
// TODO: Pass the default path or config struct to the router rather than accessing it via a package global
|
||||
// TODO: SetDefaultPath
|
||||
// TODO: GetDefaultPath
|
||||
func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// Redirect www. requests to the right place
|
||||
if req.Host == "www." + common.Site.Host {
|
||||
var malformedRequest = func() {
|
||||
w.WriteHeader(200) // 400
|
||||
w.Write([]byte(""))
|
||||
r.DumpRequest(req,"Malformed Request")
|
||||
counters.AgentViewCounter.Bump(27)
|
||||
}
|
||||
|
||||
// Split the Host and Port string
|
||||
var shost, sport string
|
||||
if req.Host[0]=='[' {
|
||||
spl := strings.Split(req.Host,"]")
|
||||
if len(spl) > 2 {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
shost = strings.TrimPrefix(spl[0],"[")
|
||||
sport = strings.TrimPrefix(spl[1],":")
|
||||
} else {
|
||||
spl := strings.Split(req.Host,":")
|
||||
if len(spl) > 2 {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
shost = spl[0]
|
||||
if len(shost)==2 {
|
||||
sport = spl[1]
|
||||
}
|
||||
}
|
||||
// TODO: Reject requests from non-local IPs, if the site host is set to localhost or a localhost IP
|
||||
if common.Site.PortInt != 80 && common.Site.PortInt != 443 && sport != common.Site.Port {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
|
||||
// Redirect www. and local IP requests to the right place
|
||||
if shost == "www." + common.Site.Host || (common.Site.LocalHost && shost != common.Site.Host && isLocalHost(shost)) {
|
||||
// TODO: Abstract the redirect logic?
|
||||
w.Header().Set("Connection", "close")
|
||||
var s string
|
||||
if common.Site.EnableSsl {
|
||||
s = "s"
|
||||
}
|
||||
dest := "http"+s+"://" + common.Site.Host + req.URL.Path
|
||||
var p string
|
||||
if common.Site.PortInt != 80 && common.Site.PortInt != 443 {
|
||||
p = ":"+common.Site.Port
|
||||
}
|
||||
dest := "http"+s+"://" + common.Site.Host+p + req.URL.Path
|
||||
if len(req.URL.RawQuery) > 0 {
|
||||
dest += "?" + req.URL.RawQuery
|
||||
}
|
||||
|
@ -717,12 +759,8 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
// Deflect malformed requests
|
||||
shost := strings.Split(req.Host,":")
|
||||
if len(req.URL.Path) == 0 || req.URL.Path[0] != '/' || shost[0] != common.Site.Host || len(shost) > 2 {
|
||||
w.WriteHeader(200) // 400
|
||||
w.Write([]byte(""))
|
||||
r.DumpRequest(req,"Malformed Request")
|
||||
counters.AgentViewCounter.Bump(27)
|
||||
if len(req.URL.Path) == 0 || req.URL.Path[0] != '/' || shost != common.Site.Host {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
if common.Dev.FullReqLog {
|
||||
|
|
|
@ -475,19 +475,61 @@ func (r *GenRouter) SuspiciousRequest(req *http.Request, prepend string) {
|
|||
counters.AgentViewCounter.Bump({{.AllAgentMap.suspicious}})
|
||||
}
|
||||
|
||||
func isLocalHost(host string) bool {
|
||||
return host=="localhost" || host=="127.0.0.1" || host=="::1"
|
||||
}
|
||||
|
||||
// TODO: Pass the default path or config struct to the router rather than accessing it via a package global
|
||||
// TODO: SetDefaultPath
|
||||
// TODO: GetDefaultPath
|
||||
func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// Redirect www. requests to the right place
|
||||
if req.Host == "www." + common.Site.Host {
|
||||
var malformedRequest = func() {
|
||||
w.WriteHeader(200) // 400
|
||||
w.Write([]byte(""))
|
||||
r.DumpRequest(req,"Malformed Request")
|
||||
counters.AgentViewCounter.Bump({{.AllAgentMap.malformed}})
|
||||
}
|
||||
|
||||
// Split the Host and Port string
|
||||
var shost, sport string
|
||||
if req.Host[0]=='[' {
|
||||
spl := strings.Split(req.Host,"]")
|
||||
if len(spl) > 2 {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
shost = strings.TrimPrefix(spl[0],"[")
|
||||
sport = strings.TrimPrefix(spl[1],":")
|
||||
} else {
|
||||
spl := strings.Split(req.Host,":")
|
||||
if len(spl) > 2 {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
shost = spl[0]
|
||||
if len(shost)==2 {
|
||||
sport = spl[1]
|
||||
}
|
||||
}
|
||||
// TODO: Reject requests from non-local IPs, if the site host is set to localhost or a localhost IP
|
||||
if common.Site.PortInt != 80 && common.Site.PortInt != 443 && sport != common.Site.Port {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
|
||||
// Redirect www. and local IP requests to the right place
|
||||
if shost == "www." + common.Site.Host || (common.Site.LocalHost && shost != common.Site.Host && isLocalHost(shost)) {
|
||||
// TODO: Abstract the redirect logic?
|
||||
w.Header().Set("Connection", "close")
|
||||
var s string
|
||||
if common.Site.EnableSsl {
|
||||
s = "s"
|
||||
}
|
||||
dest := "http"+s+"://" + common.Site.Host + req.URL.Path
|
||||
var p string
|
||||
if common.Site.PortInt != 80 && common.Site.PortInt != 443 {
|
||||
p = ":"+common.Site.Port
|
||||
}
|
||||
dest := "http"+s+"://" + common.Site.Host+p + req.URL.Path
|
||||
if len(req.URL.RawQuery) > 0 {
|
||||
dest += "?" + req.URL.RawQuery
|
||||
}
|
||||
|
@ -496,12 +538,8 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
// Deflect malformed requests
|
||||
shost := strings.Split(req.Host,":")
|
||||
if len(req.URL.Path) == 0 || req.URL.Path[0] != '/' || shost[0] != common.Site.Host || len(shost) > 2 {
|
||||
w.WriteHeader(200) // 400
|
||||
w.Write([]byte(""))
|
||||
r.DumpRequest(req,"Malformed Request")
|
||||
counters.AgentViewCounter.Bump({{.AllAgentMap.malformed}})
|
||||
if len(req.URL.Path) == 0 || req.URL.Path[0] != '/' || shost != common.Site.Host {
|
||||
malformedRequest()
|
||||
return
|
||||
}
|
||||
if common.Dev.FullReqLog {
|
||||
|
|
Loading…
Reference in New Issue