Skip to content

Commit

Permalink
change
Browse files Browse the repository at this point in the history
  • Loading branch information
3JoB committed Aug 26, 2023
1 parent 2b51efa commit e191699
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 140 deletions.
64 changes: 36 additions & 28 deletions analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@ package teler
import (
"errors"
"fmt"
"net/http"
"net/url"
"strings"

"github.com/grafana/regexp"
"github.com/savsgio/atreugo/v11"
"go.uber.org/zap/zapcore"
"golang.org/x/net/publicsuffix"

"github.com/3JoB/teler-waf/request"
"github.com/3JoB/teler-waf/threat"
"github.com/3JoB/unsafeConvert"
)

// Analyze runs the actual checks.
func (t *Teler) Analyze(w http.ResponseWriter, r *http.Request) error {
_, err := t.analyzeRequest(w, r)
func (t *Teler) Analyze(c *atreugo.RequestCtx) error {
_, err := t.analyzeRequest(c)

// If threat detected, set teler request ID to the header
if err != nil {
setReqIdHeader(w)
setReqIdHeader(c)
}

return err
Expand Down Expand Up @@ -56,14 +57,14 @@ The types of threats that are checked for are:
- Bad crawlers
- Directory bruteforce attacks
*/
func (t *Teler) analyzeRequest(w http.ResponseWriter, r *http.Request) (threat.Threat, error) {
func (t *Teler) analyzeRequest(c *atreugo.RequestCtx) (threat.Threat, error) {
var err error

// Initialize DSL requests environment
t.setDSLRequestEnv(r)
t.setDSLRequestEnv(c)

// Check the request against custom rules
if err = t.checkCustomRules(r); err != nil {
if err = t.checkCustomRules(c); err != nil {
return threat.Custom, err
}

Expand All @@ -83,17 +84,17 @@ func (t *Teler) analyzeRequest(w http.ResponseWriter, r *http.Request) (threat.T
// Check for the threat type specified by the key in the excludes map
switch k {
case threat.CommonWebAttack:
err = t.checkCommonWebAttack(r) // Check for common web attacks
err = t.checkCommonWebAttack(c) // Check for common web attacks
case threat.CVE:
err = t.checkCVE(r) // Check for Common Vulnerabilities and Exposures (CVEs)
err = t.checkCVE(c) // Check for Common Vulnerabilities and Exposures (CVEs)
case threat.BadIPAddress:
err = t.checkBadIPAddress(r) // Check for bad IP addresses
err = t.checkBadIPAddress() // Check for bad IP addresses
case threat.BadReferrer:
err = t.checkBadReferrer(r) // Check for bad referrers
err = t.checkBadReferrer(c) // Check for bad referrers
case threat.BadCrawler:
err = t.checkBadCrawler(r) // Check for bad crawlers
err = t.checkBadCrawler(c) // Check for bad crawlers
case threat.DirectoryBruteforce:
err = t.checkDirectoryBruteforce(r) // Check for directory bruteforce attacks
err = t.checkDirectoryBruteforce(c) // Check for directory bruteforce attacks
}

// If a threat is detected, return the threat type and an error
Expand All @@ -109,7 +110,7 @@ func (t *Teler) analyzeRequest(w http.ResponseWriter, r *http.Request) (threat.T
// checkCustomRules checks the given http.Request against a set of custom rules defined in the Teler struct.
// If any of the custom rules are violated, the function returns an error with the name of the violated rule as the message.
// If no custom rules are violated, the function returns nil.
func (t *Teler) checkCustomRules(r *http.Request) error {
func (t *Teler) checkCustomRules(c *atreugo.RequestCtx) error {
// Declare headers, URI, and body of a request.
headers := t.env.GetRequestValue("Headers")
uri := t.env.GetRequestValue("URI")
Expand Down Expand Up @@ -146,7 +147,7 @@ func (t *Teler) checkCustomRules(r *http.Request) error {
switch {
case cond.Method == request.ALL:
ok = true
case string(cond.Method) == r.Method:
case string(cond.Method) == unsafeConvert.StringSlice(c.Method()):
ok = true
}

Expand Down Expand Up @@ -206,10 +207,10 @@ func (t *Teler) checkCustomRules(r *http.Request) error {
// checkCommonWebAttack checks if the request contains any patterns that match the common web attacks data.
// If a match is found, it returns an error indicating a common web attack has been detected.
// If no match is found, it returns nil.
func (t *Teler) checkCommonWebAttack(r *http.Request) error {
func (t *Teler) checkCommonWebAttack(c *atreugo.RequestCtx) error {
// Decode the URL-encoded and unescape HTML entities in the
// request URI of the URL then remove all special characters
uri := removeSpecialChars(stringDeUnescape(r.URL.RequestURI()))
uri := removeSpecialChars(stringDeUnescape(unsafeConvert.StringSlice(c.URI().FullURI())))

// Declare body of request then remove all special characters
body := removeSpecialChars(t.env.GetRequestValue("Body"))
Expand Down Expand Up @@ -260,7 +261,7 @@ func (t *Teler) checkCommonWebAttack(r *http.Request) error {
// Common Vulnerabilities and Exposures (CVE) threat.
// It takes a pointer to an HTTP request as an input and returns an error if the request
// matches a known threat. Otherwise, it returns nil.
func (t *Teler) checkCVE(r *http.Request) error {
func (t *Teler) checkCVE(c *atreugo.RequestCtx) error {
// data is the set of templates to check against.
cveData := t.threat.cve

Expand All @@ -270,7 +271,12 @@ func (t *Teler) checkCVE(r *http.Request) error {
// requestParams is a map that stores the query parameters of the request URI and
// iterate over the query parameters of the request URI and add them to the map.
requestParams := make(map[string]string)
for q, v := range r.URL.Query() {

prul, err := url.Parse(unsafeConvert.StringSlice(c.URI().FullURI()))
if err != nil {
return err
}
for q, v := range prul.Query() {
requestParams[q] = v[0]
}

Expand Down Expand Up @@ -303,7 +309,7 @@ func (t *Teler) checkCVE(r *http.Request) error {
}

// If the template is a "path" type and the request method doesn't match, skip this template.
if kind == "path" && string(request.GetStringBytes("method")) != r.Method {
if kind == "path" && unsafeConvert.StringSlice(request.GetStringBytes("method")) != unsafeConvert.StringSlice(c.Method()) {
continue
}

Expand All @@ -315,7 +321,8 @@ func (t *Teler) checkCVE(r *http.Request) error {
}

// If the request path doesn't match the CVE path, skip this CVE URL.
if r.URL.Path != cve.Path {

if unsafeConvert.StringSlice(c.URI().Path()) != cve.Path {
continue
}

Expand Down Expand Up @@ -358,7 +365,7 @@ func (t *Teler) checkCVE(r *http.Request) error {
// checkBadIPAddress checks if the client IP address is in the BadIPAddress index.
// It returns an error if the client IP address is found in the index, indicating a bad IP address.
// Otherwise, it returns nil.
func (t *Teler) checkBadIPAddress(r *http.Request) error {
func (t *Teler) checkBadIPAddress() error {
// Get the client's IP address
clientIP := t.env.GetRequestValue("IP")

Expand Down Expand Up @@ -395,9 +402,10 @@ func (t *Teler) checkBadIPAddress(r *http.Request) error {
// The resulting domain is then checked against the BadReferrer index in the threat struct.
// If the domain is found in the index, an error indicating a bad HTTP referer is returned.
// Otherwise, nil is returned.
func (t *Teler) checkBadReferrer(r *http.Request) error {
func (t *Teler) checkBadReferrer(c *atreugo.RequestCtx) error {
// Parse the request referer URL
ref, err := url.Parse(r.Referer())

ref, err := url.Parse(unsafeConvert.StringSlice(c.Referer()))
if err != nil {
t.error(zapcore.ErrorLevel, err.Error())
return nil
Expand Down Expand Up @@ -450,9 +458,9 @@ func (t *Teler) checkBadReferrer(r *http.Request) error {
// it returns an error with the message "bad crawler".
// If the User-Agent is empty or no regular expressions match,
// it returns nil.
func (t *Teler) checkBadCrawler(r *http.Request) error {
func (t *Teler) checkBadCrawler(c *atreugo.RequestCtx) error {
// Retrieve the User-Agent from the request
ua := r.UserAgent()
ua := unsafeConvert.StringSlice(c.UserAgent())

// Do not process the check if User-Agent is empty
if ua == "" {
Expand Down Expand Up @@ -504,10 +512,10 @@ func (t *Teler) checkBadCrawler(r *http.Request) error {
// is found, it returns an error indicating a directory bruteforce attack has been
// detected. If no match is found or there was an error during the regex matching
// process, it returns nil.
func (t *Teler) checkDirectoryBruteforce(r *http.Request) error {
func (t *Teler) checkDirectoryBruteforce(c *atreugo.RequestCtx) error {
// Trim the leading slash from the request path, and if path
// is empty string after the trim, do not process the check
path := strings.TrimLeft(r.URL.Path, "/")
path := strings.TrimLeft(unsafeConvert.StringSlice(c.URI().Path()), "/")
if path == "" {
return nil
}
Expand Down
20 changes: 14 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,26 @@ module github.com/3JoB/teler-waf
go 1.21.0

require (
github.com/antonmedv/expr v1.12.7
github.com/3JoB/atreugo-realip v0.0.1
github.com/3JoB/unsafeConvert v1.5.0
github.com/3JoB/validator v0.0.1
github.com/antonmedv/expr v1.14.3
github.com/daniel-hutao/spinlock v0.1.0
github.com/dwisiswant0/clientip v0.3.0
github.com/go-playground/validator/v10 v10.14.0
github.com/goccy/go-json v0.10.2
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd
github.com/hashicorp/go-getter v1.7.2
github.com/klauspost/compress v1.16.7
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/projectdiscovery/mapcidr v1.1.2
github.com/samber/lo v1.38.1
github.com/savsgio/atreugo/v11 v11.10.1
github.com/stretchr/testify v1.8.2
github.com/twharmon/gouid v0.5.2
github.com/valyala/fastjson v1.6.3
github.com/valyala/fasttemplate v1.2.2
gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84
go.uber.org/zap v1.25.0
golang.org/x/net v0.12.0
golang.org/x/net v0.14.0
golang.org/x/text v0.12.0
gopkg.in/yaml.v3 v3.0.1
)
Expand All @@ -31,13 +33,16 @@ require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
cloud.google.com/go/storage v1.28.1 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/aws/aws-sdk-go v1.44.296 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fasthttp/router v1.4.20 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/goccy/go-reflect v1.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
Expand All @@ -58,14 +63,17 @@ require (
github.com/projectdiscovery/blackrock v0.0.1 // indirect
github.com/projectdiscovery/utils v0.0.32 // indirect
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.48.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.114.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
Expand Down
Loading

0 comments on commit e191699

Please sign in to comment.