Skip to content

Commit

Permalink
Merge pull request #3 from dvwright/support_nested_json_cont
Browse files Browse the repository at this point in the history
make nested work
  • Loading branch information
dvwright committed Oct 28, 2018
2 parents c478415 + 6c153c0 commit 75189b7
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 140 deletions.
131 changes: 46 additions & 85 deletions xss.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import (
"io/ioutil"
"mime/multipart"
"net/url"
"reflect" // debugging type
//"reflect" // debugging type
"strconv"
"strings"
)
Expand Down Expand Up @@ -421,6 +421,9 @@ func (mw *XssMw) HandleJson(c *gin.Context) error {
if err != nil {
return err
}
//fmt.Println("DONE JSON")
//fmt.Println(buff.String())

err = mw.SetRequestBodyJson(c, buff)
if err != nil {
//fmt.Println("Set request body failed")
Expand All @@ -446,7 +449,8 @@ func (mw *XssMw) jsonToStringMap(buff bytes.Buffer, jsonBod interface{}) (bytes.
case map[string]interface{}:
//fmt.Printf("\n\n\n1st type\n\n\n")
xmj := jsonBod.(map[string]interface{})
buff := mw.ConstructJson(xmj)
var sbuff bytes.Buffer
buff := mw.ConstructJson(xmj, sbuff)
return buff, nil
// TODO: need a test to prove this
case []interface{}:
Expand All @@ -455,7 +459,8 @@ func (mw *XssMw) jsonToStringMap(buff bytes.Buffer, jsonBod interface{}) (bytes.
for _, n := range jbt {
//fmt.Printf("Item: %v= %v\n", i, n)
xmj := n.(map[string]interface{})
buff = mw.ConstructJson(xmj)
var sbuff bytes.Buffer
buff = mw.ConstructJson(xmj, sbuff)
multiRec.WriteString(buff.String())
multiRec.WriteByte(',')
}
Expand Down Expand Up @@ -499,18 +504,14 @@ func (mw *XssMw) SetRequestBodyJson(c *gin.Context, buff bytes.Buffer) error {
// keeps the good content to construct
// returns the cleaned http request
// Map to Bytes (struct to json string...)
func (mw *XssMw) ConstructJson(xmj XssMwJson) bytes.Buffer {
//fmt.Printf("JSON BOD: %#v\n", xmj)

var buff bytes.Buffer
func (mw *XssMw) ConstructJson(xmj XssMwJson, buff bytes.Buffer) bytes.Buffer {
//var buff bytes.Buffer
buff.WriteByte('{')

p := mw.GetBlueMondayPolicy()

m := xmj //m := jsonBod.(map[string]interface{})
m := xmj
for k, v := range m {
//fmt.Println(k, v)

buff.WriteByte('"')
buff.WriteString(k)
buff.WriteByte('"')
Expand Down Expand Up @@ -541,91 +542,51 @@ func (mw *XssMw) ConstructJson(xmj XssMwJson) bytes.Buffer {
return buff
}

func (mw *XssMw) buildJsonApplyPolicy(v interface{}, buff bytes.Buffer, p *bluemonday.Policy) bytes.Buffer {
switch vv := v.(type) { // FYI, JSON data is string or float
case string:
//fmt.Println(k, "is string", vv)
//buff.WriteString(`"` + p.Sanitize(vv) + `",`)
buff.WriteString(fmt.Sprintf("%q", p.Sanitize(vv)))
buff.WriteByte(',')
case float64:
//fmt.Println(k, "is float", vv)
//buff.WriteString(strconv.FormatFloat(vv, 'g', 0, 64))
//buff.WriteString(html.EscapeString(strconv.FormatFloat(vv, 'g', 0, 64)))
buff.WriteString(p.Sanitize(strconv.FormatFloat(vv, 'g', 0, 64)))
buff.WriteByte(',')
default:
var b bytes.Buffer
apndBuff := mw.reiterateInterface(v, b, p)
buff.WriteString(apndBuff.String())
}
return buff
}

func (mw *XssMw) reiterateInterfaceSlice(vvv []interface{}, buff bytes.Buffer, p *bluemonday.Policy) bytes.Buffer {
var lst bytes.Buffer
lst.WriteByte('[')
for i, n := range vvv {
fmt.Printf("Iter: %v= %v\n", i, n)
fmt.Println("I don't know how to handle")
var r = reflect.TypeOf(n)
fmt.Printf("Unknown Type!:%v\n", r)

//lst.WriteString(p.Sanitize(fmt.Sprintf("\"%v\"", n)))
// NOTE changes from ["1", "4", "8"] to [1,4,8]
lst.WriteString(p.Sanitize(fmt.Sprintf("%v", n)))
lst.WriteByte(',')
}
lst.Truncate(lst.Len() - 1) // remove last ','
lst.WriteByte(']')
return lst
}

func (mw *XssMw) reiterateInterface(vv interface{}, buff bytes.Buffer, p *bluemonday.Policy) bytes.Buffer {
switch vvv := vv.(type) {
// map[string]interface {}{"id":"1", "assoc_ids":[]interface {}{"1", "4", "8"}}
func (mw *XssMw) buildJsonApplyPolicy(interf interface{}, buff bytes.Buffer, p *bluemonday.Policy) bytes.Buffer {
switch v := interf.(type) {
case map[string]interface{}:

var sbuff bytes.Buffer
scnd := mw.ConstructJson(v, sbuff)
buff.WriteString(scnd.String())
buff.WriteByte(',')
case []interface{}:

var b bytes.Buffer
b = mw.reiterateInterfaceSlice(vvv, b, p)
b := mw.unravelSlice(v)
buff.WriteString(b.String())
buff.WriteByte(',') // add cause expected
buff.WriteByte(',')
case json.Number:
//fmt.Println(k, "is number", vv)
//buff.WriteString(`"` + p.Sanitize(vv) + `",`)
buff.WriteString(p.Sanitize(fmt.Sprintf("%v", vvv)))
buff.WriteString(p.Sanitize(fmt.Sprintf("%v", v)))
buff.WriteByte(',')
case string:
buff.WriteString(fmt.Sprintf("%q", p.Sanitize(v)))
buff.WriteByte(',')
case float64:
buff.WriteString(p.Sanitize(strconv.FormatFloat(v, 'g', 0, 64)))
buff.WriteByte(',')
default:
fmt.Println("I don't know how to handle")
var r = reflect.TypeOf(vvv)
fmt.Printf("Unknown Type!:%v\n", r)

if vvv == nil {
if v == nil {
buff.WriteString(fmt.Sprintf("%s", "null"))
buff.WriteByte(',')
} else {
buff.WriteString(p.Sanitize(fmt.Sprintf("%v", vvv)))
buff.WriteString(p.Sanitize(fmt.Sprintf("%v", v)))
buff.WriteByte(',')
}
buff.WriteByte(',')
}
return buff
}

// TODO
// add feature to accept all content in Request and filter out on Response
// NOTE: I don't know how to achieve this yet... will something like this help?
// gin help said call Next first to capture Response
//func ConstructRequest(next http.Handler) http.Handler {
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// fmt.Println(r.Method, "-", r.RequestURI)
// cookie, _ := r.Cookie("username")
// if cookie != nil {
// //Add data to context
// ctx := context.WithValue(r.Context(), "Username", cookie.Value)
// next.ServeHTTP(w, r.WithContext(ctx))
// } else {
// next.ServeHTTP(w, r)
// }
// })
//}
func (mw *XssMw) unravelSlice(slce []interface{}) bytes.Buffer {
var buff bytes.Buffer
buff.WriteByte('[')
for _, n := range slce {
switch nn := n.(type) {
case map[string]interface{}:
var sbuff bytes.Buffer
scnd := mw.ConstructJson(nn, sbuff)
buff.WriteString(scnd.String())
buff.WriteByte(',')
}
}
buff.Truncate(buff.Len() - 1) // remove last ','
buff.WriteByte(']')
return buff
}
Loading

0 comments on commit 75189b7

Please sign in to comment.