Skip to content

Commit 0c8e63e

Browse files
authored
1 parent 6a26c23 commit 0c8e63e

File tree

5 files changed

+122
-0
lines changed

5 files changed

+122
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ directory you can supply `./...` as the input argument.
146146
- G111: Potential directory traversal
147147
- G112: Potential slowloris attack
148148
- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772)
149+
- G114: Use of net/http serve function that has no support for setting timeouts
149150
- G201: SQL query construction using format string
150151
- G202: SQL query construction using string concatenation
151152
- G203: Use of unescaped data in HTML templates

rules/http_serve.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package rules
2+
3+
import (
4+
"go/ast"
5+
6+
"github.com/securego/gosec/v2"
7+
)
8+
9+
type httpServeWithoutTimeouts struct {
10+
gosec.MetaData
11+
pkg string
12+
calls []string
13+
}
14+
15+
func (r *httpServeWithoutTimeouts) ID() string {
16+
return r.MetaData.ID
17+
}
18+
19+
func (r *httpServeWithoutTimeouts) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err error) {
20+
if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches {
21+
return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil
22+
}
23+
return nil, nil
24+
}
25+
26+
// NewHTTPServeWithoutTimeouts detects use of net/http serve functions that have no support for setting timeouts.
27+
func NewHTTPServeWithoutTimeouts(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
28+
return &httpServeWithoutTimeouts{
29+
pkg: "net/http",
30+
calls: []string{"ListenAndServe", "ListenAndServeTLS", "Serve", "ServeTLS"},
31+
MetaData: gosec.MetaData{
32+
ID: id,
33+
What: "Use of net/http serve function that has no support for setting timeouts",
34+
Severity: gosec.Medium,
35+
Confidence: gosec.High,
36+
},
37+
}, []ast.Node{(*ast.CallExpr)(nil)}
38+
}

rules/rulelist.go

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList {
7676
{"G111", "Detect http.Dir('/') as a potential risk", NewDirectoryTraversal},
7777
{"G112", "Detect ReadHeaderTimeout not configured as a potential risk", NewSlowloris},
7878
{"G113", "Usage of Rat.SetString in math/big with an overflow", NewUsingOldMathBig},
79+
{"G114", "Use of net/http serve function that has no support for setting timeouts", NewHTTPServeWithoutTimeouts},
7980

8081
// injection
8182
{"G201", "SQL query construction using format string", NewSQLStrFormat},

rules/rules_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ var _ = Describe("gosec rules", func() {
102102
runner("G113", testutils.SampleCodeG113)
103103
})
104104

105+
It("should detect uses of net/http serve functions that have no support for setting timeouts", func() {
106+
runner("G114", testutils.SampleCodeG114)
107+
})
108+
105109
It("should detect sql injection via format strings", func() {
106110
runner("G201", testutils.SampleCodeG201)
107111
})

testutils/source.go

+78
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,84 @@ func main() {
11101110
}, 1, gosec.NewConfig()},
11111111
}
11121112

1113+
// SampleCodeG114 - Use of net/http serve functions that have no support for setting timeouts
1114+
SampleCodeG114 = []CodeSample{
1115+
{[]string{
1116+
`
1117+
package main
1118+
1119+
import (
1120+
"log"
1121+
"net/http"
1122+
)
1123+
1124+
func main() {
1125+
err := http.ListenAndServe(":8080", nil)
1126+
log.Fatal(err)
1127+
}`,
1128+
}, 1, gosec.NewConfig()},
1129+
{
1130+
[]string{
1131+
`
1132+
package main
1133+
1134+
import (
1135+
"log"
1136+
"net/http"
1137+
)
1138+
1139+
func main() {
1140+
err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
1141+
log.Fatal(err)
1142+
}`,
1143+
}, 1, gosec.NewConfig(),
1144+
},
1145+
{
1146+
[]string{
1147+
`
1148+
package main
1149+
1150+
import (
1151+
"log"
1152+
"net"
1153+
"net/http"
1154+
)
1155+
1156+
func main() {
1157+
l, err := net.Listen("tcp", ":8080")
1158+
if err != nil {
1159+
log.Fatal(err)
1160+
}
1161+
defer l.Close()
1162+
err = http.Serve(l, nil)
1163+
log.Fatal(err)
1164+
}`,
1165+
}, 1, gosec.NewConfig(),
1166+
},
1167+
{
1168+
[]string{
1169+
`
1170+
package main
1171+
1172+
import (
1173+
"log"
1174+
"net"
1175+
"net/http"
1176+
)
1177+
1178+
func main() {
1179+
l, err := net.Listen("tcp", ":8443")
1180+
if err != nil {
1181+
log.Fatal(err)
1182+
}
1183+
defer l.Close()
1184+
err = http.ServeTLS(l, nil, "cert.pem", "key.pem")
1185+
log.Fatal(err)
1186+
}`,
1187+
}, 1, gosec.NewConfig(),
1188+
},
1189+
}
1190+
11131191
// SampleCodeG201 - SQL injection via format string
11141192
SampleCodeG201 = []CodeSample{
11151193
{[]string{`

0 commit comments

Comments
 (0)