Added some pretty liberal limits on query length to make it more difficult to cause a DOS condition.

(the go http package by default limits the header length to 1 Megabyte, which is great at preventing someone from causing trpuble at the http layer, but doesn't work too well when there is a pretty expensive search going on in the background)
pull/20/head^2
Slatian 2022-11-24 20:29:39 +01:00 zatwierdzone przez Alexander Cobleigh
rodzic e21cc9a9d0
commit f41b7f87e7
3 zmienionych plików z 19 dodań i 16 usunięć

Wyświetl plik

@ -20,7 +20,7 @@
<form class="search"> <form class="search">
<label class="visually-hidden" for="search">Search {{ .SiteName }}</label> <label class="visually-hidden" for="search">Search {{ .SiteName }}</label>
<span class="search__input"> <span class="search__input">
<input type="search" required minlength="1" name="q" placeholder="{{ .Data.Placeholder }}" class="flex-grow" id="search"> <input type="search" required minlength="1" name="q" placeholder="{{ .Data.Placeholder }}" class="flex-grow" id="search" maxlength="6000" >
<button type="submit" class="search__button" aria-label="Search" title="Search"> <button type="submit" class="search__button" aria-label="Search" title="Search">
<svg viewBox="0 0 420 300" xmlns="http://www.w3.org/2000/svg" baseProfile="full" style="background:var(--secondary)" width="42" height="30" fill="none"><path d="M90 135q60-60 120-60 0 0 0 0 60 0 120 60m-120 60a60 60 0 01-60-60 60 60 0 0160-60 60 60 0 0160 60 60 60 0 01-60 60m45-15h0l30 30m-75-15h0v45m-45-60h0l-30 30" stroke-width="81" stroke-linecap="square" stroke-linejoin="round" stroke="var(--primary)"/></svg> <svg viewBox="0 0 420 300" xmlns="http://www.w3.org/2000/svg" baseProfile="full" style="background:var(--secondary)" width="42" height="30" fill="none"><path d="M90 135q60-60 120-60 0 0 0 0 60 0 120 60m-120 60a60 60 0 01-60-60 60 60 0 0160-60 60 60 0 0160 60 60 60 0 01-60 60m45-15h0l30 30m-75-15h0v45m-45-60h0l-30 30" stroke-width="81" stroke-linecap="square" stroke-linejoin="round" stroke="var(--primary)"/></svg>
</button> </button>

Wyświetl plik

@ -6,7 +6,7 @@
<form method="GET" class="search"> <form method="GET" class="search">
<label for="search">Search {{ .SiteName }} </label> <label for="search">Search {{ .SiteName }} </label>
<span class="search__input"> <span class="search__input">
<input type="search" minlength="1" required name="q" placeholder="Search" value="{{ .Data.Query }}" class="search-box" id="search"> <input type="search" minlength="1" required name="q" placeholder="Search" value="{{ .Data.Query }}" class="search-box" id="search" maxlength="6000">
{{ if ne .Data.Site "" }} {{ if ne .Data.Site "" }}
<input type="hidden" value="{{ .Data.Site }}" name="site"> <input type="hidden" value="{{ .Data.Site }}" name="site">
{{ end }} {{ end }}

Wyświetl plik

@ -70,7 +70,7 @@ func (h RequestHandler) searchRoute(res http.ResponseWriter, req *http.Request)
var langs = []string{} var langs = []string{}
var queryFields = []string{} var queryFields = []string{}
if req.Method == http.MethodGet { if req.Method == http.MethodGet{
params := req.URL.Query() params := req.URL.Query()
if words, exists := params["q"]; exists && words[0] != "" { if words, exists := params["q"]; exists && words[0] != "" {
query = words[0] query = words[0]
@ -86,24 +86,27 @@ func (h RequestHandler) searchRoute(res http.ResponseWriter, req *http.Request)
domains = append(domains, domain) domains = append(domains, domain)
} }
var newQueryFields []string; // don't process if there are too many fields
for _, word := range queryFields { if len(queryFields) <= 100 {
// This could be more efficient by splitting arrays, but I'm going with the more readable version for now var newQueryFields []string;
if strings.HasPrefix(word, "site:") { for _, word := range queryFields {
domains = append(domains, strings.TrimPrefix(word, "site:")) // This could be more efficient by splitting arrays, but I'm going with the more readable version for now
} else if strings.HasPrefix(word, "-site:") { if strings.HasPrefix(word, "site:") {
nodomains = append(nodomains, strings.TrimPrefix(word, "-site:")) domains = append(domains, strings.TrimPrefix(word, "site:"))
} else if strings.HasPrefix(word, "lang:") { } else if strings.HasPrefix(word, "-site:") {
langs = append(langs, strings.TrimPrefix(word, "lang:")) nodomains = append(nodomains, strings.TrimPrefix(word, "-site:"))
} else { } else if strings.HasPrefix(word, "lang:") {
newQueryFields = append(newQueryFields, word) langs = append(langs, strings.TrimPrefix(word, "lang:"))
} else {
newQueryFields = append(newQueryFields, word)
}
} }
queryFields = newQueryFields;
} }
queryFields = newQueryFields;
} }
if len(queryFields) == 0 { if len(queryFields) == 0 || len(queryFields) > 100 || len(query) >= 8192 {
view.Data = IndexData{Tagline: h.config.General.Tagline, Placeholder: h.config.General.Placeholder} view.Data = IndexData{Tagline: h.config.General.Tagline, Placeholder: h.config.General.Placeholder}
h.renderView(res, "index", view) h.renderView(res, "index", view)
return return