Add SslSchema config setting.

Reject URL usernames on registration.

Reduce length of char variable name.
This commit is contained in:
Azareal 2019-11-04 21:55:52 +10:00
parent 0f75e96a2d
commit 142359ce11
13 changed files with 59 additions and 50 deletions

View File

@ -12,7 +12,7 @@ import (
func SendActivationEmail(username string, email string, token string) error {
schema := "http"
if Site.EnableSsl {
if Config.SslSchema {
schema += "s"
}
// TODO: Move these to the phrase system
@ -23,7 +23,7 @@ func SendActivationEmail(username string, email string, token string) error {
func SendValidationEmail(username string, email string, token string) error {
schema := "http"
if Site.EnableSsl {
if Config.SslSchema {
schema += "s"
}
r := func(body *string) func(name, val string) {

View File

@ -872,7 +872,7 @@ func parseMediaString(data string) (media MediaEmbed, ok bool) {
host = strings.Split(Site.URL, ":")[0]
// ?- Test this as I'm not sure it'll do what it should. If someone's running SSL on port 80 or non-SSL on port 443 then... Well... They're in far worse trouble than this...
port = Site.Port
if Site.EnableSsl {
if Config.SslSchema {
scheme = "https"
}
}

View File

@ -293,7 +293,7 @@ func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
// TODO: Add a config setting to disable this header
// TODO: Have this header cover more things
if Site.EnableSsl {
if Config.SslSchema {
w.Header().Set("Content-Security-Policy", "upgrade-insecure-requests")
}

View File

@ -62,7 +62,7 @@ type config struct {
SslPrivkey string
SslFullchain string
HashAlgo string // Defaults to bcrypt, and in the future, possibly something stronger
ConvoKey string
ConvoKey string
MaxRequestSizeStr string
MaxRequestSize int
@ -89,9 +89,9 @@ type config struct {
MinifyTemplates bool
BuildSlugs bool // TODO: Make this a setting?
PrimaryServer bool
ServerCount int
PostIPCutoff int
PrimaryServer bool
ServerCount int
PostIPCutoff int
LogPruneCutoff int
DisableLiveTopicList bool
@ -99,13 +99,14 @@ type config struct {
//LooseCSP bool
LooseHost bool
LoosePort bool
SslSchema bool // Pretend we're using SSL, might be useful if a reverse-proxy terminates SSL in-front of Gosora
DisableServerPush bool
EnableCDNPush bool
DisableNoavatarRange bool
DisableDefaultNoavatar bool
RefNoTrack bool
RefNoRef bool
RefNoRef bool
Noavatar string // ? - Move this into the settings table?
ItemsPerPage int // ? - Move this into the settings table?
@ -174,6 +175,9 @@ func ProcessConfig() (err error) {
Site.URL = strings.TrimSuffix(Site.URL, ":")
Site.URL = Site.URL + ":" + Site.Port
}
if Site.EnableSsl {
Config.SslSchema = Site.EnableSsl
}
if Config.DefaultPath == "" {
Config.DefaultPath = "/topics/"
}

View File

@ -808,7 +808,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// TODO: Abstract the redirect logic?
w.Header().Set("Connection", "close")
var s string
if c.Site.EnableSsl {
if c.Config.SslSchema {
s = "s"
}
var p string
@ -833,8 +833,8 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
// TODO: Cover more suspicious strings and at a lower layer than this
for _, char := range req.URL.Path {
if char != '&' && !(char > 44 && char < 58) && char != '=' && char != '?' && !(char > 64 && char < 91) && char != '\\' && char != '_' && !(char > 96 && char < 123) {
for _, ch := range req.URL.Path { //char
if ch != '&' && !(ch > 44 && ch < 58) && ch != '=' && ch != '?' && !(ch > 64 && ch < 91) && ch != '\\' && ch != '_' && !(ch > 96 && ch < 123) {
r.SuspiciousRequest(req,"Bad char in path")
break
}
@ -869,7 +869,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
h.Set("X-Frame-Options", "deny")
h.Set("X-XSS-Protection", "1; mode=block") // TODO: Remove when we add a CSP? CSP's are horrendously glitchy things, tread with caution before removing
h.Set("X-Content-Type-Options", "nosniff")
if c.Config.RefNoRef || !c.Site.EnableSsl {
if c.Config.RefNoRef || !c.Config.SslSchema {
h.Set("Referrer-Policy","no-referrer")
} else {
h.Set("Referrer-Policy","strict-origin")

View File

@ -97,6 +97,7 @@
"register_need_username":"You didn't put in a username.",
"register_need_email":"You didn't put in an email.",
"register_first_word_numeric":"The first word of your name must not be purely numeric",
"register_url_username":"You cannot have a URL within your username",
"register_suspicious_email":"Your email address is suspicious.",
"register_password_mismatch":"The two passwords don't match.",
"register_username_unavailable":"This username isn't available. Try another.",

View File

@ -202,12 +202,12 @@ func TestParser(t *testing.T) {
l.Add("//"+url+"\n//"+url, eurl+"<br>"+eurl)
l.Add("//"+url+"\n\n//"+url, eurl+"<br><br>"+eurl)
pre2 := c.Site.EnableSsl
c.Site.EnableSsl = true
pre2 := c.Config.SslSchema
c.Config.SslSchema = true
local := func(u string) {
s := "//" + c.Site.URL
fs := "http://" + c.Site.URL
if c.Site.EnableSsl {
if c.Config.SslSchema {
s = "https:" + s
fs = "https://" + c.Site.URL
}
@ -301,13 +301,13 @@ func TestParser(t *testing.T) {
break
}
}
c.Site.EnableSsl = pre2
c.Config.SslSchema = pre2
l = &METriList{nil}
pre := c.Site.URL // Just in case this is localhost...
pre2 = c.Site.EnableSsl
pre2 = c.Config.SslSchema
c.Site.URL = "example.com"
c.Site.EnableSsl = true
c.Config.SslSchema = true
l.Add("//"+c.Site.URL, "<a href='https://"+c.Site.URL+"'>"+c.Site.URL+"</a>")
l.Add("//"+c.Site.URL+"\n", "<a href='https://"+c.Site.URL+"'>"+c.Site.URL+"</a><br>")
l.Add("//"+c.Site.URL+"\n//"+c.Site.URL, "<a href='https://"+c.Site.URL+"'>"+c.Site.URL+"</a><br><a href='https://"+c.Site.URL+"'>"+c.Site.URL+"</a>")
@ -323,7 +323,7 @@ func TestParser(t *testing.T) {
}
}
c.Site.URL = pre
c.Site.EnableSsl = pre2
c.Config.SslSchema = pre2
c.AddHashLinkType("nnid-", func(sb *strings.Builder, msg string, i *int) {
tid, intLen := c.CoerceIntString(msg[*i:])

View File

@ -531,7 +531,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// TODO: Abstract the redirect logic?
w.Header().Set("Connection", "close")
var s string
if c.Site.EnableSsl {
if c.Config.SslSchema {
s = "s"
}
var p string
@ -556,8 +556,8 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
// TODO: Cover more suspicious strings and at a lower layer than this
for _, char := range req.URL.Path {
if char != '&' && !(char > 44 && char < 58) && char != '=' && char != '?' && !(char > 64 && char < 91) && char != '\\' && char != '_' && !(char > 96 && char < 123) {
for _, ch := range req.URL.Path { //char
if ch != '&' && !(ch > 44 && ch < 58) && ch != '=' && ch != '?' && !(ch > 64 && ch < 91) && ch != '\\' && ch != '_' && !(ch > 96 && ch < 123) {
r.SuspiciousRequest(req,"Bad char in path")
break
}
@ -592,7 +592,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
h.Set("X-Frame-Options", "deny")
h.Set("X-XSS-Protection", "1; mode=block") // TODO: Remove when we add a CSP? CSP's are horrendously glitchy things, tread with caution before removing
h.Set("X-Content-Type-Options", "nosniff")
if c.Config.RefNoRef || !c.Site.EnableSsl {
if c.Config.RefNoRef || !c.Config.SslSchema {
h.Set("Referrer-Policy","no-referrer")
} else {
h.Set("Referrer-Policy","strict-origin")

View File

@ -235,6 +235,9 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
if isNumeric(nameBits[0]) {
regError(p.GetErrorPhrase("register_first_word_numeric"), "numeric-name")
}
if strings.Contains(name,"http://") || strings.Contains(name,"https://") || strings.Contains(name,"ftp://") || strings.Contains(name,"ssh://") {
regError(p.GetErrorPhrase("register_url_username"), "url-name")
}
// TODO: Add a dedicated function for validating emails
email := c.SanitiseSingleLine(r.PostFormValue("email"))
@ -807,12 +810,12 @@ func AccountPasswordResetSubmit(w http.ResponseWriter, r *http.Request, user c.U
return c.InternalError(err, w, r)
}
var schema string
if c.Site.EnableSsl {
schema = "s"
var s string
if c.Config.SslSchema {
s = "s"
}
err = c.SendEmail(tuser.Email, p.GetTmplPhrase("password_reset_subject"), p.GetTmplPhrasef("password_reset_body", tuser.Name, "http"+schema+"://"+c.Site.URL+"/accounts/password-reset/token/?uid="+strconv.Itoa(tuser.ID)+"&token="+token))
err = c.SendEmail(tuser.Email, p.GetTmplPhrase("password_reset_subject"), p.GetTmplPhrasef("password_reset_body", tuser.Name, "http"+s+"://"+c.Site.URL+"/accounts/password-reset/token/?uid="+strconv.Itoa(tuser.ID)+"&token="+token))
if err != nil {
return c.LocalError(p.GetErrorPhrase("password_reset_email_fail"), w, r, user)
}

View File

@ -33,13 +33,13 @@ func writeXMLHeader(w http.ResponseWriter, r *http.Request) {
// TODO: Keep track of when a sitemap was last modifed and add a lastmod element for it
func SitemapXml(w http.ResponseWriter, r *http.Request) c.RouteError {
var sslBit string
if c.Site.EnableSsl {
sslBit = "s"
var s string
if c.Config.SslSchema {
s = "s"
}
sitemapItem := func(path string) {
w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
<loc>http` + s + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap>
`))
}
@ -95,13 +95,13 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) c.RouteError {
}
func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
var sslBit string
if c.Site.EnableSsl {
sslBit = "s"
var s string
if c.Config.SslSchema {
s = "s"
}
sitemapItem := func(path string) {
w.Write([]byte(`<url>
<loc>http` + sslBit + `://` + c.Site.URL + path + `</loc>
<loc>http` + s + `://` + c.Site.URL + path + `</loc>
</url>
`))
}
@ -129,13 +129,13 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
// TODO: Add a global ratelimit. 10 50MB files (smaller if compressed better) per minute?
// ? We might have problems with banned users, if they have fewer ViewTopic permissions than guests as they'll be able to see this list. Then again, a banned user could just logout to see it
func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
var sslBit string
if c.Site.EnableSsl {
sslBit = "s"
var s string
if c.Config.SslSchema {
s = "s"
}
sitemapItem := func(path string) {
w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
<loc>http` + s + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap>
`))
}
@ -171,13 +171,13 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
}
func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) c.RouteError {
/*var sslBit string
if c.Site.EnableSsl {
sslBit = "s"
/*var s string
if c.Config.SslSchema {
s = "s"
}
var sitemapItem = func(path string) {
w.Write([]byte(`<url>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
<loc>http` + s + `://` + c.Site.URL + "/" + path + `</loc>
</url>
`))
}*/
@ -254,7 +254,7 @@ func APIMe(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
func OpenSearchXml(w http.ResponseWriter, r *http.Request) c.RouteError {
furl := "http"
if c.Site.EnableSsl {
if c.Config.SslSchema {
furl += "s"
}
furl += "://" + c.Site.URL

View File

@ -61,7 +61,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
} else {
return c.LocalError("Unknown section", w, r, user)
}
if originTable != "topics" && originTable != "replies" {
return c.LocalError("Unknown origin", w, r, user)
}
@ -74,10 +74,11 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
if ferr != nil {
return ferr
}
h := w.Header()
if guest.Perms.ViewTopic {
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
h.Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
} else {
w.Header().Set("Cache-Control", "private")
h.Set("Cache-Control", "private")
}
}

View File

@ -99,7 +99,7 @@ func renderTemplate2(tmplName string, hookName string, w http.ResponseWriter, r
func FootHeaders(w http.ResponseWriter, header *c.Header) {
if !header.LooseCSP {
if c.Site.EnableSsl {
if c.Config.SslSchema {
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com;upgrade-insecure-requests")
} else {
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com")

View File

@ -24,7 +24,7 @@ func successRedirect(dest string, w http.ResponseWriter, r *http.Request, js boo
// TODO: Prerender needs to handle dyntmpl templates better...
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError {
if !header.LooseCSP {
if c.Site.EnableSsl {
if c.Config.SslSchema {
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self';upgrade-insecure-requests")
} else {
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self'")