mirror of
https://github.com/pushbits/server.git
synced 2025-04-29 18:26:49 +02:00
Add semgrep-rules as submodule
This commit is contained in:
parent
a75478f83b
commit
5267359a60
71 changed files with 23 additions and 2555 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "tests/semgrep-rules"]
|
||||
path = tests/semgrep-rules
|
||||
url = https://github.com/returntocorp/semgrep-rules
|
22
Makefile
22
Makefile
|
@ -1,21 +1,33 @@
|
|||
OUTDIR := ./out
|
||||
|
||||
SEMGREP_MODFILE := ./tests/semgrep-rules/go.mod
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
mkdir -p ./out
|
||||
go build -ldflags="-w -s" -o ./out/pushbits ./cmd/pushbits
|
||||
mkdir -p $(OUTDIR)
|
||||
go build -ldflags="-w -s" -o $(OUTDIR)/pushbits ./cmd/pushbits
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
rm -rf $(SEMGREP_MODFILE)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
stdout=$$(gofmt -l . 2>&1); if [ "$$stdout" ]; then exit 1; fi
|
||||
touch $(SEMGREP_MODFILE) # Needed so the Go files of semgrep-rules do not interfere with static analysis
|
||||
go fmt ./...
|
||||
go vet ./...
|
||||
gocyclo -over 10 $(shell find . -iname '*.go' -type f)
|
||||
gocyclo -over 10 $(shell find . -type f \( -iname '*.go' ! -path "./tests/semgrep-rules/*" \))
|
||||
staticcheck ./...
|
||||
go test -v -cover ./...
|
||||
gosec -exclude-dir=tests ./...
|
||||
semgrep --lang=go --config=tests/semgrep --metrics=off
|
||||
semgrep --lang=go --config=tests/semgrep-rules/go --metrics=off
|
||||
rm -rf $(SEMGREP_MODFILE)
|
||||
@printf '\n%s\n' "> Test successful"
|
||||
|
||||
.PHONY: setup
|
||||
setup:
|
||||
git submodule update --init --recursive
|
||||
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
|
||||
go install github.com/securego/gosec/v2/cmd/gosec@latest
|
||||
go install github.com/swaggo/swag/cmd/swag@latest
|
||||
|
|
|
@ -21,7 +21,7 @@ func IsPasswordPwned(password string) (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// nosemgrep: tests.semgrep.go.lang.security.audit.crypto.insecure-module-used, tests.semgrep.go.lang.security.audit.crypto.use-of-sha1
|
||||
// nosemgrep: tests.semgrep-rules.go.lang.security.audit.crypto.insecure-module-used, tests.semgrep-rules.go.lang.security.audit.crypto.use-of-sha1
|
||||
hash := sha1.Sum([]byte(password)) //#nosec G401 -- False positive, only the first 5 bytes are transmitted.
|
||||
hashStr := fmt.Sprintf("%X", hash)
|
||||
lookup := hashStr[0:5]
|
||||
|
|
|
@ -27,7 +27,7 @@ func createFileDir(file string) {
|
|||
dir := filepath.Dir(file)
|
||||
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
// nosemgrep: tests.semgrep.go.lang.correctness.permissions.incorrect-default-permission
|
||||
// nosemgrep: tests.semgrep-rules.go.lang.correctness.permissions.incorrect-default-permission
|
||||
if err := os.MkdirAll(dir, 0750); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
1
tests/semgrep-rules
Submodule
1
tests/semgrep-rules
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 46e040f844c2b1c40599c8d4f1cdf277b197329e
|
|
@ -1,51 +0,0 @@
|
|||
rules:
|
||||
- id: database-sqli
|
||||
languages:
|
||||
- go
|
||||
message: >-
|
||||
Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled
|
||||
and not properly sanitized. In order to prevent SQL injection,
|
||||
used parameterized queries or prepared statements instead.
|
||||
You can use prepared statements with the 'Prepare' and 'PrepareContext' calls.
|
||||
mode: taint
|
||||
metadata:
|
||||
references:
|
||||
- 'https://pkg.go.dev/database/sql#DB.Query'
|
||||
category: security
|
||||
owasp: "A1: Injection"
|
||||
cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')"
|
||||
technology:
|
||||
- aws-lambda
|
||||
- database
|
||||
- sql
|
||||
pattern-sinks:
|
||||
- patterns:
|
||||
- pattern: $QUERY
|
||||
- pattern-either:
|
||||
- pattern: $DB.Exec($QUERY,...)
|
||||
- pattern: $DB.ExecContent($QUERY,...)
|
||||
- pattern: $DB.Query($QUERY,...)
|
||||
- pattern: $DB.QueryContext($QUERY,...)
|
||||
- pattern: $DB.QueryRow($QUERY,...)
|
||||
- pattern: $DB.QueryRowContext($QUERY,...)
|
||||
- pattern-inside: |
|
||||
import "database/sql"
|
||||
...
|
||||
pattern-sources:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...}
|
||||
...
|
||||
lambda.Start($HANDLER, ...)
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
func $HANDLER($EVENT $TYPE) {...}
|
||||
...
|
||||
lambda.Start($HANDLER, ...)
|
||||
- pattern-not-inside: |
|
||||
func $HANDLER($EVENT context.Context) {...}
|
||||
...
|
||||
lambda.Start($HANDLER, ...)
|
||||
- pattern: $EVENT
|
||||
severity: WARNING
|
|
@ -1,57 +0,0 @@
|
|||
rules:
|
||||
- id: handler-assignment-from-multiple-sources
|
||||
metadata:
|
||||
cwe: "CWE-289: Authentication Bypass by Alternate Name"
|
||||
owasp: "A2: Broken Authentication"
|
||||
owaspapi: "API1: Broken Object Level Authorization"
|
||||
category: security
|
||||
technology:
|
||||
- gorilla
|
||||
confidence: MEDIUM
|
||||
patterns:
|
||||
- pattern-inside: |
|
||||
func $HANDLER(..., $R *http.Request, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-not: |
|
||||
$VAR = true
|
||||
...
|
||||
$VAR = false
|
||||
- pattern-not: |
|
||||
$VAR = false
|
||||
...
|
||||
$VAR = true
|
||||
- pattern-not: |
|
||||
$VAR = $X
|
||||
...
|
||||
$VAR = $X
|
||||
- pattern-not: |
|
||||
$VAR = $X
|
||||
...
|
||||
$VAR = $Z(..., $VAR, ...)
|
||||
- pattern-not: |
|
||||
$VAR = $X
|
||||
...
|
||||
$VAR = $Z($W(..., $VAR, ...))
|
||||
- pattern-not: |
|
||||
$VAR = $X
|
||||
...
|
||||
$VAR = $VAR[:$Z(..., $VAR, ...)]
|
||||
- pattern-not: |
|
||||
$VAR = $X
|
||||
...
|
||||
$VAR = $VAR[$Z(..., $VAR, ...):]
|
||||
- pattern-not: |
|
||||
$VAR = $X
|
||||
...
|
||||
$VAR = $VAR[$Z(..., $VAR, ...)]
|
||||
- pattern: |
|
||||
$VAR = $X
|
||||
...
|
||||
$VAR = $Y
|
||||
message:
|
||||
"Variable $VAR is assigned from two different sources: '$X' and '$Y'. Make\
|
||||
\ sure this is intended, as this could cause logic bugs if they are treated as\
|
||||
\ they are the same object."
|
||||
languages: [go]
|
||||
severity: WARNING
|
|
@ -1,33 +0,0 @@
|
|||
rules:
|
||||
- id: session-cookie-missing-httponly
|
||||
patterns:
|
||||
- pattern-not-inside: |
|
||||
&sessions.Options{
|
||||
...,
|
||||
HttpOnly: true,
|
||||
...,
|
||||
}
|
||||
- pattern: |
|
||||
&sessions.Options{
|
||||
...,
|
||||
}
|
||||
message: >-
|
||||
A session cookie was detected without setting the 'HttpOnly' flag.
|
||||
The 'HttpOnly' flag for cookies instructs the browser to forbid
|
||||
client-side scripts from reading the cookie which mitigates XSS
|
||||
attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true'
|
||||
in the Options struct.
|
||||
metadata:
|
||||
cwe: "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
references:
|
||||
- https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69
|
||||
category: security
|
||||
technology:
|
||||
- gorilla
|
||||
confidence: MEDIUM
|
||||
fix-regex:
|
||||
regex: (HttpOnly\s*:\s+)false
|
||||
replacement: \1true
|
||||
severity: WARNING
|
||||
languages: [go]
|
|
@ -1,32 +0,0 @@
|
|||
rules:
|
||||
- id: session-cookie-missing-secure
|
||||
patterns:
|
||||
- pattern-not-inside: |
|
||||
&sessions.Options{
|
||||
...,
|
||||
Secure: true,
|
||||
...,
|
||||
}
|
||||
- pattern: |
|
||||
&sessions.Options{
|
||||
...,
|
||||
}
|
||||
message: >-
|
||||
A session cookie was detected without setting the 'Secure' flag.
|
||||
The 'secure' flag for cookies prevents the client from transmitting
|
||||
the cookie over insecure channels such as HTTP. Set the 'Secure'
|
||||
flag by setting 'Secure' to 'true' in the Options struct.
|
||||
metadata:
|
||||
cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
references:
|
||||
- https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69
|
||||
category: security
|
||||
technology:
|
||||
- gorilla
|
||||
confidence: MEDIUM
|
||||
fix-regex:
|
||||
regex: (Secure\s*:\s+)false
|
||||
replacement: \1true
|
||||
severity: WARNING
|
||||
languages: [go]
|
|
@ -1,26 +0,0 @@
|
|||
rules:
|
||||
- id: grpc-client-insecure-connection
|
||||
metadata:
|
||||
cwe: "CWE-300: Channel Accessible by Non-Endpoint"
|
||||
references:
|
||||
- https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption
|
||||
category: security
|
||||
technology:
|
||||
- grpc
|
||||
confidence: HIGH
|
||||
message: >-
|
||||
Found an insecure gRPC connection using 'grpc.WithInsecure()'. This creates a
|
||||
connection without encryption to a gRPC
|
||||
server. A malicious attacker could tamper with the gRPC message, which could compromise
|
||||
the machine. Instead, establish
|
||||
a secure connection with an
|
||||
SSL certificate using the 'grpc.WithTransportCredentials()' function. You can
|
||||
create a create credentials using a 'tls.Config{}'
|
||||
struct with 'credentials.NewTLS()'. The final fix looks like this: 'grpc.WithTransportCredentials(credentials.NewTLS(<config>))'.
|
||||
languages:
|
||||
- go
|
||||
severity: ERROR
|
||||
pattern: $GRPC.Dial($ADDR, ..., $GRPC.WithInsecure(...), ...)
|
||||
fix-regex:
|
||||
regex: (.*)WithInsecure\(.*?\)
|
||||
replacement: \1WithTransportCredentials(credentials.NewTLS(<your_tls_config_here>))
|
|
@ -1,41 +0,0 @@
|
|||
rules:
|
||||
- id: grpc-server-insecure-connection
|
||||
metadata:
|
||||
cwe: "CWE-300: Channel Accessible by Non-Endpoint"
|
||||
references:
|
||||
- https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption
|
||||
category: security
|
||||
technology:
|
||||
- grpc
|
||||
confidence: HIGH
|
||||
message: >-
|
||||
Found an insecure gRPC server without 'grpc.Creds()' or options with credentials.
|
||||
This allows for a connection without
|
||||
encryption to this server.
|
||||
A malicious attacker could tamper with the gRPC message, which could compromise
|
||||
the machine. Include credentials derived
|
||||
from an SSL certificate in order to create a secure gRPC connection. You can create
|
||||
credentials using 'credentials.NewServerTLSFromFile("cert.pem",
|
||||
"cert.key")'.
|
||||
languages:
|
||||
- go
|
||||
severity: ERROR
|
||||
patterns:
|
||||
- pattern-not: grpc.NewServer(..., grpc.Creds(...), ...)
|
||||
- pattern-not-inside: |
|
||||
$OPTS := []grpc.ServerOption{
|
||||
...,
|
||||
grpc.Creds(credentials.NewClientTLSFromCert(...)),
|
||||
...,
|
||||
}
|
||||
grpc.NewServer($OPTS...)
|
||||
- pattern-not-inside: |
|
||||
$CREDS := credentials.NewClientTLSFromCert(...)
|
||||
...
|
||||
$OPTS := []grpc.ServerOption{
|
||||
...,
|
||||
$CREDS,
|
||||
...,
|
||||
}
|
||||
grpc.NewServer($OPTS...)
|
||||
- pattern: grpc.NewServer(...)
|
|
@ -1,22 +0,0 @@
|
|||
rules:
|
||||
- id: jwt-go-parse-unverified
|
||||
message: >-
|
||||
Detected the decoding of a JWT token without a verify step.
|
||||
Don't use `ParseUnverified` unless you know what you're doing
|
||||
This method parses the token but doesn't validate the signature. It's only ever useful in cases where you know the signature is valid (because it has been checked previously in the stack) and you want to extract values from it.
|
||||
metadata:
|
||||
cwe: "CWE-345: Insufficient Verification of Data Authenticity"
|
||||
owasp: "A2: Broken Authentication"
|
||||
source-rule-url: https://r2c.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/
|
||||
category: security
|
||||
technology:
|
||||
- jwt
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-inside: |
|
||||
import "github.com/dgrijalva/jwt-go"
|
||||
...
|
||||
- pattern: |
|
||||
$JWT.ParseUnverified(...)
|
|
@ -1,26 +0,0 @@
|
|||
rules:
|
||||
- id: jwt-go-none-algorithm
|
||||
message: >-
|
||||
Detected use of the 'none' algorithm in a JWT token.
|
||||
The 'none' algorithm assumes the integrity of the token has already
|
||||
been verified. This would allow a malicious actor to forge a JWT token
|
||||
that will automatically be verified. Do not explicitly use the 'none'
|
||||
algorithm. Instead, use an algorithm such as 'HS256'.
|
||||
metadata:
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
owasp: "A2: Broken Authentication"
|
||||
source-rule-url: https://r2c.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/
|
||||
category: security
|
||||
technology:
|
||||
- jwt
|
||||
confidence: HIGH
|
||||
languages: [go]
|
||||
severity: ERROR
|
||||
patterns:
|
||||
- pattern-inside: |
|
||||
import "github.com/dgrijalva/jwt-go"
|
||||
...
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
jwt.SigningMethodNone
|
||||
- pattern: jwt.UnsafeAllowNoneSignatureType
|
|
@ -1,19 +0,0 @@
|
|||
rules:
|
||||
- id: hardcoded-jwt-key
|
||||
metadata:
|
||||
cwe: "CWE-798: Use of Hard-coded Credentials"
|
||||
owasp: "A2: Broken Authentication"
|
||||
category: security
|
||||
technology:
|
||||
- jwt
|
||||
confidence: MEDIUM
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
$X = []byte("...")
|
||||
...
|
||||
$Y := $TOKEN.SignedString($X)
|
||||
- pattern: |
|
||||
$TOKEN.SignedString([]byte("..."))
|
||||
message: JWT token is hardcoded
|
||||
languages: [go]
|
||||
severity: WARNING
|
|
@ -1,22 +0,0 @@
|
|||
rules:
|
||||
- id: channel-guarded-with-mutex
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
$MUX.Lock()
|
||||
$VALUE <- $CHANNEL
|
||||
$MUX.Unlock()
|
||||
- pattern: |
|
||||
$MUX.Lock()
|
||||
$VALUE = <- $CHANNEL
|
||||
$MUX.Unlock()
|
||||
message: >-
|
||||
Detected a channel guarded with a mutex. Channels already have
|
||||
an internal mutex, so this is unnecessary. Remove the mutex.
|
||||
See https://hackmongo.com/page/golang-antipatterns/#guarded-channel
|
||||
for more information.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
category: best-practice
|
||||
technology:
|
||||
- go
|
|
@ -1,27 +0,0 @@
|
|||
rules:
|
||||
- id: hidden-goroutine
|
||||
patterns:
|
||||
- pattern-not: |
|
||||
func $FUNC(...) {
|
||||
go func() {
|
||||
...
|
||||
}(...)
|
||||
$MORE
|
||||
}
|
||||
- pattern: |
|
||||
func $FUNC(...) {
|
||||
go func() {
|
||||
...
|
||||
}(...)
|
||||
}
|
||||
message: >-
|
||||
Detected a hidden goroutine. Function invocations are expected to synchronous,
|
||||
and this function will execute asynchronously because all it does is call a
|
||||
goroutine. Instead, remove the internal goroutine and call the function using
|
||||
'go'.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
category: best-practice
|
||||
technology:
|
||||
- go
|
|
@ -1,29 +0,0 @@
|
|||
rules:
|
||||
- id: exported_loop_pointer
|
||||
message: >-
|
||||
`$VALUE` is a loop pointer that may be exported from the loop. This pointer is
|
||||
shared between loop iterations, so the exported reference will always point to
|
||||
the last loop value, which is likely unintentional. To fix, copy the pointer to
|
||||
a new pointer within the loop.
|
||||
metadata:
|
||||
references:
|
||||
- https://github.com/kyoh86/looppointer
|
||||
category: correctness
|
||||
technology:
|
||||
- go
|
||||
severity: WARNING
|
||||
languages:
|
||||
- go
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
for _, $VALUE := range $SOURCE {
|
||||
<... &($VALUE) ...>
|
||||
}
|
||||
- pattern: |
|
||||
for _, $VALUE := range $SOURCE {
|
||||
<... func() { <... &$VALUE ...> } ...>
|
||||
}
|
||||
- pattern: |
|
||||
for _, $VALUE := range $SOURCE {
|
||||
<... $ANYTHING(..., <... $VALUE ...>, ...) ...>
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
rules:
|
||||
- id: integer-overflow-int16
|
||||
message:
|
||||
Detected conversion of the result of a strconv.Atoi command to an int16. This could lead to an integer overflow,
|
||||
which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern: |
|
||||
$F, $ERR := strconv.Atoi($NUM)
|
||||
...
|
||||
int16($F)
|
||||
- metavariable-comparison:
|
||||
metavariable: $NUM
|
||||
comparison: $NUM > 32767 or $NUM < -32768
|
||||
strip: true
|
||||
metadata:
|
||||
category: correctness
|
||||
technology:
|
||||
- go
|
||||
- id: integer-overflow-int32
|
||||
message:
|
||||
Detected conversion of the result of a strconv.Atoi command to an int32. This could lead to an integer overflow,
|
||||
which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern: |
|
||||
$F, $ERR := strconv.Atoi($NUM)
|
||||
...
|
||||
int32($F)
|
||||
- metavariable-comparison:
|
||||
metavariable: $NUM
|
||||
comparison: $NUM > 2147483647 or $NUM < -2147483648
|
||||
strip: true
|
||||
metadata:
|
||||
category: correctness
|
||||
technology:
|
||||
- go
|
|
@ -1,25 +0,0 @@
|
|||
rules:
|
||||
- id: incorrect-default-permission
|
||||
message:
|
||||
Detected file permissions that are set to more than `0600` (user/owner can read and write). Setting file permissions
|
||||
to higher than `0600` is most likely unnecessary and violates the principle of least privilege. Instead, set permissions
|
||||
to be `0600` or less for os.Chmod, os.Mkdir, os.OpenFile, os.MkdirAll, and ioutil.WriteFile
|
||||
metadata:
|
||||
cwe: "CWE-276: Incorrect Default Permissions"
|
||||
source_rule_url: https://github.com/securego/gosec
|
||||
category: correctness
|
||||
technology:
|
||||
- go
|
||||
severity: WARNING
|
||||
languages: [go]
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern: os.Chmod($NAME, $PERM)
|
||||
- pattern: os.Mkdir($NAME, $PERM)
|
||||
- pattern: os.OpenFile($NAME, $FLAG, $PERM)
|
||||
- pattern: os.MkdirAll($NAME, $PERM)
|
||||
- pattern: ioutil.WriteFile($NAME, $DATA, $PERM)
|
||||
- metavariable-comparison:
|
||||
metavariable: $PERM
|
||||
comparison: $PERM > 0o600
|
||||
base: 8
|
|
@ -1,16 +0,0 @@
|
|||
rules:
|
||||
- id: use-filepath-join
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
message: >-
|
||||
`path.Join(...)` always joins using a forward slash. This may cause
|
||||
issues on Windows or other systems using a different delimiter. Use
|
||||
`filepath.Join(...)` instead which uses OS-specific path separators.
|
||||
pattern: path.Join(...)
|
||||
metadata:
|
||||
category: correctness
|
||||
references:
|
||||
- https://parsiya.net/blog/2019-03-09-path.join-considered-harmful/
|
||||
- https://go.dev/src/path/path.go?s=4034:4066#L145
|
||||
technology:
|
||||
- go
|
|
@ -1,31 +0,0 @@
|
|||
rules:
|
||||
- id: eqeq-is-bad
|
||||
patterns:
|
||||
- pattern-not-inside: assert(...)
|
||||
- pattern-either:
|
||||
- pattern: $X == $X
|
||||
- pattern: $X != $X
|
||||
- pattern-not: 1 == 1
|
||||
message:
|
||||
Detected useless comparison operation `$X == $X` or `$X != $X`. This will always return 'True' or 'False' and therefore
|
||||
is not necessary. Instead, remove this comparison operation or use another comparison expression that is not deterministic.
|
||||
languages: [go]
|
||||
severity: ERROR
|
||||
metadata:
|
||||
category: correctness
|
||||
technology:
|
||||
- go
|
||||
- id: hardcoded-eq-true-or-false
|
||||
message:
|
||||
Detected useless if statement. 'if (True)' and 'if (False)' always result in the same behavior, and therefore is
|
||||
not necessary in the code. Remove the 'if (False)' expression completely or just the 'if (True)' comparison depending
|
||||
on which expression is in the code.
|
||||
languages: [go]
|
||||
severity: ERROR
|
||||
pattern-either:
|
||||
- pattern: if (true) { ... }
|
||||
- pattern: if (false) { ... }
|
||||
metadata:
|
||||
category: correctness
|
||||
technology:
|
||||
- go
|
|
@ -1,33 +0,0 @@
|
|||
rules:
|
||||
- id: useless-if-conditional
|
||||
message:
|
||||
Detected an if block that checks for the same condition on both branches (`$X`). The second condition check is
|
||||
useless as it is the same as the first, and therefore can be removed from the code,
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern: |
|
||||
if ($X) {
|
||||
...
|
||||
} else if ($X) {
|
||||
...
|
||||
}
|
||||
metadata:
|
||||
category: maintainability
|
||||
technology:
|
||||
- go
|
||||
- id: useless-if-body
|
||||
pattern: |
|
||||
if ($X) {
|
||||
$S
|
||||
} else {
|
||||
$S
|
||||
}
|
||||
message:
|
||||
Detected identical statements in the if body and the else body of an if-statement. This will lead to the same code
|
||||
being executed no matter what the if-expression evaluates to. Instead, remove the if statement.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
category: maintainability
|
||||
technology:
|
||||
- go
|
|
@ -1,48 +0,0 @@
|
|||
rules:
|
||||
- id: insecure-module-used
|
||||
message: >-
|
||||
Detected use of an insecure cryptographic hashing method. This method is known
|
||||
to be broken and easily compromised. Use SHA256 or SHA3 instead.
|
||||
metadata:
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
source-rule-url: https://github.com/securego/gosec
|
||||
references:
|
||||
- https://godoc.org/golang.org/x/crypto/sha3
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern-either:
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
import "crypto/md5"
|
||||
...
|
||||
- pattern: |
|
||||
md5.$FUNC(...)
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
import "crypto/des"
|
||||
...
|
||||
- pattern: |
|
||||
des.$FUNC(...)
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
import "crypto/sha1"
|
||||
...
|
||||
- pattern: |
|
||||
sha1.$FUNC(...)
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
import "crypto/rc4"
|
||||
...
|
||||
- pattern: |
|
||||
rc4.$FUNC(...)
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
import "net/http/cgi"
|
||||
...
|
||||
- pattern: |
|
||||
cgi.$FUNC(...)
|
|
@ -1,23 +0,0 @@
|
|||
rules:
|
||||
- id: avoid-ssh-insecure-ignore-host-key
|
||||
message: >-
|
||||
Disabled host key verification detected. This allows man-in-the-middle
|
||||
attacks. Use the 'golang.org/x/crypto/ssh/knownhosts' package to do
|
||||
host key verification.
|
||||
See https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/
|
||||
to learn more about the problem and how to fix it.
|
||||
metadata:
|
||||
cwe: "CWE-322: Key Exchange without Entity Authentication"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
source-rule-url: https://github.com/securego/gosec
|
||||
references:
|
||||
- https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/
|
||||
- https://gist.github.com/Skarlso/34321a230cf0245018288686c9e70b2d
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern: |-
|
||||
ssh.InsecureIgnoreHostKey()
|
|
@ -1,32 +0,0 @@
|
|||
rules:
|
||||
- id: math-random-used
|
||||
metadata:
|
||||
cwe: "CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
references:
|
||||
- https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
message: Do not use `math/rand`. Use `crypto/rand` instead.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern-either:
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
import mrand "math/rand"
|
||||
...
|
||||
- pattern-either:
|
||||
- pattern: mrand.Int()
|
||||
- pattern: mrand.Read(...)
|
||||
- patterns:
|
||||
- pattern-inside: |
|
||||
import "math/rand"
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
import "crypto/rand"
|
||||
...
|
||||
- pattern-either:
|
||||
- pattern: rand.Int()
|
||||
- pattern: rand.Read(...)
|
|
@ -1,28 +0,0 @@
|
|||
rules:
|
||||
- id: missing-ssl-minversion
|
||||
message: >-
|
||||
`MinVersion` is missing from this TLS configuration. The default
|
||||
value is TLS1.0 which is considered insecure. Explicitly set the
|
||||
`MinVersion` to a secure version of TLS, such as `VersionTLS13`.
|
||||
metadata:
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go
|
||||
references:
|
||||
- https://golang.org/doc/go1.14#crypto/tls
|
||||
- https://golang.org/pkg/crypto/tls/#:~:text=MinVersion
|
||||
- https://www.us-cert.gov/ncas/alerts/TA14-290A
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: HIGH
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern: |-
|
||||
tls.Config{...}
|
||||
- pattern-not-inside: |-
|
||||
tls.Config{..., MinVersion: ..., ...}
|
||||
fix-regex:
|
||||
regex: Config\s*\{
|
||||
replacement: "Config{MinVersion: SSL.VersionTLS13,"
|
|
@ -1,23 +0,0 @@
|
|||
rules:
|
||||
- id: ssl-v3-is-insecure
|
||||
message: >-
|
||||
SSLv3 is insecure because it has known vulnerabilities.
|
||||
Starting with go1.14, SSLv3 will be removed. Instead, use
|
||||
'tls.VersionTLS13'.
|
||||
metadata:
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go
|
||||
references:
|
||||
- https://golang.org/doc/go1.14#crypto/tls
|
||||
- https://www.us-cert.gov/ncas/alerts/TA14-290A
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: HIGH
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
fix-regex:
|
||||
regex: VersionSSL30
|
||||
replacement: VersionTLS13
|
||||
pattern: "tls.Config{..., MinVersion: $TLS.VersionSSL30, ...}"
|
|
@ -1,45 +0,0 @@
|
|||
rules:
|
||||
- id: tls-with-insecure-cipher
|
||||
message: >-
|
||||
Detected an insecure CipherSuite via the 'tls' module. This suite is considered
|
||||
weak.
|
||||
Use the function 'tls.CipherSuites()' to get a list of good cipher suites.
|
||||
See https://golang.org/pkg/crypto/tls/#InsecureCipherSuites
|
||||
for why and what other cipher suites to use.
|
||||
metadata:
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls.go
|
||||
references:
|
||||
- https://golang.org/pkg/crypto/tls/#InsecureCipherSuites
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: HIGH
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_RC4_128_SHA,...}}
|
||||
- pattern: |
|
||||
tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_AES_128_CBC_SHA256,...}}
|
||||
- pattern: |
|
||||
tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,...}}
|
||||
- pattern: |
|
||||
tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,...}}
|
||||
- pattern: |
|
||||
tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,...}}
|
||||
- pattern: |
|
||||
tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,...}}
|
||||
- pattern: |
|
||||
tls.CipherSuite{..., TLS_RSA_WITH_RC4_128_SHA ,...}
|
||||
- pattern: |
|
||||
tls.CipherSuite{..., TLS_RSA_WITH_AES_128_CBC_SHA256 ,...}
|
||||
- pattern: |
|
||||
tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ,...}
|
||||
- pattern: |
|
||||
tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_RC4_128_SHA ,...}
|
||||
- pattern: |
|
||||
tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ,...}
|
||||
- pattern: |-
|
||||
tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,...}
|
|
@ -1,73 +0,0 @@
|
|||
rules:
|
||||
- id: use-of-md5
|
||||
message: >-
|
||||
Detected MD5 hash algorithm which is considered insecure. MD5 is not
|
||||
collision resistant and is therefore not suitable as a cryptographic
|
||||
signature. Use SHA256 or SHA3 instead.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
source-rule-url: https://github.com/securego/gosec#available-rules
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
md5.New()
|
||||
- pattern: |
|
||||
md5.Sum(...)
|
||||
- id: use-of-sha1
|
||||
message: >-
|
||||
Detected SHA1 hash algorithm which is considered insecure. SHA1 is not
|
||||
collision resistant and is therefore not suitable as a cryptographic
|
||||
signature. Use SHA256 or SHA3 instead.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
source-rule-url: https://github.com/securego/gosec#available-rules
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
sha1.New()
|
||||
- pattern: |
|
||||
sha1.Sum(...)
|
||||
- id: use-of-DES
|
||||
message: >-
|
||||
Detected DES cipher algorithm which is insecure. The algorithm is
|
||||
considered weak and has been deprecated. Use AES instead.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
source-rule-url: https://github.com/securego/gosec#available-rules
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
des.NewTripleDESCipher(...)
|
||||
- pattern: |
|
||||
des.NewCipher(...)
|
||||
- id: use-of-rc4
|
||||
message: >-
|
||||
Detected RC4 cipher algorithm which is insecure. The algorithm has many
|
||||
known vulnerabilities. Use AES instead.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
owasp: "A9: Using Components with Known Vulnerabilities"
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
source-rule-url: https://github.com/securego/gosec#available-rules
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
pattern: |-
|
||||
rc4.NewCipher(...)
|
|
@ -1,24 +0,0 @@
|
|||
rules:
|
||||
- id: use-of-weak-rsa-key
|
||||
message: RSA keys should be at least 2048 bits
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
cwe: "CWE-326: Inadequate Encryption Strength"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
source-rule-url: https://github.com/securego/gosec/blob/master/rules/rsa.go
|
||||
references:
|
||||
- https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
rsa.GenerateKey(..., $BITS)
|
||||
- pattern: |
|
||||
rsa.GenerateMultiPrimeKey(..., $BITS)
|
||||
- metavariable-comparison:
|
||||
metavariable: $BITS
|
||||
comparison: $BITS < 2048
|
|
@ -1,35 +0,0 @@
|
|||
rules:
|
||||
- id: dangerous-command-write
|
||||
patterns:
|
||||
- pattern: |
|
||||
$CW.Write($BYTE)
|
||||
- pattern-inside: |
|
||||
$CW,$ERR := $CMD.StdinPipe()
|
||||
...
|
||||
- pattern-not: |
|
||||
$CW.Write("...")
|
||||
- pattern-not: |
|
||||
$CW.Write([]byte("..."))
|
||||
- pattern-not: |
|
||||
$CW.Write([]byte("..."+"..."))
|
||||
- pattern-not-inside: |
|
||||
$BYTE = []byte("...");
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$BYTE = []byte("..."+"...");
|
||||
...
|
||||
- pattern-inside: |
|
||||
import "os/exec"
|
||||
...
|
||||
message: >-
|
||||
Detected non-static command inside Write. Audit the input to '$CW.Write'.
|
||||
If unverified user data can reach this call site, this is a code injection
|
||||
vulnerability. A malicious actor can inject a malicious script to execute
|
||||
arbitrary code.
|
||||
severity: ERROR
|
||||
languages: [go]
|
||||
metadata:
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
|
@ -1,76 +0,0 @@
|
|||
rules:
|
||||
- id: dangerous-exec-cmd
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern: |
|
||||
exec.Cmd {...,Path: $CMD,...}
|
||||
- pattern-not: |
|
||||
exec.Cmd {...,Path: "...",...}
|
||||
- pattern-not-inside: |
|
||||
$CMD,$ERR := exec.LookPath("...");
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD = "...";
|
||||
...
|
||||
- patterns:
|
||||
- pattern: |
|
||||
exec.Cmd {...,Args: $ARGS,...}
|
||||
- pattern-not: |
|
||||
exec.Cmd {...,Args: []string{...},...}
|
||||
- pattern-not-inside: |
|
||||
$ARGS = []string{"...",...};
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD = "...";
|
||||
...
|
||||
$ARGS = []string{$CMD,...};
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD = exec.LookPath("...");
|
||||
...
|
||||
$ARGS = []string{$CMD,...};
|
||||
...
|
||||
- patterns:
|
||||
- pattern: |
|
||||
exec.Cmd {...,Args: []string{$CMD,...},...}
|
||||
- pattern-not: |
|
||||
exec.Cmd {...,Args: []string{"...",...},...}
|
||||
- pattern-not-inside: |
|
||||
$CMD,$ERR := exec.LookPath("...");
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD = "...";
|
||||
...
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
exec.Cmd {...,Args: []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...}
|
||||
- patterns:
|
||||
- pattern: |
|
||||
exec.Cmd {...,Args: []string{$CMD,"-c",$EXE,...},...}
|
||||
- pattern-inside: |
|
||||
$CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/");
|
||||
...
|
||||
- pattern-not: |
|
||||
exec.Cmd {...,Args: []string{"...","...","...",...},...}
|
||||
- pattern-not-inside: |
|
||||
$EXE = "...";
|
||||
...
|
||||
- pattern-inside: |
|
||||
import "os/exec"
|
||||
...
|
||||
message: >-
|
||||
Detected non-static command inside exec.Cmd. Audit the input to 'exec.Cmd'.
|
||||
If unverified user data can reach this call site, this is a code injection
|
||||
vulnerability. A malicious actor can inject a malicious script to execute
|
||||
arbitrary code.
|
||||
metadata:
|
||||
cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
|
||||
owasp: "A1: Injection"
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
||||
languages: [go]
|
|
@ -1,47 +0,0 @@
|
|||
rules:
|
||||
- id: dangerous-exec-command
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
exec.Command($CMD,...)
|
||||
- pattern: |
|
||||
exec.CommandContext($CTX,$CMD,...)
|
||||
- pattern-not: |
|
||||
exec.Command("...",...)
|
||||
- pattern-not: |
|
||||
exec.CommandContext($CTX,"...",...)
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
exec.Command("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...)
|
||||
- pattern: |
|
||||
exec.CommandContext($CTX,"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...)
|
||||
- pattern-not: |
|
||||
exec.Command("...","...","...",...)
|
||||
- pattern-not: |
|
||||
exec.CommandContext($CTX,"...","...","...",...)
|
||||
- pattern-inside: |
|
||||
import "os/exec"
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD,$ERR := exec.LookPath("...");
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD = "...";
|
||||
...
|
||||
message: >-
|
||||
Detected non-static command inside Command. Audit the input to 'exec.Command'.
|
||||
If unverified user data can reach this call site, this is a code injection
|
||||
vulnerability. A malicious actor can inject a malicious script to execute
|
||||
arbitrary code.
|
||||
metadata:
|
||||
cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
|
||||
owasp: "A1: Injection"
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
||||
languages: [go]
|
|
@ -1,88 +0,0 @@
|
|||
rules:
|
||||
- id: dangerous-syscall-exec
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern: |
|
||||
syscall.$METHOD($BIN,...)
|
||||
- pattern-not: |
|
||||
syscall.$METHOD("...",...)
|
||||
- pattern-not-inside: |
|
||||
$BIN,$ERR := exec.LookPath("...");
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$BIN = "...";
|
||||
...
|
||||
- patterns:
|
||||
- pattern: |
|
||||
syscall.$METHOD($BIN,$ARGS,...)
|
||||
- pattern-not: |
|
||||
syscall.$METHOD($BIN,[]string{"...",...},...)
|
||||
- pattern-not-inside: |
|
||||
$ARGS := []string{"...",...};
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD = "...";
|
||||
...
|
||||
$ARGS = []string{$CMD,...};
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD,$ERR := exec.LookPath("...");
|
||||
...
|
||||
$ARGS = []string{$CMD,...};
|
||||
...
|
||||
- patterns:
|
||||
- pattern: |
|
||||
syscall.$METHOD($BIN,[]string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...)
|
||||
- pattern-not: |
|
||||
syscall.$METHOD($BIN,[]string{"...","...","...",...},...)
|
||||
- patterns:
|
||||
- pattern: |
|
||||
syscall.$METHOD($BIN,$ARGS,...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$ARGS := []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...};
|
||||
...
|
||||
- pattern-inside: |
|
||||
$CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/";
|
||||
...
|
||||
$ARGS = []string{$CMD,"-c",$EXE,...};
|
||||
...
|
||||
- pattern-inside: |
|
||||
$CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/");
|
||||
...
|
||||
$ARGS = []string{$CMD,"-c",$EXE,...};
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$ARGS := []string{"...","...","...",...};
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD = "...";
|
||||
...
|
||||
$ARGS = []string{$CMD,"...","...",...};
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$CMD,$ERR := exec.LookPath("...");
|
||||
...
|
||||
$ARGS = []string{$CMD,"...","...",...};
|
||||
...
|
||||
- pattern-inside: |
|
||||
import "syscall"
|
||||
...
|
||||
- metavariable-regex:
|
||||
metavariable: $METHOD
|
||||
regex: (Exec|ForkExec)
|
||||
message: >-
|
||||
Detected non-static command inside Exec. Audit the input to 'syscall.Exec'.
|
||||
If unverified user data can reach this call site, this is a code injection
|
||||
vulnerability. A malicious actor can inject a malicious script to execute
|
||||
arbitrary code.
|
||||
metadata:
|
||||
cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
|
||||
owasp: "A1: Injection"
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
||||
languages: [go]
|
|
@ -1,155 +0,0 @@
|
|||
rules:
|
||||
- id: string-formatted-query
|
||||
languages: [go]
|
||||
message: >-
|
||||
String-formatted SQL query detected. This could lead to SQL injection if
|
||||
the string is not sanitized properly. Audit this call to ensure the
|
||||
SQL is not manipulable by external data.
|
||||
severity: WARNING
|
||||
metadata:
|
||||
owasp: "A1: Injection"
|
||||
cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')"
|
||||
source-rule-url: https://github.com/securego/gosec
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
patterns:
|
||||
- pattern-not-inside: |
|
||||
$VAR = "..." + "..."
|
||||
...
|
||||
$OBJ.$SINK(..., $VAR, ...)
|
||||
- pattern-not: $OBJ.Exec("...")
|
||||
- pattern-not: $OBJ.ExecContext($CTX, "...")
|
||||
- pattern-not: $OBJ.Query("...")
|
||||
- pattern-not: $OBJ.QueryContext($CTX, "...")
|
||||
- pattern-not: $OBJ.QueryRow("...")
|
||||
- pattern-not: $OBJ.QueryRow($CTX, "...")
|
||||
- pattern-not: $OBJ.QueryRowContext($CTX, "...")
|
||||
- pattern-either:
|
||||
- pattern: $OBJ.Exec($X + ...)
|
||||
- pattern: $OBJ.ExecContext($CTX, $X + ...)
|
||||
- pattern: $OBJ.Query($X + ...)
|
||||
- pattern: $OBJ.QueryContext($CTX, $X + ...)
|
||||
- pattern: $OBJ.QueryRow($X + ...)
|
||||
- pattern: $OBJ.QueryRow($CTX, $X + ...)
|
||||
- pattern: $OBJ.QueryRowContext($CTX, $X + ...)
|
||||
- pattern: $OBJ.Exec(fmt.$P("...", ...))
|
||||
- pattern: $OBJ.ExecContext($CTX, fmt.$P("...", ...))
|
||||
- pattern: $OBJ.Query(fmt.$P("...", ...))
|
||||
- pattern: $OBJ.QueryContext($CTX, fmt.$P("...", ...))
|
||||
- pattern: $OBJ.QueryRow(fmt.$P("...", ...))
|
||||
- pattern: $OBJ.QueryRow($CTX, fmt.$P("...", ...))
|
||||
- pattern: $OBJ.QueryRowContext($CTX, fmt.$P("...", ...))
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$QUERY = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.Exec($QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$QUERY = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.Query($QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$QUERY = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.ExecContext($CTX, $QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$QUERY = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryContext($CTX, $QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$QUERY = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryRow($QUERY)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$QUERY = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryRow($CTX, $QUERY)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$QUERY = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryRowContext($CTX, $QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$OTHER = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.Exec($OTHER, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$OTHER = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.Query($OTHER, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$OTHER = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.ExecContext($CTX, $OTHER, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$OTHER = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryContext($CTX, $OTHER, ...)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$OTHER = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryRow($OTHER)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$OTHER = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryRow($CTX, $OTHER)
|
||||
- pattern: |
|
||||
$QUERY = "..."
|
||||
...
|
||||
$OTHER = $FXN(..., $QUERY, ...)
|
||||
...
|
||||
$OBJ.QueryRowContext($CTX, $OTHER, ...)
|
||||
- pattern: |
|
||||
$QUERY = $X + ...
|
||||
...
|
||||
$OBJ.Exec($QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = $X + ...
|
||||
...
|
||||
$OBJ.Query($QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = $X + ...
|
||||
...
|
||||
$OBJ.ExecContext($CTX, $QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = $X + ...
|
||||
...
|
||||
$OBJ.QueryContext($CTX, $QUERY, ...)
|
||||
- pattern: |
|
||||
$QUERY = $X + ...
|
||||
...
|
||||
$OBJ.QueryRow($QUERY)
|
||||
- pattern: |
|
||||
$QUERY = $X + ...
|
||||
...
|
||||
$OBJ.QueryRow($CTX, $QUERY)
|
||||
- pattern: |
|
||||
$QUERY = $X + ...
|
||||
...
|
||||
$OBJ.QueryRowContext($CTX, $QUERY, ...)
|
|
@ -1,35 +0,0 @@
|
|||
rules:
|
||||
- id: md5-used-as-password
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
message: >-
|
||||
It looks like MD5 is used as a password hash. MD5 is not considered a
|
||||
secure password hash because it can be cracked by an attacker in a short
|
||||
amount of time. Use a suitable password hashing function such as bcrypt.
|
||||
You can use the `golang.org/x/crypto/bcrypt` package.
|
||||
metadata:
|
||||
category: security
|
||||
technology:
|
||||
- md5
|
||||
references:
|
||||
- https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html
|
||||
- https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords
|
||||
- https://github.com/returntocorp/semgrep-rules/issues/1609
|
||||
- https://pkg.go.dev/golang.org/x/crypto/bcrypt
|
||||
owasp:
|
||||
- A02:2017 - Broken Authentication
|
||||
- A02:2021 - Cryptographic Failures
|
||||
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
confidence: HIGH
|
||||
mode: taint
|
||||
pattern-sources:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: md5.New
|
||||
- pattern: md5.Sum
|
||||
pattern-sinks:
|
||||
- patterns:
|
||||
- pattern: $FUNCTION(...)
|
||||
- metavariable-regex:
|
||||
metavariable: $FUNCTION
|
||||
regex: (?i)(.*password.*)
|
|
@ -1,21 +0,0 @@
|
|||
rules:
|
||||
- id: avoid-bind-to-all-interfaces
|
||||
message: >-
|
||||
Detected a network listener listening on 0.0.0.0 or an empty string.
|
||||
This could unexpectedly expose the server publicly as it binds to all available interfaces.
|
||||
Instead, specify another IP address that is not 0.0.0.0 nor the empty string.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
|
||||
owasp: "A6: Security Misconfiguration"
|
||||
source-rule-url: https://github.com/securego/gosec
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
pattern-either:
|
||||
- pattern: tls.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...)
|
||||
- pattern: net.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...)
|
||||
- pattern: tls.Listen($NETWORK, "=~/^:.*$/", ...)
|
||||
- pattern: net.Listen($NETWORK, "=~/^:.*$/", ...)
|
|
@ -1,34 +0,0 @@
|
|||
rules:
|
||||
- id: cookie-missing-httponly
|
||||
patterns:
|
||||
- pattern-not-inside: |
|
||||
http.Cookie{
|
||||
...,
|
||||
HttpOnly: true,
|
||||
...,
|
||||
}
|
||||
- pattern: |
|
||||
http.Cookie{
|
||||
...,
|
||||
}
|
||||
message: >-
|
||||
A session cookie was detected without setting the 'HttpOnly' flag.
|
||||
The 'HttpOnly' flag for cookies instructs the browser to forbid
|
||||
client-side scripts from reading the cookie which mitigates XSS
|
||||
attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true'
|
||||
in the Cookie.
|
||||
metadata:
|
||||
cwe: "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
references:
|
||||
- https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go
|
||||
- https://golang.org/src/net/http/cookie.go
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
fix-regex:
|
||||
regex: (HttpOnly\s*:\s+)false
|
||||
replacement: \1true
|
||||
severity: WARNING
|
||||
languages: [go]
|
|
@ -1,33 +0,0 @@
|
|||
rules:
|
||||
- id: cookie-missing-secure
|
||||
patterns:
|
||||
- pattern-not-inside: |
|
||||
http.Cookie{
|
||||
...,
|
||||
Secure: true,
|
||||
...,
|
||||
}
|
||||
- pattern: |
|
||||
http.Cookie{
|
||||
...,
|
||||
}
|
||||
message: >-
|
||||
A session cookie was detected without setting the 'Secure' flag.
|
||||
The 'secure' flag for cookies prevents the client from transmitting
|
||||
the cookie over insecure channels such as HTTP. Set the 'Secure'
|
||||
flag by setting 'Secure' to 'true' in the Options struct.
|
||||
metadata:
|
||||
cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
references:
|
||||
- https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go
|
||||
- https://golang.org/src/net/http/cookie.go
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
fix-regex:
|
||||
regex: (Secure\s*:\s+)false
|
||||
replacement: \1true
|
||||
severity: WARNING
|
||||
languages: [go]
|
|
@ -1,32 +0,0 @@
|
|||
rules:
|
||||
- id: dynamic-httptrace-clienttrace
|
||||
message: >-
|
||||
Detected a potentially dynamic ClientTrace. This occurred because semgrep could
|
||||
not
|
||||
find a static definition for '$TRACE'. Dynamic ClientTraces are dangerous because
|
||||
they deserialize function code to run when certain Request events occur, which
|
||||
could lead
|
||||
to code being run without your knowledge. Ensure that your ClientTrace is statically
|
||||
defined.
|
||||
metadata:
|
||||
cwe: "CWE-913: Improper Control of Dynamically-Managed Code Resources"
|
||||
owasp: "A8: Insecure Deserialization"
|
||||
references:
|
||||
- https://github.com/returntocorp/semgrep-rules/issues/518
|
||||
# Detects when a static ClientTrace is not defined in the same file as
|
||||
# WithClientTrace. Not a perfect detection, but sufficiently works in a
|
||||
# scan of ~1k repos: https://dev.massive.ret2.co/triager/filter/1007
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
patterns:
|
||||
- pattern-not-inside: |
|
||||
package $PACKAGE
|
||||
...
|
||||
&httptrace.ClientTrace { ... }
|
||||
...
|
||||
- pattern: httptrace.WithClientTrace($ANY, $TRACE)
|
||||
severity: WARNING
|
||||
languages:
|
||||
- go
|
|
@ -1,47 +0,0 @@
|
|||
rules:
|
||||
- id: formatted-template-string
|
||||
message: >-
|
||||
Found a formatted template string passed to 'template.HTML()'.
|
||||
'template.HTML()' does not escape contents.
|
||||
Be absolutely sure there is no user-controlled data in this template.
|
||||
If user data can reach this template, you may have a XSS vulnerability.
|
||||
metadata:
|
||||
cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')"
|
||||
owasp: "A1: Injection"
|
||||
references:
|
||||
- https://golang.org/pkg/html/template/#HTML
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-not: template.HTML("..." + "...")
|
||||
- pattern-either:
|
||||
- pattern: template.HTML($T + $X, ...)
|
||||
- pattern: template.HTML(fmt.$P("...", ...), ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$T = $FXN(..., $T, ...)
|
||||
...
|
||||
template.HTML($T, ...)
|
||||
- pattern: |
|
||||
$T = fmt.$P("...", ...)
|
||||
...
|
||||
template.HTML($T, ...)
|
||||
- pattern: |
|
||||
$T, $ERR = fmt.$P("...", ...)
|
||||
...
|
||||
template.HTML($T, ...)
|
||||
- pattern: |
|
||||
$T = $X + $Y
|
||||
...
|
||||
template.HTML($T, ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$OTHER, $ERR = fmt.$P(..., $T, ...)
|
||||
...
|
||||
template.HTML($OTHER, ...)
|
|
@ -1,35 +0,0 @@
|
|||
rules:
|
||||
- id: pprof-debug-exposure
|
||||
metadata:
|
||||
cwe: "CWE-489: Active Debug Code"
|
||||
owasp: "A6: Security Misconfiguration"
|
||||
source-rule-url: https://github.com/securego/gosec#available-rules
|
||||
references:
|
||||
- https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
message: >-
|
||||
The profiling 'pprof' endpoint is automatically exposed on /debug/pprof.
|
||||
This could leak information about the server.
|
||||
Instead, use `import "net/http/pprof"`. See
|
||||
https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/
|
||||
for more information and mitigation.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-inside: |
|
||||
import _ "net/http/pprof"
|
||||
...
|
||||
- pattern-inside: |
|
||||
func $ANY(...) {
|
||||
...
|
||||
}
|
||||
- pattern-not-inside: |
|
||||
$MUX = http.NewServeMux(...)
|
||||
...
|
||||
http.ListenAndServe($ADDR, $MUX)
|
||||
- pattern-not: http.ListenAndServe("=~/^localhost.*/", ...)
|
||||
- pattern-not: http.ListenAndServe("=~/^127[.]0[.]0[.]1.*/", ...)
|
||||
- pattern: http.ListenAndServe(...)
|
|
@ -1,47 +0,0 @@
|
|||
rules:
|
||||
- id: unescaped-data-in-htmlattr
|
||||
message: >-
|
||||
Found a formatted template string passed to 'template.
|
||||
HTMLAttr()'. 'template.HTMLAttr()' does not escape contents.
|
||||
Be absolutely sure there is no user-controlled data in this template or
|
||||
validate and sanitize the data before passing it into the template.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
owasp: "A1: Injection"
|
||||
references:
|
||||
- https://golang.org/pkg/html/template/#HTMLAttr
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern-either:
|
||||
- pattern: template.HTMLAttr($T + $X, ...)
|
||||
- pattern: template.HTMLAttr(fmt.$P("...", ...), ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$T = $FXN(..., $T, ...)
|
||||
...
|
||||
template.HTMLAttr($T, ...)
|
||||
- pattern: |
|
||||
$T = fmt.$P("...", ...)
|
||||
...
|
||||
template.HTMLAttr($T, ...)
|
||||
- pattern: |
|
||||
$T, $ERR = fmt.$P("...", ...)
|
||||
...
|
||||
template.HTMLAttr($T, ...)
|
||||
- pattern: |
|
||||
$T = $X + $Y
|
||||
...
|
||||
template.HTMLAttr($T, ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$OTHER, $ERR = fmt.$P(..., $T, ...)
|
||||
...
|
||||
template.HTMLAttr($OTHER, ...)
|
|
@ -1,46 +0,0 @@
|
|||
rules:
|
||||
- id: unescaped-data-in-js
|
||||
message: >-
|
||||
Found a formatted template string passed to 'template.JS()'.
|
||||
'template.JS()' does not escape contents. Be absolutely sure
|
||||
there is no user-controlled data in this template.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
owasp: "A1: Injection"
|
||||
references:
|
||||
- https://golang.org/pkg/html/template/#JS
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern-either:
|
||||
- pattern: template.JS($T + $X, ...)
|
||||
- pattern: template.JS(fmt.$P("...", ...), ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$T = $FXN(..., $T, ...)
|
||||
...
|
||||
template.JS($T, ...)
|
||||
- pattern: |
|
||||
$T = fmt.$P("...", ...)
|
||||
...
|
||||
template.JS($T, ...)
|
||||
- pattern: |
|
||||
$T, $ERR = fmt.$P("...", ...)
|
||||
...
|
||||
template.JS($T, ...)
|
||||
- pattern: |
|
||||
$T = $X + $Y
|
||||
...
|
||||
template.JS($T, ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$OTHER, $ERR = fmt.$P(..., $T, ...)
|
||||
...
|
||||
template.JS($OTHER, ...)
|
|
@ -1,48 +0,0 @@
|
|||
rules:
|
||||
- id: unescaped-data-in-url
|
||||
message: >-
|
||||
Found a formatted template string passed to 'template.URL()'.
|
||||
'template.URL()' does not escape contents, and this could result in XSS (cross-site scripting)
|
||||
and therefore confidential data being stolen.
|
||||
Sanitize data coming into this function or make sure that
|
||||
no user-controlled input is coming into the function.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
owasp: "A1: Injection"
|
||||
references:
|
||||
- https://golang.org/pkg/html/template/#URL
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern-either:
|
||||
- pattern: template.URL($T + $X, ...)
|
||||
- pattern: template.URL(fmt.$P("...", ...), ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$T = $FXN(..., $T, ...)
|
||||
...
|
||||
template.URL($T, ...)
|
||||
- pattern: |
|
||||
$T = fmt.$P("...", ...)
|
||||
...
|
||||
template.URL($T, ...)
|
||||
- pattern: |
|
||||
$T, $ERR = fmt.$P("...", ...)
|
||||
...
|
||||
template.URL($T, ...)
|
||||
- pattern: |
|
||||
$T = $X + $Y
|
||||
...
|
||||
template.URL($T, ...)
|
||||
- pattern: |
|
||||
$T = "..."
|
||||
...
|
||||
$OTHER, $ERR = fmt.$P(..., $T, ...)
|
||||
...
|
||||
template.URL($OTHER, ...)
|
|
@ -1,18 +0,0 @@
|
|||
rules:
|
||||
- id: use-tls
|
||||
pattern: http.ListenAndServe($ADDR, $HANDLER)
|
||||
fix: http.ListenAndServeTLS($ADDR, certFile, keyFile, $HANDLER)
|
||||
metadata:
|
||||
cwe: "CWE-319: Cleartext Transmission of Sensitive Information"
|
||||
owasp: "A3: Sensitive Data Exposure"
|
||||
references:
|
||||
- https://golang.org/pkg/net/http/#ListenAndServeTLS
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
message: >-
|
||||
Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead.
|
||||
See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information.
|
||||
languages: [go]
|
||||
severity: WARNING
|
|
@ -1,61 +0,0 @@
|
|||
rules:
|
||||
- id: wip-xss-using-responsewriter-and-printf
|
||||
patterns:
|
||||
- pattern-inside: |
|
||||
func $FUNC(..., $W http.ResponseWriter, ...) {
|
||||
...
|
||||
var $TEMPLATE = "..."
|
||||
...
|
||||
$W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...)
|
||||
...
|
||||
}
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
$PARAMS = r.URL.Query()
|
||||
...
|
||||
$DATA, $ERR := $PARAMS[...]
|
||||
...
|
||||
$INTERM = $ANYTHING(..., $DATA, ...)
|
||||
...
|
||||
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
|
||||
- pattern: |
|
||||
$PARAMS = r.URL.Query()
|
||||
...
|
||||
$DATA, $ERR := $PARAMS[...]
|
||||
...
|
||||
$INTERM = $DATA[...]
|
||||
...
|
||||
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
|
||||
- pattern: |
|
||||
$DATA, $ERR := r.URL.Query()[...]
|
||||
...
|
||||
$INTERM = $DATA[...]
|
||||
...
|
||||
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
|
||||
- pattern: |
|
||||
$DATA, $ERR := r.URL.Query()[...]
|
||||
...
|
||||
$INTERM = $ANYTHING(..., $DATA, ...)
|
||||
...
|
||||
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
|
||||
- pattern: |
|
||||
$PARAMS = r.URL.Query()
|
||||
...
|
||||
$DATA, $ERR := $PARAMS[...]
|
||||
...
|
||||
$W.Write([]byte(fmt.$PRINTF(..., $DATA, ...)))
|
||||
message: >-
|
||||
Found data going from url query parameters into formatted data written to ResponseWriter.
|
||||
This could be XSS and should not be done. If you must do this, ensure your data
|
||||
is
|
||||
sanitized or escaped.
|
||||
metadata:
|
||||
cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')"
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: WARNING
|
||||
languages:
|
||||
- go
|
|
@ -1,18 +0,0 @@
|
|||
rules:
|
||||
- id: reflect-makefunc
|
||||
message: >-
|
||||
'reflect.MakeFunc' detected. This will sidestep protections that are
|
||||
normally afforded by Go's type system. Audit this call and be sure that
|
||||
user input cannot be used to affect the code generated by MakeFunc;
|
||||
otherwise, you will have a serious security vulnerability.
|
||||
metadata:
|
||||
owasp: "A8: Insecure Deserialization"
|
||||
cwe: "CWE-913: Improper Control of Dynamically-Managed Code Resources"
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
||||
pattern: reflect.MakeFunc(...)
|
||||
languages:
|
||||
- go
|
|
@ -1,52 +0,0 @@
|
|||
rules:
|
||||
- id: gosql-sqli
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern: $DB.$METHOD(...,$QUERY,...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$QUERY = $X + $Y
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY += $X
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY = fmt.Sprintf("...", $PARAM1, ...)
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY += "..."
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY = "..." + "..."
|
||||
...
|
||||
- pattern: $DB.$METHOD(..., $X + $Y, ...)
|
||||
- pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$DB, ... = sql.Open(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
func $FUNCNAME(..., $DB *sql.DB, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-not: $DB.$METHOD(..., "..." + "...", ...)
|
||||
- metavariable-regex:
|
||||
metavariable: $METHOD
|
||||
regex: ^(Exec|ExecContent|Query|QueryContext|QueryRow|QueryRowContext)$
|
||||
languages:
|
||||
- go
|
||||
message: >-
|
||||
Detected string concatenation with a non-literal variable in a "database/sql"
|
||||
Go SQL statement. This could lead to SQL injection if the variable is user-controlled
|
||||
and not properly sanitized. In order to prevent SQL injection,
|
||||
used parameterized queries or prepared statements instead.
|
||||
You can use prepared statements with the 'Prepare' and 'PrepareContext' calls.
|
||||
metadata:
|
||||
references:
|
||||
- https://golang.org/pkg/database/sql/
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
|
@ -1,55 +0,0 @@
|
|||
rules:
|
||||
- id: pg-orm-sqli
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern: $DB.$METHOD(...,$QUERY,...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$QUERY = $X + $Y
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY += $X
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY = fmt.Sprintf("...", $PARAM1, ...)
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY += "..."
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY = "..." + "..."
|
||||
...
|
||||
- pattern: |
|
||||
$DB.$INTFUNC1(...).$METHOD(..., $X + $Y, ...).$INTFUNC2(...)
|
||||
- pattern: |
|
||||
$DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...)
|
||||
- pattern-inside: |
|
||||
$DB = pg.Connect(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
func $FUNCNAME(..., $DB *pg.DB, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-not: |
|
||||
$DB.$INTFUNC1(...).$METHOD(..., "..." + "...", ...).$INTFUNC2(...)
|
||||
- pattern-not: path.Join(...)
|
||||
- metavariable-regex:
|
||||
metavariable: $METHOD
|
||||
regex: ^(Where|WhereOr|Join|GroupExpr|OrderExpr|ColumnExpr)$
|
||||
languages:
|
||||
- go
|
||||
message: >-
|
||||
Detected string concatenation with a non-literal variable in a go-pg ORM
|
||||
SQL statement. This could lead to SQL injection if the variable is user-controlled
|
||||
and not properly sanitized. In order to prevent SQL injection,
|
||||
do not use strings concatenated with user-controlled input.
|
||||
Instead, use parameterized statements.
|
||||
metadata:
|
||||
references:
|
||||
- https://pg.uptrace.dev/queries/
|
||||
category: security
|
||||
technology:
|
||||
- go-pg
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
|
@ -1,55 +0,0 @@
|
|||
rules:
|
||||
- id: pg-sqli
|
||||
languages:
|
||||
- go
|
||||
message: >-
|
||||
Detected string concatenation with a non-literal variable in a go-pg
|
||||
SQL statement. This could lead to SQL injection if the variable is user-controlled
|
||||
and not properly sanitized. In order to prevent SQL injection,
|
||||
used parameterized queries instead of string concatenation. You can use parameterized
|
||||
queries like so:
|
||||
'(SELECT ? FROM table, data1)'
|
||||
metadata:
|
||||
references:
|
||||
- https://pg.uptrace.dev/
|
||||
- https://pkg.go.dev/github.com/go-pg/pg/v10
|
||||
category: security
|
||||
technology:
|
||||
- go-pg
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern: |
|
||||
$DB.$METHOD(...,$QUERY,...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$QUERY = $X + $Y
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY += $X
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY = fmt.Sprintf("...", $PARAM1, ...)
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY += "..."
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY = "..." + "..."
|
||||
...
|
||||
- pattern: $DB.$METHOD(..., $X + $Y, ...)
|
||||
- pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$DB = pg.Connect(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
func $FUNCNAME(..., $DB *pg.DB, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-not: $DB.$METHOD(..., "..." + "...", ...)
|
||||
- metavariable-regex:
|
||||
metavariable: $METHOD
|
||||
regex: ^(Exec|ExecContext|ExecOne|ExecOneContext|Query|QueryOne|QueryContext|QueryOneContext)$
|
|
@ -1,59 +0,0 @@
|
|||
rules:
|
||||
- id: pgx-sqli
|
||||
languages:
|
||||
- go
|
||||
message: >-
|
||||
Detected string concatenation with a non-literal variable in a pgx
|
||||
Go SQL statement. This could lead to SQL injection if the variable is user-controlled
|
||||
and not properly sanitized. In order to prevent SQL injection,
|
||||
used parameterized queries instead. You can use parameterized queries like so:
|
||||
(`SELECT $1 FROM table`, `data1)
|
||||
metadata:
|
||||
references:
|
||||
- https://github.com/jackc/pgx
|
||||
- https://pkg.go.dev/github.com/jackc/pgx/v4#hdr-Connection_Pool
|
||||
category: security
|
||||
technology:
|
||||
- pgx
|
||||
confidence: MEDIUM
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern: $DB.$METHOD(...,$QUERY,...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$QUERY = $X + $Y
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY += $X
|
||||
...
|
||||
- pattern-inside: |
|
||||
$QUERY = fmt.Sprintf("...", $PARAM1, ...)
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY += "..."
|
||||
...
|
||||
- pattern-not-inside: |
|
||||
$QUERY = "..." + "..."
|
||||
...
|
||||
- pattern: $DB.$METHOD(..., $X + $Y, ...)
|
||||
- pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
$DB, ... = pgx.Connect(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
$DB, ... = pgx.NewConnPool(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
$DB, ... = pgx.ConnectConfig(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
func $FUNCNAME(..., $DB *pgx.Conn, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-not: $DB.$METHOD(..., "..." + "...", ...)
|
||||
- metavariable-regex:
|
||||
metavariable: $METHOD
|
||||
regex: ^(Exec|ExecEx|Query|QueryEx|QueryRow|QueryRowEx)$
|
||||
severity: ERROR
|
|
@ -1,34 +0,0 @@
|
|||
rules:
|
||||
- id: unsafe-reflect-by-name
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
$SMTH.MethodByName($NAME,...)
|
||||
- pattern: |
|
||||
$SMTH.FieldByName($NAME,...)
|
||||
- pattern-not: |
|
||||
$SMTH.MethodByName("...",...)
|
||||
- pattern-not: |
|
||||
$SMTH.FieldByName("...",...)
|
||||
- pattern-inside: |
|
||||
import "reflect"
|
||||
...
|
||||
message: >-
|
||||
If an attacker can supply values that the application then uses to determine which
|
||||
method or field to invoke,
|
||||
the potential exists for the attacker to create control flow paths through the
|
||||
application
|
||||
that were not intended by the application developers.
|
||||
This attack vector may allow the attacker to bypass authentication or access control
|
||||
checks
|
||||
or otherwise cause the application to behave in an unexpected manner.
|
||||
metadata:
|
||||
cwe: "CWE-470: Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')"
|
||||
owasp: "A1: Injection"
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: WARNING
|
||||
languages:
|
||||
- go
|
|
@ -1,17 +0,0 @@
|
|||
rules:
|
||||
- id: use-of-unsafe-block
|
||||
message: >-
|
||||
Using the unsafe package in Go gives you low-level memory management
|
||||
and many of the strengths of the C language, but also steps around the type safety of Go
|
||||
and can lead to buffer overflows and possible arbitrary code execution by an attacker.
|
||||
Only use this package if you absolutely know what you're doing.
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
cwe: "CWE-242: Use of Inherently Dangerous Function"
|
||||
source_rule_url: https://github.com/securego/gosec/blob/master/rules/unsafe.go
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
pattern: unsafe.$FUNC(...)
|
|
@ -1,21 +0,0 @@
|
|||
rules:
|
||||
- id: import-text-template
|
||||
message: >-
|
||||
'text/template' does not escape HTML content. If you need
|
||||
to escape HTML content, use 'html/template' instead.
|
||||
metadata:
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
references:
|
||||
- https://www.veracode.com/blog/secure-development/use-golang-these-mistakes-could-compromise-your-apps-security
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: WARNING
|
||||
pattern: |
|
||||
import "text/template"
|
||||
languages:
|
||||
- go
|
|
@ -1,40 +0,0 @@
|
|||
rules:
|
||||
- id: no-direct-write-to-responsewriter
|
||||
languages:
|
||||
- go
|
||||
message: >-
|
||||
Detected directly writing or similar in 'http.ResponseWriter.write()'.
|
||||
This bypasses HTML escaping that prevents cross-site scripting
|
||||
vulnerabilities. Instead, use the 'html/template' package
|
||||
and render data using 'template.Execute()'.
|
||||
metadata:
|
||||
category: security
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
references:
|
||||
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
func $HANDLER(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-inside: |
|
||||
func $HANDLER(..., $WRITER *http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-inside: |
|
||||
func(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-either:
|
||||
- pattern: $WRITER.Write(...)
|
||||
- pattern: (*$WRITER).Write(...)
|
||||
- pattern-not: $WRITER.Write([]byte("..."))
|
||||
severity: WARNING
|
|
@ -1,33 +0,0 @@
|
|||
rules:
|
||||
- id: no-fprintf-to-responsewriter
|
||||
message: >-
|
||||
Detected 'Fprintf' or similar writing to 'http.ResponseWriter'.
|
||||
This bypasses HTML escaping that prevents cross-site scripting
|
||||
vulnerabilities. Instead, use the 'html/template' package
|
||||
to render data to users.
|
||||
metadata:
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
references:
|
||||
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
func $HANDLER(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-inside: |
|
||||
func(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-not: fmt.$PRINTF($WRITER, "...")
|
||||
- pattern: fmt.$PRINTF($WRITER, ...)
|
||||
languages:
|
||||
- go
|
|
@ -1,24 +0,0 @@
|
|||
rules:
|
||||
- id: no-interpolation-in-tag
|
||||
message: >-
|
||||
Detected template variable interpolation in an HTML tag.
|
||||
This is potentially vulnerable to cross-site scripting (XSS)
|
||||
attacks because a malicious actor has control over HTML
|
||||
but without the need to use escaped characters. Use explicit
|
||||
tags instead.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
references:
|
||||
- https://github.com/golang/go/issues/19669
|
||||
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
|
||||
category: security
|
||||
technology:
|
||||
- generic
|
||||
confidence: MEDIUM
|
||||
languages:
|
||||
- generic
|
||||
severity: WARNING
|
||||
pattern: <{{ ... }} ... >
|
|
@ -1,28 +0,0 @@
|
|||
rules:
|
||||
- id: no-interpolation-js-template-string
|
||||
message: >-
|
||||
Detected template variable interpolation in a JavaScript
|
||||
template string. This is potentially vulnerable to
|
||||
cross-site scripting (XSS) attacks because a malicious
|
||||
actor has control over JavaScript but without the need
|
||||
to use escaped characters. Instead, obtain this variable
|
||||
outside of the template string and ensure your template
|
||||
is properly escaped.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
references:
|
||||
- https://github.com/golang/go/issues/9200#issuecomment-66100328
|
||||
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
|
||||
category: security
|
||||
technology:
|
||||
- generic
|
||||
confidence: MEDIUM
|
||||
languages:
|
||||
- generic
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-inside: <script ...> ... ... ... ... ... </script>
|
||||
- pattern: "` ... {{ ... }} ...`"
|
|
@ -1,34 +0,0 @@
|
|||
rules:
|
||||
- id: no-io-writestring-to-responsewriter
|
||||
message: >-
|
||||
Detected 'io.WriteString()' writing directly to 'http.ResponseWriter'.
|
||||
This bypasses HTML escaping that prevents cross-site scripting
|
||||
vulnerabilities. Instead, use the 'html/template' package
|
||||
to render data to users.
|
||||
metadata:
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
references:
|
||||
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
|
||||
- https://golang.org/pkg/io/#WriteString
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
func $HANDLER(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-inside: |
|
||||
func(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-not: io.WriteString($WRITER, "...")
|
||||
- pattern: io.WriteString($WRITER, $STRING)
|
||||
languages:
|
||||
- go
|
|
@ -1,33 +0,0 @@
|
|||
rules:
|
||||
- id: no-printf-in-responsewriter
|
||||
message: >-
|
||||
Detected 'printf' or similar in 'http.ResponseWriter.write()'.
|
||||
This bypasses HTML escaping that prevents cross-site scripting
|
||||
vulnerabilities. Instead, use the 'html/template' package
|
||||
to render data to users.
|
||||
metadata:
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
references:
|
||||
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
func $HANDLER(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern-inside: |
|
||||
func(..., $WRITER http.ResponseWriter, ...) {
|
||||
...
|
||||
}
|
||||
- pattern: |
|
||||
$WRITER.Write(<... fmt.$PRINTF(...) ...>, ...)
|
||||
languages:
|
||||
- go
|
|
@ -1,34 +0,0 @@
|
|||
rules:
|
||||
- id: unsafe-template-type
|
||||
message: >-
|
||||
Semgrep could not determine that the argument to 'template.HTML()'
|
||||
is a constant. 'template.HTML()' and similar does not escape contents.
|
||||
Be absolutely sure there is no user-controlled data in this
|
||||
template. If user data can reach this template, you may have
|
||||
a XSS vulnerability. Instead, do not use this function and
|
||||
use 'template.Execute()'.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
owasp: "A7: Cross-Site Scripting (XSS)"
|
||||
references:
|
||||
- https://golang.org/pkg/html/template/#HTML
|
||||
- https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/vulnerability/xss/xss.go#L33
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
patterns:
|
||||
- pattern-not: template.$ANY("..." + "...")
|
||||
- pattern-not: template.$ANY("...")
|
||||
- pattern-either:
|
||||
- pattern: template.HTML(...)
|
||||
- pattern: template.CSS(...)
|
||||
- pattern: template.HTMLAttr(...)
|
||||
- pattern: template.JS(...)
|
||||
- pattern: template.JSStr(...)
|
||||
- pattern: template.Srcset(...)
|
||||
- pattern: template.URL(...)
|
|
@ -1,15 +0,0 @@
|
|||
rules:
|
||||
- id: bad-tmp-file-creation
|
||||
message: File creation in shared tmp directory without using ioutil.Tempfile
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
metadata:
|
||||
cwe: "CWE-377: Insecure Temporary File"
|
||||
source-rule-url: https://github.com/securego/gosec
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
pattern-either:
|
||||
- pattern: ioutil.WriteFile("=~//tmp/.*$/", ...)
|
||||
- pattern: os.Create("=~//tmp/.*$/", ...)
|
|
@ -1,59 +0,0 @@
|
|||
rules:
|
||||
- id: potential-dos-via-decompression-bomb
|
||||
message: >-
|
||||
Detected a possible denial-of-service via a zip bomb attack. By limiting the max
|
||||
bytes read, you can mitigate this attack.
|
||||
`io.CopyN()` can specify a size. Refer to https://bomb.codes/ to learn more about
|
||||
this attack and other ways to mitigate
|
||||
it.
|
||||
severity: WARNING
|
||||
languages: [go]
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern: io.Copy(...)
|
||||
- pattern: io.CopyBuffer(...)
|
||||
- pattern-either:
|
||||
- pattern-inside: |
|
||||
gzip.NewReader(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
zlib.NewReader(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
zlib.NewReaderDict(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
bzip2.NewReader(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
flate.NewReader(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
flate.NewReaderDict(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
lzw.NewReader(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
tar.NewReader(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
zip.NewReader(...)
|
||||
...
|
||||
- pattern-inside: |
|
||||
zip.OpenReader(...)
|
||||
...
|
||||
fix-regex:
|
||||
regex: (.*)(Copy|CopyBuffer)\((.*?),(.*?)(\)|,.*\))
|
||||
replacement: \1CopyN(\3, \4, 1024*1024*256)
|
||||
metadata:
|
||||
cwe: "CWE-400: Uncontrolled Resource Consumption"
|
||||
source-rule-url: https://github.com/securego/gosec
|
||||
references:
|
||||
- https://bomb.codes/
|
||||
- https://golang.org/pkg/io/#CopyN
|
||||
- https://github.com/securego/gosec/blob/master/rules/decompression-bomb.go
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
|
@ -1,41 +0,0 @@
|
|||
rules:
|
||||
- id: filepath-clean-misuse
|
||||
message: >-
|
||||
`Clean` is not intended to sanitize against path traversal attacks.
|
||||
This function is for finding the shortest path name equivalent to the given input.
|
||||
Using `Clean` to sanitize file reads may expose this application to
|
||||
path traversal attacks, where an attacker could access arbitrary files on the server.
|
||||
To fix this easily, write this: `filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/")))`
|
||||
However, a better solution is using the `SecureJoin` function in the package `filepath-securejoin`.
|
||||
See https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme.
|
||||
severity: ERROR
|
||||
languages: [go]
|
||||
mode: taint
|
||||
pattern-sources:
|
||||
- pattern-either:
|
||||
- pattern: "($REQUEST : *http.Request).$ANYTHING"
|
||||
- pattern: "($REQUEST : http.Request).$ANYTHING"
|
||||
pattern-sinks:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: filepath.Clean($...INNER)
|
||||
- pattern: path.Clean($...INNER)
|
||||
pattern-sanitizers:
|
||||
- pattern-either:
|
||||
- pattern: |
|
||||
"/" + ...
|
||||
fix: filepath.FromSlash(filepath.Clean("/"+strings.Trim($...INNER, "/")))
|
||||
metadata:
|
||||
references:
|
||||
- https://pkg.go.dev/path#Clean
|
||||
- http://technosophos.com/2016/03/31/go-quickly-cleaning-filepaths.html
|
||||
- https://labs.detectify.com/2021/12/15/zero-day-path-traversal-grafana/
|
||||
- https://dzx.cz/2021/04/02/go_path_traversal/
|
||||
- https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme
|
||||
cwe: 'CWE-22: Path Traversal'
|
||||
owasp:
|
||||
- 'A03:2021 - Injection'
|
||||
- 'A01:2017 - Injection'
|
||||
category: security
|
||||
technology:
|
||||
- go
|
|
@ -1,47 +0,0 @@
|
|||
rules:
|
||||
- id: raw-html-format
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
message: >-
|
||||
Detected user input flowing into a manually constructed HTML string. You may be
|
||||
accidentally bypassing secure methods
|
||||
of rendering HTML by manually constructing HTML and this could create a cross-site
|
||||
scripting vulnerability, which could
|
||||
let attackers steal sensitive user data. Use the `html/template` package which
|
||||
will safely render HTML instead, or inspect
|
||||
that the HTML is rendered safely.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\
|
||||
\ Scripting')"
|
||||
owasp:
|
||||
- A07:2017
|
||||
- A03:2021
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
references:
|
||||
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
|
||||
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
|
||||
confidence: HIGH
|
||||
mode: taint
|
||||
pattern-sanitizers:
|
||||
- pattern: html.EscapeString(...)
|
||||
pattern-sources:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: "($REQUEST : *http.Request).$ANYTHING"
|
||||
- pattern: "($REQUEST : http.Request).$ANYTHING"
|
||||
pattern-sinks:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: fmt.Printf("$HTMLSTR", ...)
|
||||
- pattern: fmt.Sprintf("$HTMLSTR", ...)
|
||||
- pattern: fmt.Fprintf($W, "$HTMLSTR", ...)
|
||||
- pattern: '"$HTMLSTR" + ...'
|
||||
- metavariable-pattern:
|
||||
metavariable: $HTMLSTR
|
||||
language: generic
|
||||
pattern: <$TAG ...
|
|
@ -1,50 +0,0 @@
|
|||
rules:
|
||||
- id: tainted-sql-string
|
||||
languages: [go]
|
||||
message: >-
|
||||
User data flows into this manually-constructed SQL string. User data
|
||||
can be safely inserted into SQL strings using prepared statements or an
|
||||
object-relational mapper (ORM). Manually-constructed SQL strings is a
|
||||
possible indicator of SQL injection, which could let an attacker steal
|
||||
or manipulate data from the database.
|
||||
Instead, use prepared statements (`db.Query("SELECT * FROM t WHERE id = ?", id)`)
|
||||
or a safe library.
|
||||
metadata:
|
||||
cwe:
|
||||
"CWE-89: Improper Neutralization of Special Elements used in an SQL Command\
|
||||
\ ('SQL Injection')"
|
||||
owasp:
|
||||
- A10:2021
|
||||
- A01:2017
|
||||
references:
|
||||
- https://golang.org/doc/database/sql-injection
|
||||
- https://www.stackhawk.com/blog/golang-sql-injection-guide-examples-and-prevention/
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: HIGH
|
||||
mode: taint
|
||||
severity: WARNING
|
||||
pattern-sources:
|
||||
- pattern-either:
|
||||
- pattern: "($REQUEST : *http.Request).$ANYTHING"
|
||||
- pattern: "($REQUEST : http.Request).$ANYTHING"
|
||||
pattern-sinks:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern: |
|
||||
"$SQLSTR" + ...
|
||||
- metavariable-regex:
|
||||
metavariable: $SQLSTR
|
||||
regex: (?i)(select|delete|insert|create|update|alter|drop).*
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: fmt.Fprintf($F, "$SQLSTR", ...)
|
||||
- pattern: fmt.Sprintf("$SQLSTR", ...)
|
||||
- pattern: fmt.Printf("$SQLSTR", ...)
|
||||
- metavariable-regex:
|
||||
metavariable: $SQLSTR
|
||||
regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).*
|
||||
pattern-sanitizers:
|
||||
- pattern: strconv.Atoi(...)
|
|
@ -1,46 +0,0 @@
|
|||
rules:
|
||||
- id: tainted-url-host
|
||||
languages:
|
||||
- go
|
||||
message:
|
||||
User data flows into the host portion of this manually-constructed URL.
|
||||
This could allow an attacker to send data to their own server, potentially exposing
|
||||
sensitive data such as cookies or authorization information sent with this request.
|
||||
They could also probe internal servers or other resources that the server runnig
|
||||
this code can access. (This is called server-side request forgery, or SSRF.) Do
|
||||
not allow arbitrary hosts. Instead, create an allowlist for approved hosts hardcode
|
||||
the correct host.
|
||||
metadata:
|
||||
cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
|
||||
owasp:
|
||||
- A10:2021
|
||||
- A01:2017
|
||||
references:
|
||||
- https://goteleport.com/blog/ssrf-attacks/
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
|
||||
confidence: HIGH
|
||||
mode: taint
|
||||
pattern-sinks:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- patterns:
|
||||
- pattern-either:
|
||||
- pattern: fmt.Fprintf($F, "$URLSTR", ...)
|
||||
- pattern: fmt.Sprintf("$URLSTR", ...)
|
||||
- pattern: fmt.Printf("$URLSTR", ...)
|
||||
- metavariable-regex:
|
||||
metavariable: $URLSTR
|
||||
regex: http(s?)://%(v|s|q).*
|
||||
- patterns:
|
||||
- pattern: '"$URLSTR" + ...'
|
||||
- metavariable-regex:
|
||||
metavariable: $URLSTR
|
||||
regex: \w+://.*
|
||||
pattern-sources:
|
||||
- pattern-either:
|
||||
- pattern: "($REQUEST : *http.Request).$ANYTHING"
|
||||
- pattern: "($REQUEST : http.Request).$ANYTHING"
|
||||
severity: WARNING
|
|
@ -1,20 +0,0 @@
|
|||
rules:
|
||||
- id: path-traversal-inside-zip-extraction
|
||||
message: File traversal when extracting zip archive
|
||||
metadata:
|
||||
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')"
|
||||
source_rule_url: https://github.com/securego/gosec/issues/205
|
||||
category: security
|
||||
technology:
|
||||
- go
|
||||
confidence: MEDIUM
|
||||
languages: [go]
|
||||
severity: WARNING
|
||||
pattern: |
|
||||
reader, $ERR := zip.OpenReader($ARCHIVE)
|
||||
...
|
||||
for _, $FILE := range reader.File {
|
||||
...
|
||||
path := filepath.Join($TARGET, $FILE.Name)
|
||||
...
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
rules:
|
||||
- id: dangerous-execution
|
||||
message: >-
|
||||
Detected non-static script inside otto VM. Audit the input to 'VM.Run'.
|
||||
If unverified user data can reach this call site, this is a code injection
|
||||
vulnerability. A malicious actor can inject a malicious script to execute
|
||||
arbitrary code.
|
||||
metadata:
|
||||
cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
|
||||
owasp: "A1: Injection"
|
||||
category: security
|
||||
technology:
|
||||
- otto
|
||||
- vm
|
||||
confidence: MEDIUM
|
||||
severity: ERROR
|
||||
patterns:
|
||||
- pattern-inside: |
|
||||
$VM = otto.New(...)
|
||||
...
|
||||
- pattern-not: $VM.Run("...", ...)
|
||||
- pattern: $VM.Run(...)
|
||||
languages:
|
||||
- go
|
|
@ -1,26 +0,0 @@
|
|||
rules:
|
||||
- id: go-insecure-templates
|
||||
patterns:
|
||||
- pattern-inside: |
|
||||
import "html/template"
|
||||
...
|
||||
- pattern-either:
|
||||
- pattern: var $VAR template.HTML = $EXP
|
||||
- pattern: var $VAR template.CSS = $EXP
|
||||
- pattern: var $VAR template.HTMLAttr = $EXP
|
||||
- pattern: var $VAR template.JS = $EXP
|
||||
- pattern: var $VAR template.JSStr = $EXP
|
||||
- pattern: var $VAR template.Srcset = $EXP
|
||||
message: >-
|
||||
usage of insecure template types. They are documented as a security risk. See https://golang.org/pkg/html/template/#HTML.
|
||||
severity: WARNING
|
||||
metadata:
|
||||
references:
|
||||
- https://golang.org/pkg/html/template/#HTML
|
||||
- https://twitter.com/empijei/status/1275177219011350528
|
||||
category: security
|
||||
technology:
|
||||
- template
|
||||
confidence: MEDIUM
|
||||
languages:
|
||||
- go
|
Loading…
Add table
Reference in a new issue