Skip to content

Commit 664449a

Browse files
committed
add support for sanitizing multipart-file uploads
1 parent b65d4ac commit 664449a

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

doc/body.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package doc
22

33
import (
4+
"regexp"
45
"strings"
56
"text/template"
67
)
@@ -13,8 +14,16 @@ var (
1314
`
1415
)
1516

17+
var multipartBoundaryREStr = "^([-]+[a-zA-Z0-9]+)\nContent-Disposition.*"
18+
var multipartFileREStr = "(Content-Disposition: .*filename=.*\n?(?:Content-Type: .*))\n\n"
19+
20+
var multipartBoundaryRE, multipartFileRE *regexp.Regexp
21+
1622
func init() {
1723
bodyTmpl = template.Must(template.New("body").Parse(bodyFmt))
24+
25+
multipartBoundaryRE = regexp.MustCompile(multipartBoundaryREStr)
26+
multipartFileRE = regexp.MustCompile(multipartFileREStr)
1827
}
1928

2029
type Body struct {
@@ -41,6 +50,9 @@ func (b *Body) FormattedStr() string {
4150
if strings.HasPrefix(b.ContentType, "application/json") {
4251
return b.FormattedJSON()
4352
}
53+
if strings.HasPrefix(b.ContentType, "multipart/form-data") {
54+
return b.SanitizedMultipartForm()
55+
}
4456
return string(b.Content)
4557
}
4658

@@ -52,3 +64,23 @@ func (b *Body) FormattedJSON() string {
5264

5365
return fbody
5466
}
67+
68+
func (b *Body) SanitizedMultipartForm() string {
69+
bodyStr := string(b.Content)
70+
matches := multipartBoundaryRE.FindStringSubmatch(bodyStr)
71+
if len(matches) < 2 {
72+
// Fail, just return full body
73+
return string(b.Content)
74+
}
75+
boundary := matches[1]
76+
parts := strings.Split(bodyStr, boundary+"\n")
77+
78+
for i, p := range parts {
79+
fileMatches := multipartFileRE.FindStringSubmatch(p)
80+
if len(fileMatches) > 0 {
81+
parts[i] = fileMatches[0] + "<FILE DATA>\n\n"
82+
}
83+
}
84+
85+
return strings.Join(parts, boundary+"\n") + boundary + "--"
86+
}

0 commit comments

Comments
 (0)