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">
<label class="visually-hidden" for="search">Search {{ .SiteName }}</label>
<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">
<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>

Wyświetl plik

@ -6,7 +6,7 @@
<form method="GET" class="search">
<label for="search">Search {{ .SiteName }} </label>
<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 "" }}
<input type="hidden" value="{{ .Data.Site }}" name="site">
{{ end }}

Wyświetl plik

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