mirror of
https://github.com/muraenateam/muraena.git
synced 2026-01-23 10:25:35 +00:00
Fix #65
Due to backward compatibility to Go 1, it won't be possible to avoid net.url to sort query strings. Therefore, a custom core/url.go was introduced for this purpose.
This commit is contained in:
parent
1bcc838924
commit
7f7cbc526a
2 changed files with 98 additions and 11 deletions
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
"github.com/evilsocket/islazy/tui"
|
||||
. "github.com/logrusorgru/aurora"
|
||||
"github.com/muraenateam/muraena/core"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/muraenateam/muraena/core/db"
|
||||
|
|
@ -147,8 +148,8 @@ func (muraena *MuraenaProxy) RequestProcessor(request *http.Request) (err error)
|
|||
//
|
||||
// HEADERS
|
||||
//
|
||||
// Transform query string
|
||||
query, err := url.ParseQuery(request.URL.RawQuery)
|
||||
// Transform query string using internal core.url instead of net.url
|
||||
query, err := core.ParseQuery(request.URL.RawQuery)
|
||||
if err != nil {
|
||||
log.Error("URL: %s \n %s", request.URL, err.Error())
|
||||
}
|
||||
|
|
@ -159,15 +160,6 @@ func (muraena *MuraenaProxy) RequestProcessor(request *http.Request) (err error)
|
|||
}
|
||||
}
|
||||
|
||||
// FIX #65. If the query string ends with a key without value, such as: victim.com/a?test
|
||||
// the query.Encode() automatically adds an equal sign at the end it i.e. victim.com/a?test=
|
||||
realLast := request.URL.RawQuery[len(request.URL.RawQuery)-1:]
|
||||
request.URL.RawQuery = query.Encode()
|
||||
newLast := request.URL.RawQuery[len(request.URL.RawQuery)-1:]
|
||||
if newLast == "=" && realLast != "=" {
|
||||
request.URL.RawQuery = strings.TrimSuffix(request.URL.RawQuery, "=")
|
||||
}
|
||||
|
||||
// Remove headers
|
||||
for _, header := range sess.Config.Remove.Request.Headers {
|
||||
request.Header.Del(header)
|
||||
|
|
|
|||
95
core/url.go
Normal file
95
core/url.go
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Values maps a string key to a list of values.
|
||||
// It is typically used for query parameters and form values.
|
||||
// Unlike in the http.Header map, the keys in a Values map
|
||||
// are case-sensitive.
|
||||
type Values map[string][]string
|
||||
|
||||
// ParseQuery parses the URL-encoded query string and returns
|
||||
// a map listing the values specified for each key.
|
||||
// ParseQuery always returns a non-nil map containing all the
|
||||
// valid query parameters found; err describes the first decoding error
|
||||
// encountered, if any.
|
||||
//
|
||||
// Query is expected to be a list of key=value settings separated by ampersands.
|
||||
// A setting without an equals sign is interpreted as a key set to an empty
|
||||
// value.
|
||||
// Settings containing a non-URL-encoded semicolon are considered invalid.
|
||||
func ParseQuery(query string) (Values, error) {
|
||||
m := make(Values)
|
||||
err := parseQuery(m, query)
|
||||
return m, err
|
||||
}
|
||||
|
||||
func parseQuery(m Values, query string) (err error) {
|
||||
for query != "" {
|
||||
key := query
|
||||
if i := strings.IndexAny(key, "&"); i >= 0 {
|
||||
key, query = key[:i], key[i+1:]
|
||||
} else {
|
||||
query = ""
|
||||
}
|
||||
//if strings.Contains(key, ";") {
|
||||
// err = fmt.Errorf("invalid semicolon separator in query")
|
||||
// continue
|
||||
//}
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
value := ""
|
||||
if i := strings.Index(key, "="); i >= 0 {
|
||||
key, value = key[:i], key[i+1:]
|
||||
}
|
||||
key, err1 := url.QueryUnescape(key)
|
||||
if err1 != nil {
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
continue
|
||||
}
|
||||
value, err1 = url.QueryUnescape(value)
|
||||
if err1 != nil {
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
continue
|
||||
}
|
||||
m[key] = append(m[key], value)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Encode encodes the values into ``URL encoded'' form
|
||||
// ("bar=baz&foo=quux") NOT sorted by key.
|
||||
func (v Values) Encode() string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
var buf strings.Builder
|
||||
keys := make([]string, 0, len(v))
|
||||
for k := range v {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
// We don't want to be sorted
|
||||
// sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vs := v[k]
|
||||
keyEscaped := url.QueryEscape(k)
|
||||
for _, v := range vs {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(keyEscaped)
|
||||
buf.WriteByte('=')
|
||||
buf.WriteString(url.QueryEscape(v))
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue