Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ directory you can supply `./...` as the input argument.
- G111: Potential directory traversal
- G112: Potential slowloris attack
- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772)
- G114: Use of net/http serve function that has no support for setting timeouts
- G201: SQL query construction using format string
- G202: SQL query construction using string concatenation
- G203: Use of unescaped data in HTML templates
Expand Down
38 changes: 38 additions & 0 deletions rules/http_serve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package rules

import (
"go/ast"

"github.com/securego/gosec/v2"
)

type httpServeWithoutTimeouts struct {
gosec.MetaData
pkg string
calls []string
}

func (r *httpServeWithoutTimeouts) ID() string {
return r.MetaData.ID
}

func (r *httpServeWithoutTimeouts) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err error) {
if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches {
return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil
}
return nil, nil
}

// NewHTTPServeWithoutTimeouts detects use of net/http serve functions that have no support for setting timeouts.
func NewHTTPServeWithoutTimeouts(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
return &httpServeWithoutTimeouts{
pkg: "net/http",
calls: []string{"ListenAndServe", "ListenAndServeTLS", "Serve", "ServeTLS"},
MetaData: gosec.MetaData{
ID: id,
What: "Use of net/http serve function that has no support for setting timeouts",
Severity: gosec.Medium,
Confidence: gosec.High,
},
}, []ast.Node{(*ast.CallExpr)(nil)}
}
1 change: 1 addition & 0 deletions rules/rulelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList {
{"G111", "Detect http.Dir('/') as a potential risk", NewDirectoryTraversal},
{"G112", "Detect ReadHeaderTimeout not configured as a potential risk", NewSlowloris},
{"G113", "Usage of Rat.SetString in math/big with an overflow", NewUsingOldMathBig},
{"G114", "Use of net/http serve function that has no support for setting timeouts", NewHTTPServeWithoutTimeouts},

// injection
{"G201", "SQL query construction using format string", NewSQLStrFormat},
Expand Down
4 changes: 4 additions & 0 deletions rules/rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ var _ = Describe("gosec rules", func() {
runner("G113", testutils.SampleCodeG113)
})

It("should detect uses of net/http serve functions that have no support for setting timeouts", func() {
runner("G114", testutils.SampleCodeG114)
})

It("should detect sql injection via format strings", func() {
runner("G201", testutils.SampleCodeG201)
})
Expand Down
78 changes: 78 additions & 0 deletions testutils/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,84 @@ func main() {
}, 1, gosec.NewConfig()},
}

// SampleCodeG114 - Use of net/http serve functions that have no support for setting timeouts
SampleCodeG114 = []CodeSample{
{[]string{
`
package main

import (
"log"
"net/http"
)

func main() {
err := http.ListenAndServe(":8080", nil)
log.Fatal(err)
}`,
}, 1, gosec.NewConfig()},
{
[]string{
`
package main

import (
"log"
"net/http"
)

func main() {
err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
log.Fatal(err)
}`,
}, 1, gosec.NewConfig(),
},
{
[]string{
`
package main

import (
"log"
"net"
"net/http"
)

func main() {
l, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
defer l.Close()
err = http.Serve(l, nil)
log.Fatal(err)
}`,
}, 1, gosec.NewConfig(),
},
{
[]string{
`
package main

import (
"log"
"net"
"net/http"
)

func main() {
l, err := net.Listen("tcp", ":8443")
if err != nil {
log.Fatal(err)
}
defer l.Close()
err = http.ServeTLS(l, nil, "cert.pem", "key.pem")
log.Fatal(err)
}`,
}, 1, gosec.NewConfig(),
},
}

// SampleCodeG201 - SQL injection via format string
SampleCodeG201 = []CodeSample{
{[]string{`
Expand Down