Code Monkey home page Code Monkey logo

xss-mw's Introduction

Xss Middleware

XssMw is an middleware written in Golang for the Gin web framework. Although, it should be useable with any Go web framework which utilizes Golang's "net/http" native library in a similiar way to Gin.

The idea behind XssMw is to "auto remove XSS" from user submitted input.

It's applied on http GET, POST and PUT Requests only

The XSS filtering is performed by HTML sanitizer Bluemonday.

The default is to the strictest policy - StrictPolicy()

How To Use it?

Using the defaults, It will skip filtering for a field named 'password' but will run the filter on everything else. Uses the Bluemonday strictest policy - StrictPolicy()

package main

import "gopkg.in/gin-gonic/gin.v1"
import "github.com/dvwright/xss-mw"

func main() {
    r := gin.Default()

    // include as standard middleware
    var xssMdlwr xss.XssMw
    r.Use(xssMdlwr.RemoveXss())

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

Using some config options, here It will skip filtering for a fields named 'password', "create_date" and "token" but will run the filter on everything else.

Uses Bluemonday UGCPolicy

package main

import "gopkg.in/gin-gonic/gin.v1"
import "github.com/dvwright/xss-mw"

func main() {
    r := gin.Default()

    xssMdlwr := &xss.XssMw{
            FieldsToSkip: []string{"password", "create_date", "token"},
            BmPolicy:     "UGCPolicy",
    }
    r.Use(xssMdlwr.RemoveXss())

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

Data

Currently, it removes (deletes) all HTML and malicious detected input from user input on

the submitted request to the server.

It handles three Request types:

  • JSON requests - Content-Type application/json

  • Form Encoded - Content-Type application/x-www-form-urlencoded

  • Multipart Form Data - Content-Type multipart/form-data

A future plan is have a feature to store all user submitted data intact and have the option to

filter it out on the http Response, so you can choose your preference. - in other words - data would be stored in the database as it was submitted and removed in Responses back to the user. pros: data integrity, cons: XSS exploits still present

NOTE: This is Beta level code with minimal actual real world usage

Contributing

You are welcome to contribute to this project.

Please update/add tests as appropriate.

Send pull request against the Develop branch.

Please use the same formatting as the Go authors. Run code through gofmt before submitting.

Thanks

Misc

Thanks to

https://github.com/goware/jsonp

https://github.com/appleboy/gin-jwt/tree/v2.1.1

Whose source I read throughly to aid in writing this

and of course

https://github.com/microcosm-cc/bluemonday

and the gin middleware

and

https://static.googleusercontent.com/intl/hu/about/appsecurity/learning/xss/

for inspiring me to to look for and not finding a framework, so attempting to write one.

A note on manually escaping input Writing your own code for escaping input and then properly and consistently applying it is extremely difficult. We do not recommend that you manually escape user-supplied data. Instead, we strongly recommend that you use a templating system or web development framework that provides context-aware auto-escaping.

xss-mw's People

Contributors

bonedaddy avatar dvwright avatar jefferywang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

xss-mw's Issues

Remove test for multi-part form request

Hello!

In the line of code referenced you ask if that section of code is needed. I would say no.

xss-mw/xss.go

Line 376 in 7a0dab8

// XXX needed?

I am supporting a legacy application which sends data using a multi-part form. When it finishes sending, it sends a final request without any data, just form fields. I don't have access to the source, but I assume it's done in some sort of loop and when it runs out of data to send, it sends a field to indicate that no more data is coming but doesn't change the way it formats the request. This causes the application to fail as it doesn't get the response it expects.

So, I would say that it should be removed, or at least a flag to enable ignoring empty multi-part data.

Thanks!

Panic Error: bytes.Buffer: truncation out of range

Running a web service scan using acunetix, and the following panic occurred, let me know if there's any other information i can provide

ESC[31m2019/01/03 23:21:03 [Recovery] 2019/01/03 - 23:21:03 panic recovered:
POST /NmConsole/CoreNm/User/DlgUserLogin/DlgUserLogin.asp HTTP/1.1
Host: nuts.rtradetechnologies.com:6767
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Connection: Keep-Alive
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0


bytes.Buffer: truncation out of range
/usr/local/go/src/runtime/panic.go:513 (0x42d8c8)
        gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/usr/local/go/src/bytes/buffer.go:90 (0x11cf716)
        (*XssMw).HandleXFormEncoded: panic("bytes.Buffer: truncation out of range")
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/dvwright/xss-mw/xss.go:269 (0x11cf716)
        (*XssMw).HandleXFormEncoded: bq.Truncate(bq.Len() - 1) // remove last '&'
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/dvwright/xss-mw/xss.go:194 (0x11cf000)
        (*XssMw).XssRemove: err := mw.HandleXFormEncoded(c)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/dvwright/xss-mw/xss.go:109 (0x11cec39)
        (*XssMw).callRemoveXss: err := mw.XssRemove(c)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/dvwright/xss-mw/xss.go:90 (0x11d2083)
        (*XssMw).RemoveXss.func1: mw.callRemoveXss(c)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/context.go:109 (0x11b0262)
        (*Context).Next: c.handlers[c.index](c)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/zsais/go-gin-prometheus/middleware.go:364 (0x1237f4e)
        (*Prometheus).HandlerFunc.func1: c.Next()
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/context.go:109 (0x11b0262)
        (*Context).Next: c.handlers[c.index](c)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/recovery.go:76 (0x11c2949)
        RecoveryWithWriter.func1: c.Next()
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/context.go:109 (0x11b0262)
        (*Context).Next: c.handlers[c.index](c)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/logger.go:84 (0x11c1681)
        LoggerWithWriter.func1: c.Next()
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/context.go:109 (0x11b0262)
        (*Context).Next: c.handlers[c.index](c)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/gin.go:419 (0x11b9657)
        serveError: c.Next()
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/gin.go:412 (0x11b938b)
        (*Engine).handleHTTPRequest: serveError(c, http.StatusNotFound, default404Body)
/home/rtrade/go/src/github.com/RTradeLtd/Temporal/vendor/github.com/gin-gonic/gin/gin.go:349 (0x11b8e01)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2741 (0x6d9c1a)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1847 (0x6d5e15)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_amd64.s:1333 (0x45b860)
        goexit: BYTE    $0x90   // NOP
ESC[0m

json array got truncated

request body(with application/json content-type header):

{
   "corp_ids": ["id1"]
}

after xss-mw, body becomes:

{"corp_ids":]}

which is mal-formed

remove array

when request have array ,it is remove array and put only ]

Enforce Validation on any request type

Hey there ,
Thank you for providing this middleware , it's a blessing since i don't have to have to manually do it now. I forked it and modified abit for a project i'm working on .

I would only recommend that for the validation to not rely on the front end headers for the content type. as alot of times those aren't provided and as a result your validation logic will not work.

in this code block , theoretically we should just enforce validation on all 3 types of request types and headers types.

if ctLen > 1 && ctHdr == "application/json" {
			err := mw.HandleJson(c)
			if err != nil {
				return err
			}
		} else if ctHdr == "application/x-www-form-urlencoded" {
			err := mw.HandleXFormEncoded(c)
			if err != nil {
				return err
			}
		} else if strings.Contains(ctHdr, "multipart/form-data") {
			err := mw.HandleMultiPartFormData(c, ctHdr)
			if err != nil {
				return err
			}
		}

or an alternative solution if you think that makes it not elegant , is to enforce it route level , where we can specify which request typeValidator to use ie would look like this kind of.

var xssMdlwr middleware.XssMw
router.POST("",xssMdlwr.HeaderType('application/json'),controller.SomePostFunc)

this way we don't have to rely on the client passed header type.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.