gosec - Golang Security Checker

gosec - Golang Security Checker

Inspects source code for security problems by scanning the Go AST.

License

Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License here.

Project status

CII Best Practices Build Status Coverage Status GoReport GoDoc Docs Downloads Docker Pulls Slack

Install

CI Installation

gosec_vX.Y.Z_OS.tar.gz" | sha256sum -c - gosec --help ">
# binary will be $(go env GOPATH)/bin/gosec
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(go env GOPATH)/bin vX.Y.Z

# or install it into ./bin/
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z

# In alpine linux (as it does not come with curl by default)
wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z

# If you want to use the checksums provided on the "Releases" page
# then you will have to download a tar.gz file for your operating system instead of a binary file
wget https://github.com/securego/gosec/releases/download/vX.Y.Z/gosec_vX.Y.Z_OS.tar.gz

# The file will be in the current folder where you run the command
# and you can check the checksum like this
echo "  gosec_vX.Y.Z_OS.tar.gz" | sha256sum -c -

gosec --help

GitHub Action

You can run gosec as a GitHub action as follows:

name: Run Gosec
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
jobs:
  tests:
    runs-on: ubuntu-latest
    env:
      GO111MODULE: on
    steps:
      - name: Checkout Source
        uses: actions/checkout@v2
      - name: Run Gosec Security Scanner
        uses: securego/gosec@master
        with:
          args: ./...

Integrating with code scanning

You can integrate third-party code analysis tools with GitHub code scanning by uploading data as SARIF files.

The workflow shows an example of running the gosec as a step in a GitHub action workflow which outputs the results.sarif file. The workflow then uploads the results.sarif file to GitHub using the upload-sarif action.

name: "Security Scan"

# Run workflow each time code is pushed to your repository and on a schedule.
# The scheduled workflow runs every at 00:00 on Sunday UTC time.
on:
  push:
  schedule:
  - cron: '0 0 * * 0'

jobs:
  tests:
    runs-on: ubuntu-latest
    env:
      GO111MODULE: on
    steps:
      - name: Checkout Source
        uses: actions/checkout@v2
      - name: Run Gosec Security Scanner
        uses: securego/gosec@master
        with:
          # we let the report trigger content trigger a failure using the GitHub Security features.
          args: '-no-fail -fmt sarif -out results.sarif ./...'
      - name: Upload SARIF file
        uses: github/codeql-action/upload-sarif@v1
        with:
          # Path to SARIF file relative to the root of the repository
          sarif_file: results.sarif

Local Installation

go get -u github.com/securego/gosec/v2/cmd/gosec

Usage

Gosec can be configured to only run a subset of rules, to exclude certain file paths, and produce reports in different formats. By default all rules will be run against the supplied input files. To recursively scan from the current directory you can supply ./... as the input argument.

Available rules

  • G101: Look for hard coded credentials
  • G102: Bind to all interfaces
  • G103: Audit the use of unsafe block
  • G104: Audit errors not checked
  • G106: Audit the use of ssh.InsecureIgnoreHostKey
  • G107: Url provided to HTTP request as taint input
  • G108: Profiling endpoint automatically exposed on /debug/pprof
  • G109: Potential Integer overflow made by strconv.Atoi result conversion to int16/32
  • G110: Potential DoS vulnerability via decompression bomb
  • G201: SQL query construction using format string
  • G202: SQL query construction using string concatenation
  • G203: Use of unescaped data in HTML templates
  • G204: Audit use of command execution
  • G301: Poor file permissions used when creating a directory
  • G302: Poor file permissions used with chmod
  • G303: Creating tempfile using a predictable path
  • G304: File path provided as taint input
  • G305: File traversal when extracting zip/tar archive
  • G306: Poor file permissions used when writing to a new file
  • G307: Deferring a method which returns an error
  • G401: Detect the usage of DES, RC4, MD5 or SHA1
  • G402: Look for bad TLS connection settings
  • G403: Ensure minimum RSA key length of 2048 bits
  • G404: Insecure random number source (rand)
  • G501: Import blocklist: crypto/md5
  • G502: Import blocklist: crypto/des
  • G503: Import blocklist: crypto/rc4
  • G504: Import blocklist: net/http/cgi
  • G505: Import blocklist: crypto/sha1
  • G601: Implicit memory aliasing of items from a range statement

Retired rules

Selecting rules

By default, gosec will run all rules against the supplied file paths. It is however possible to select a subset of rules to run via the -include= flag, or to specify a set of rules to explicitly exclude using the -exclude= flag.

# Run a specific set of rules
$ gosec -include=G101,G203,G401 ./...

# Run everything except for rule G303
$ gosec -exclude=G303 ./...

CWE Mapping

Every issue detected by gosec is mapped to a CWE (Common Weakness Enumeration) which describes in more generic terms the vulnerability. The exact mapping can be found here.

Configuration

A number of global settings can be provided in a configuration file as follows:

{
    "global": {
        "nosec": "enabled",
        "audit": "enabled"
    }
}
  • nosec: this setting will overwrite all #nosec directives defined throughout the code base
  • audit: runs in audit mode which enables addition checks that for normal code analysis might be too nosy
# Run with a global configuration file
$ gosec -conf config.json .

Also some rules accept configuration. For instance on rule G104, it is possible to define packages along with a list of functions which will be skipped when auditing the not checked errors:

{
    "G104": {
        "io/ioutil": ["WriteFile"]
    }
}

You can also configure the hard-coded credentials rule G101 with additional patters, or adjust the entropy threshold:

{
    "G101": {
        "pattern": "(?i)passwd|pass|password|pwd|secret|private_key|token",
         "ignore_entropy": false,
         "entropy_threshold": "80.0",
         "per_char_threshold": "3.0",
         "truncate": "32"
    }
}

Dependencies

gosec will fetch automatically the dependencies of the code which is being analyzed when go module is turned on (e.g.GO111MODULE=on). If this is not the case, the dependencies need to be explicitly downloaded by running the go get -d command before the scan.

Excluding test files and folders

gosec will ignore test files across all packages and any dependencies in your vendor directory.

The scanning of test files can be enabled with the following flag:

gosec -tests ./...

Also additional folders can be excluded as follows:

 gosec -exclude-dir=rules -exclude-dir=cmd ./...

Excluding generated files

gosec can ignore generated go files with default generated code comment.

// Code generated by some generator DO NOT EDIT.
gosec -exclude-generated ./...

Annotating code

As with all automated detection tools, there will be cases of false positives. In cases where gosec reports a failure that has been manually verified as being safe, it is possible to annotate the code with a #nosec comment.

The annotation causes gosec to stop processing any further nodes within the AST so can apply to a whole block or more granularly to a single expression.

y { h := md5.New() // this will also be ignored } } ">
import "md5" // #nosec


func main(){

    /* #nosec */
    if x > y {
        h := md5.New() // this will also be ignored
    }

}

When a specific false positive has been identified and verified as safe, you may wish to suppress only that single rule (or a specific set of rules) within a section of code, while continuing to scan for other problems. To do this, you can list the rule(s) to be suppressed within the #nosec annotation, e.g: /* #nosec G401 */ or // #nosec G201 G202 G203

In some cases you may also want to revisit places where #nosec annotations have been used. To run the scanner and ignore any #nosec annotations you can do the following:

gosec -nosec=true ./...

Build tags

gosec is able to pass your Go build tags to the analyzer. They can be provided as a comma separated list as follows:

gosec -tag debug,ignore ./...

Output formats

gosec currently supports text, json, yaml, csv, sonarqube, JUnit XML, html and golint output formats. By default results will be reported to stdout, but can also be written to an output file. The output format is controlled by the -fmt flag, and the output file is controlled by the -out flag as follows:

# Write output in json format to results.json
$ gosec -fmt=json -out=results.json *.go

Results will be reported to stdout as well as to the provided output file by -stdout flag. The -verbose flag overrides the output format when stdout the results while saving them in the output file

# Write output in json format to results.json as well as stdout
$ gosec -fmt=json -out=results.json -stdout *.go

# Overrides the output format to 'text' when stdout the results, while writing it to results.json
$ gosec -fmt=json -out=results.json -stdout -verbose=text *.go

Note: gosec generates the generic issue import format for SonarQube, and a report has to be imported into SonarQube using sonar.externalIssuesReportPaths=path/to/gosec-report.json.

Development

Build

You can build the binary with:

make

Note on Sarif Types Generation

Install the tool with :

go get -u github.com/a-h/generate/cmd/schema-generate

Then generate the types with :

schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go

Most of the MarshallJSON/UnmarshalJSON are removed except the one for PropertyBag which is handy to inline the additionnal properties. The rest can be removed. The URI,ID, UUID, GUID were renamed so it fits the Golang convention defined here

Tests

You can run all unit tests using:

make test

Release

You can create a release by tagging the version as follows:

git tag v1.0.0 -m "Release version v1.0.0"
git push origin v1.0.0

The GitHub release workflow triggers immediately after the tag is pushed upstream. This flow will release the binaries using the goreleaser action and then it will build and publish the docker image into Docker Hub.

Docker image

You can also build locally the docker image by using the command:

make image

You can run the gosec tool in a container against your local Go project. You only have to mount the project into a volume as follows:

docker run --rm -it -w /<PROJECT>/ -v <YOUR PROJECT PATH>/<PROJECT>:/<PROJECT> securego/gosec /<PROJECT>/...

Note: the current working directory needs to be set with -w option in order to get successfully resolved the dependencies from go module file

Generate TLS rule

The configuration of TLS rule can be generated from Mozilla's TLS ciphers recommendation.

First you need to install the generator tool:

go get github.com/securego/gosec/v2/cmd/tlsconfig/...

You can invoke now the go generate in the root of the project:

go generate ./...

This will generate the rules/tls_config.go file which will contain the current ciphers recommendation from Mozilla.

Who is using gosec?

This is a list with some of the gosec's users.

Owner
Secure Go
Project devoted to secure programming in the Go language
Secure Go
Comments
  • Want to have a base directory concept where I can choose my root directory

    Want to have a base directory concept where I can choose my root directory

    Summary

    Want to have a base directory concept where I can choose my root directory

    Steps to reproduce the behavior

    gosec version

    go 1.13 and above

    Go version (output of 'go version')

    Operating system / Environment

    Expected behavior

    Actual behavior

  • G307: gosec starts detecting G307 (CWE-703) even with proposed way to safely handle errors

    G307: gosec starts detecting G307 (CWE-703) even with proposed way to safely handle errors

    Summary

    gosec v2.9.1 starts detecting G307 (CWE-703): Deferring unsafe method "Close" on type "*os.File" (Confidence: HIGH, Severity: MEDIUM) which could have been avoided by following https://github.com/securego/gosec/issues/512 with previous version of gosec.

    Steps to reproduce the behavior

    package main
    
    import (
            "log"
            "os"
    )
    
    func main() {
            f, err := os.Open("./testfile.txt")
            if err != nil {
                    log.Fatal(err)
                    return
            }
            defer func() {
                    if err := f.Close(); err != nil {
                            log.Fatal("failed to close file")
                    }
            }()
            log.Println("success")
            return
    }
    
    (~/work/achiku/gosec-issue)
    ❯❯❯ ll
    total 8
    -rw-r--r--  1 chiku  staff  268 10 18 11:32 main.go
    -rw-r--r--  1 chiku  staff    0 10 18 11:31 testfile.txt
    (~/work/achiku/gosec-issue)
    ❯❯❯ go run main.go
    2021/10/18 11:32:22 success
    (~/work/achiku/gosec-issue)
    ❯❯❯ gosec .
    [gosec] 2021/10/18 11:32:27 Including rules: default
    [gosec] 2021/10/18 11:32:27 Excluding rules: default
    [gosec] 2021/10/18 11:32:27 Import directory: /Users/chiku/work/achiku/gosec-issue
    [gosec] 2021/10/18 11:32:28 Checking package: main
    [gosec] 2021/10/18 11:32:28 Checking file: /Users/chiku/work/achiku/gosec-issue/main.go
    Results:
    
    
    [/Users/chiku/work/achiku/gosec-issue/main.go:14-18] - G307 (CWE-703): Deferring unsafe method "Close" on type "*os.File" (Confidence: HIGH, Severity: MEDIUM)
        13:         }
      > 14:         defer func() {
      > 15:                 if err := f.Close(); err != nil {
      > 16:                         log.Fatal("failed to close file")
      > 17:                 }
      > 18:         }()
        19:         log.Println("success")
    
    
    
    Summary:
      Gosec  : 2.9.1
      Files  : 1
      Lines  : 21
      Nosec  : 0
      Issues : 1
    
    

    with v2.8.1

    (~/work/achiku/gosec-issue)
    ❯❯❯ curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $GOPATH/bin v2.8.1
    securego/gosec info checking GitHub for tag 'v2.8.1'
    securego/gosec info found version: 2.8.1 for v2.8.1/darwin/amd64
    securego/gosec info installed /Users/chiku/sdk/go1.16.7/bin/gosec
    (~/work/achiku/gosec-issue)
    ❯❯❯ gosec .
    [gosec] 2021/10/18 11:32:43 Including rules: default
    [gosec] 2021/10/18 11:32:43 Excluding rules: default
    [gosec] 2021/10/18 11:32:43 Import directory: /Users/chiku/work/achiku/gosec-issue
    [gosec] 2021/10/18 11:32:44 Checking package: main
    [gosec] 2021/10/18 11:32:44 Checking file: /Users/chiku/work/achiku/gosec-issue/main.go
    Results:
    
    
    Summary:
      Gosec  : 2.8.1
      Files  : 1
      Lines  : 21
      Nosec  : 0
      Issues : 0
    

    gosec version

    • v2.9.1
    • https://github.com/securego/gosec/releases/tag/v2.9.1

    Go version (output of 'go version')

    ❯❯❯ go version
    go version go1.16.7 darwin/amd64
    

    Operating system / Environment

    ❯❯❯ uname -a
    Darwin FVFZR19DLYWP 20.5.0 Darwin Kernel Version 20.5.0: Sat May  8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64 x86_64
    

    Expected behavior

    No errors, or solve this error.

    Actual behavior

    gosec detects G307 (CWE-703).

  • invalid package name

    invalid package name "" when importing tview

    Summary

    When running gosec against a package on alpine/edge (but not on Feora 34) I get the error:

      > [line 26 : column 2] - could not import github.com/rivo/tview (invalid package name: "")
    

    Steps to reproduce the behavior

    go get -u github.com/securego/gosec/cmd/gosec
    cd project-that-imports-tview/
    gosec ./...
    

    gosec version

    Always pulled in CI using go get as above. Last run I see was:

    go: downloading github.com/securego/gosec v0.0.0-20200401082031-e946c8c39989
    

    Go version (output of 'go version')

    + go version
    go version go1.16.4 linux/amd64
    

    Operating system / Environment

    alpine/edge

    + go env
    GO111MODULE="on"
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/build/.cache/go-build"
    GOENV="/home/build/.config/go/env"
    GOEXE=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOINSECURE=""
    GOMODCACHE="/home/build/go/pkg/mod"
    GONOPROXY=""
    GONOSUMDB=""
    GOOS="linux"
    GOPATH="/home/build/go"
    GOPRIVATE=""
    GOPROXY="https://proxy.golang.org,direct"
    GOROOT="/usr/lib/go"
    GOSUMDB="sum.golang.org"
    GOTMPDIR=""
    GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
    GOVCS=""
    GOVERSION="go1.16.4"
    GCCGO="gccgo"
    AR="ar"
    CC="gcc"
    CXX="g++"
    CGO_ENABLED="1"
    GOMOD="/dev/null"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build254833280=/tmp/go-build -gno-record-gcc-switches"
    

    Expected behavior

    It should run like it used to before this project imported tview.

    Actual behavior

      > [line 26 : column 2] - could not import github.com/rivo/tview (invalid package name: "")
    

    This is similar to #580 except not in the standard library so I'm opening this separately.

  • gosec sonarqube format reports a wrong path for .go files when located in inner folders

    gosec sonarqube format reports a wrong path for .go files when located in inner folders

    Summary

    gosec sonarqube format reports a wrong path for .go files when located in inner folders

    Steps to reproduce the behavior

    Running gosec -fmt=sonarqube -out gosec-report.json ./... within a cloned repo containing a helloWorld.go file in a GoProjects folder

    helloworld.go file content is:

    package main
    import "fmt"
    func main() {
            var password = "f62e5bcda4fae4f82370da0c6f20697b8f8447ef"
            fmt.Printf("hello, world\n")
    }
    

    Here is the std output:

    [gosec] 2019/05/07 09:53:46 Including rules: default
    [gosec] 2019/05/07 09:53:46 Excluding rules: default
    [gosec] 2019/05/07 09:53:46 Import directory: /home/travis/gopath/src/github.ibm.com/andrea-tortosa/CICDBeta/GoProjects
    [gosec] 2019/05/07 09:53:47 Checking package: main
    [gosec] 2019/05/07 09:53:47 Checking file: /home/travis/gopath/src/github.ibm.com/andrea-tortosa/CICDBeta/GoProjects/helloWorld.go
    

    and the output file:

    {
    	"issues": [
    		{
    			"engineId": "gosec",
    			"ruleId": "G101",
    			"primaryLocation": {
    				"message": "Potential hardcoded credentials",
    				"filePath": "/home/travis/gopath/src/github.ibm.com/andrea-tortosa/CICDBeta/helloWorld.go",
    				"textRange": {
    					"startLine": 6,
    					"endLine": 6
    				}
    			},
    			"type": "VULNERABILITY",
    			"severity": "BLOCKER",
    			"effortMinutes": 5
    		}
    	]
    }
    

    As you can see the output file does not include the GoProjects folder and as a consequence of this sonarqube does not upload this result on the server. Everything works fine if the same file is located directly in the root repo.

    gosec version

    Installed a few minutes ago through go get github.com/securego/gosec/cmd/gosec/... and latest release in github.com is 2.0.0

    Go version (output of 'go version')

    1.12.3

    Operating system / Environment

    Operating System Details Distributor ID: Ubuntu Description: Ubuntu 16.04.6 LTS Release: 16.04 Codename: xenial

    Expected behavior

    FilePath in output file includes the GoProjects folder

    Actual behavior

    FilePath in output file DOES NOT include the GoProjects folder

  • SIGSEGV: segmentation violation

    SIGSEGV: segmentation violation

    When using gas to scan golang.org/x/crypto/acme/autocert/autocert.go, I get the following segmentation violation:

    [gas] 2018/02/13 16:08:38 Checking package: autocert
    [gas] 2018/02/13 16:08:38 Checking file: /Users/browne/workspace/go/src/golang.org/x/crypto/acme/autocert/autocert.go
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x126a7ec]
    goroutine 1 [running]:
    github.com/GoASTScanner/gas/rules.(*insecureConfigTLS).Match(0xc42007d920, 0x1474fc0, 0xc420239ec0, 0xc420054400, 0x1, 0xdc0000c420c2cb48, 0xc42017a928)
    	/Users/browne/go/src/github.com/GoASTScanner/gas/rules/tls.go:109 +0x7c
    github.com/GoASTScanner/gas.(*Analyzer).Visit(0xc4200841e0, 0x1474fc0, 0xc420239ec0, 0x2, 0x14e2fe0)
    	/Users/browne/go/src/github.com/GoASTScanner/gas/analyzer.go:171 +0x1c5
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1474fc0, 0xc420239ec0)
    	/usr/local/go/src/go/ast/walk.go:52 +0x66
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1475940, 0xc420240e80)
    	/usr/local/go/src/go/ast/walk.go:143 +0x15df
    go/ast.walkExprList(0x1473980, 0xc4200841e0, 0xc4205a7e70, 0x1, 0x1)
    	/usr/local/go/src/go/ast/walk.go:26 +0x81
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1474c40, 0xc420239f00)
    	/usr/local/go/src/go/ast/walk.go:207 +0x211f
    go/ast.walkStmtList(0x1473980, 0xc4200841e0, 0xc420244000, 0x3, 0x4)
    	/usr/local/go/src/go/ast/walk.go:32 +0x81
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1474e80, 0xc420244040)
    	/usr/local/go/src/go/ast/walk.go:238 +0x1e95
    go/ast.walkStmtList(0x1473980, 0xc4200841e0, 0xc420244100, 0x3, 0x4)
    	/usr/local/go/src/go/ast/walk.go:32 +0x81
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1474dc0, 0xc42023b350)
    	/usr/local/go/src/go/ast/walk.go:224 +0x1b71
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1475900, 0xc42023b380)
    	/usr/local/go/src/go/ast/walk.go:254 +0x1212
    go/ast.walkStmtList(0x1473980, 0xc4200841e0, 0xc4205bc780, 0x5, 0x8)
    	/usr/local/go/src/go/ast/walk.go:32 +0x81
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1474dc0, 0xc42023b560)
    	/usr/local/go/src/go/ast/walk.go:224 +0x1b71
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x1475240, 0xc42023b590)
    	/usr/local/go/src/go/ast/walk.go:344 +0xd83
    go/ast.walkDeclList(0x1473980, 0xc4200841e0, 0xc42046d400, 0x2b, 0x40)
    	/usr/local/go/src/go/ast/walk.go:38 +0x81
    go/ast.Walk(0x1473980, 0xc4200841e0, 0x14751c0, 0xc4205bcf80)
    	/usr/local/go/src/go/ast/walk.go:353 +0x266f
    github.com/GoASTScanner/gas.(*Analyzer).Process(0xc4200841e0, 0xc42004a8d0, 0x1, 0x1, 0x1, 0xc42004a8d0)
    	/Users/browne/go/src/github.com/GoASTScanner/gas/analyzer.go:141 +0x57d
    main.main()
    	/Users/browne/go/src/github.com/GoASTScanner/gas/cmd/gas/main.go:224 +0x459
    

    To reproduce:

    go get golang.org/x/crypto/ssh
    cd /Users/browne/workspace/go/src/golang.org
    gas x/crypto/acme/autocert/
    
  • Add G307 sample code.

    Add G307 sample code.

    fixes https://github.com/securego/gosec/issues/657

    The sample should reflect a defered close that leads to data loss. Due to IDE auto-complete people tend to at least log errors, but not really care about handling.

    To my point of view this could be fixed by seeing a deferred f.Close(), without a correspondig f.Sync(), generally as a bad pattern.

  • Path-based package wildcards don't work

    Path-based package wildcards don't work

    With the recent refactor, path-based package wildcards don't work. Using a wildcard in the current directory works:

    (env) jonm@jonm:~/go/src/github.com/GoASTScanner/gas$ gas ./... 2>&1 | head
    [gas] 2018/03/07 19:47:46 including rules: default
    [gas] 2018/03/07 19:47:46 excluding rules: default
    [gas] 2018/03/07 19:47:46 Searching directory: /home/jonm/go/src/github.com/GoASTScanner/gas
    [gas] 2018/03/07 19:47:46 Searching directory: /home/jonm/go/src/github.com/GoASTScanner/gas/cmd/gas
    [gas] 2018/03/07 19:47:46 Searching directory: /home/jonm/go/src/github.com/GoASTScanner/gas/cmd/gasutil
    [gas] 2018/03/07 19:47:46 Searching directory: /home/jonm/go/src/github.com/GoASTScanner/gas/cmd/tlsconfig
    [gas] 2018/03/07 19:47:46 Searching directory: /home/jonm/go/src/github.com/GoASTScanner/gas/output
    

    But using a real path doesn't:

    [gas] 2018/03/07 19:48:29 including rules: default
    [gas] 2018/03/07 19:48:29 excluding rules: default
    warning: "/home/jonm/go/src/github.com/GoASTScanner/gas/..." matched no packages
    [gas] 2018/03/07 19:48:29 no initial packages were loaded
    
  • could not import io/fs (invalid package name:

    could not import io/fs (invalid package name: "")

    Summary

    Steps to reproduce the behavior

    import "io/fs"
    

    and use filepath.WalkDir

    gosec version

    I assume 2.6.1 as I use snap. Unclear as there is no version subcommand` included in the tool.

    Go version (output of 'go version')

    go version go1.16 linux/amd64
    

    Operating system / Environment

    ubuntu 18.04

    Expected behavior

    no errors

    Actual behavior

      > [line 5 : column 2] - could not import io/fs (invalid package name: "")
    
      > [line 42 : column 22] - WalkDir not declared by package filepath
    
  • gosec does not check `tls.Config.MinVersion` field during structure definition when the given value is a variable containing validated value

    gosec does not check `tls.Config.MinVersion` field during structure definition when the given value is a variable containing validated value

    Summary

    When I'm coding a small library package for HTTP server using TLS, gosec from golangci-lint keeps reporting:

    internal/netserver/Server.go:47:10: G402: TLS MinVersion too low. (gosec)
    

    while I have a strict checking before use where I only allow TLS 1.2 and TLS 1.3 to pass-through and anything else is set to TLS1.3.

    switch s.TLSMinVersion {                                                                    
    case tls.VersionTLS12:                                                                      
    case tls.VersionTLS13:                                                                      
    default:                                                                                    
            s.TLSMinVersion = tls.VersionTLS13                                                  
    }
    

    Here is the screenshot of the start server function (with report): screenshot-2020-09-24-19-09-56

    My biggest concern is, am I doing things right? This is my first time bumping into what looks like a severe security problem.

    Steps to reproduce the behavior

    Try create a function referencing:

    1. https://gist.github.com/denji/12b3a568f092ab951456
    2. https://blog.cloudflare.com/exposing-go-on-the-internet/

    Then, use the golangci-lint to scan it.

    gosec version

    golangci-lint has version 1.31.0 built from 3d6d0e7 on 2020-09-07T15:14:41Z

    Go version (output of 'go version')

    go version go1.15.2 linux/amd64

    Operating system / Environment

    Debian Buster (10) Stable

    Expected behavior

    Expect to be safe and sound with gosec inspectation.

    Actual behavior

    Keeps hitting G402 even the default value is changed to tls.VersionTLS12.

  • Parsing error in windows

    Parsing error in windows

    Summary

    gosec does not work in windows.

    Steps to reproduce the behavior

    gosec F:/data/...

    • in linux, it work.
    • but in windows, failed:
     Including rules: default
     [gosec] 2019/06/13 11:34:09 Excluding rules: default
    [gosec] 2019/06/13 11:34:09 Import directory: F:\data\src\back_media
    [gosec] 2019/06/13 11:35:17 Checking package: main
    [gosec] 2019/06/13 11:35:17 Checking file: F:\data\src\back_media\back_media.go
    [gosec] 2019/06/13 11:35:17 Checking file: F:\data\src\back_media\main.go
    [gosec] 2019/06/13 11:35:17 Import directory: F:\data\src\cdnutil
     [gosec] 2019/06/13 11:35:23 parsing errors in pkg "cdnutil": parsing line: strconv.Atoi: parsing "\\data\\src\\cdnutil\\ref_api.go": invalid syntax
    

    gosec version

    2.0.0

    Go version (output of 'go version')

    1.12.6

    Operating system / Environment

    windows 7
    set GOARCH=amd64
    set GOBIN=
    set GOCACHE=C:\Users\xxx\AppData\Local\go-build
    set GOEXE=.exe
    set GOFLAGS=
    set GOHOSTARCH=amd64
    set GOHOSTOS=windows
    set GOOS=windows
    set GOPATH=F:\tools\go-1.12.6\go
    set GOPROXY=
    set GORACE=
    set GOROOT=F:\tools\go-1.12.6
    set GOTMPDIR=
    set GOTOOLDIR=F:\tools\go-1.12.6\pkg\tool\windows_amd64
    set GCCGO=gccgo
    set CC=gcc
    set CXX=g++
    set CGO_ENABLED=1
    set GOMOD=
    set CGO_CFLAGS=-g -O2
    set CGO_CPPFLAGS=
    set CGO_CXXFLAGS=-g -O2
    set CGO_FFLAGS=-g -O2
    set CGO_LDFLAGS=-g -O2
    set PKG_CONFIG=pkg-config
    set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessag
    e-length=0 -fdebug-prefix-map=C:\Users\codedog\AppData\Local\Temp\go-build106690
    454=/tmp/go-build -gno-record-gcc-switches
    

    Expected behavior

    output result.

    Actual behavior

    parsing errors in pkg "cdnutil"

  • Add support for #excluding specific rules

    Add support for #excluding specific rules

    Create the ability to exclude specific rules, rather than all of them (with "#nosec"). Works like:

                cmd := exec.Command("sh", "-c", os.Getenv("FOO")) // #exclude !G001
    

    You can specify an arbitrary number of exclusions, and they have the same scoping semantics as "#nosec". You can also add comments to explain your exclusions:

                cmd := exec.Command("sh", "-c", os.Getenv("FOO")) // #exclude !G001: Doesn't apply here
    
  • unable to suppress G307 with configuration

    unable to suppress G307 with configuration

    Summary

    Tried to suppress G307 issue similar to G104 as mentioned in the readme file

    {
        "G307": {
                "os.File": ["Close"]
        }
    }
    
    

    Steps to reproduce the behavior

    defer os.File.Close() run with this conf:

    {
        "G307": {
                "os.File": ["Close"]
        }
    }
    

    gosec version

    Version: dev Git tag: Build date:

    Go version (output of 'go version')

    go version go1.18.5 linux/amd64

    Operating system / Environment

    Ubuntu x64

    Expected behavior

    Dont know if this rule is supported, if it is then this code should not have flagged.

    Actual behavior

    This code snippet is getting flagged in the gosec report.

  • G304 fail to detect clean

    G304 fail to detect clean

    Summary

    G304 fail to detect clean

    Steps to reproduce the behavior

    consider the following code sinppet:

      func readConfig(origin string) ([]byte, error) {
          fp := filepath.Join(inputDirPath, origin)
          fp = filepath.Clean(fp)
          if !strings.HasPrefix(fp, inputDirPath) {
              return nil, fmt.Errorf("Unsafe path %s", origin)
          }
          f, err := os.Open(fp)
          if err != nil {
              return nil, fmt.Errorf("failed to open file %s: %v", fp, err)
          }
          defer f.Close()
        
          raw, err := ioutil.ReadAll(f)
          if err != nil {
              return nil, fmt.Errorf("failed to read file %s: %v", origin, err)
          }
        
          return raw, nil
      }
    

    gosec version

    $ gosec -version
    Version: 2.14.0
    Git tag: v2.14.0
    Build date: 2022-10-17T09:14:30Z
    

    Go version (output of 'go version')

    go version go1.19.2 linux/amd64
    

    Operating system / Environment

    Linux

    Expected behavior

    detect clean and not report an issue

    Actual behavior

    ] - G304 (CWE-22): Potential file inclusion via variable (Confidence: HIGH, Severity: MEDIUM)
        112: 	}
      > 113: 	f, err := os.Open(fp)
        114: 	if err != nil {
    
  • G104 fails to catch err reassignments

    G104 fails to catch err reassignments

    Summary

    Since err is commonly used, it's not uncommon to have it reassigned If someone forgets to check it before reassigning it, G104 should catch it

    Steps to reproduce the behavior

    package main
    
    import (
    	"io"
    	"log"
    	"os"
    )
    
    func main() {
    	_, _ = io.WriteString(os.Stdout, "Hello World") // # this is ok
    
    	_, err := io.WriteString(os.Stdout, "Hello World")
    	if err != nil { // good
    		log.Fatal(err)
    	}
    
    	_, err = io.WriteString(os.Stdout, "Hello World") // # this err will not be checked
    	_, err = io.WriteString(os.Stdout, "Hello World") // # this err will be checked
    
    	if err != nil { // checking the second err but not the first one
    		log.Fatal(err)
    	}
    
    }
    

    gosec version

    2.14.0

    Go version (output of 'go version')

    go version go1.19.2

    Operating system / Environment

    darwin/arm64

    Expected behavior

    Should catch the err that wasn't checked

    Actual behavior

    Doesn't.

  • No issues reported for secDevLabs (vulnerable apps)

    No issues reported for secDevLabs (vulnerable apps)

    Summary

    I am new to using gosec. So, I was trying it against a set of vulnerable go apps in the secDevLabs. The tools reports absolutely no issues although the apps are designed to be vulnerable with some of the vulnerabilities being really obvious (e.g., concatenated SQL statements for SQLi). Am I doing something wrong? Thanks a lot in advance :)

    Steps to reproduce the behavior

    1. Clone, for example, the copy-n-paste app which is vulnerable to SQL injection attacks.
    2. Go to the app/ directory (not sure if necessary but it avoids "failed to import" errors).
    3. Run gosec ./... --verbose (just to check the vulnerable files are scanned).

    gosec version

    v2.14.0

    Go version (output of 'go version')

    go1.18.7 linux/amd64

    Operating system / Environment

    Ubuntu Linux 22.04

    Expected behavior

    I expect to see some security issues like in line 49 according to the rule G202: SQL query construction using string concatenation.

    Actual behavior

    The tools reports zero issues: Summary: Gosec : v2.14.0 Files : 6 Lines : 391 Nosec : 0 Issues : 0

  • Check if package make syscalls

    Check if package make syscalls

    I was thinking about making tool to check if package makes any syscalls. There are many simple util libraries for parsing, collections helpers etc. Such libraries should not make any syscalls for network or file access.

    What do you think about adding this optional check to gosec for static syscalls analysis.

    gosec -include=Gxxx github.com/badoux/checkmail
    

    Example output

    syscall.SOCK_STREAM made by net.DialTimeout in checkmail.go:106
    
  • False alarm for G101

    False alarm for G101

    Summary

    • G101 (CWE-798): Potential hardcoded credentials (Confidence: LOW, Severity: HIGH) 56: // PropertyNameSnmpGroupWriteView - Property name sent in response if group write view in snmp group is drifted

      57: PropertyNameSnmpGroupWriteView = "Snmp Group Write View" 58: // PropertyNameSnmpGroupNotifyView - Property name sent in response if group notify view in snmp group is drifted

    Steps to reproduce the behavior

    Just have this as a const in a file

    gosec version

    Version: 2.12.0 Git tag: v2.12.0 Build date: 2022-06-13T19:36:07Z

    Go version (output of 'go version')

    go version go version go1.17.2 darwin/amd64

    Operating system / Environment

    Macos

    Expected behavior

    Should not be flagged as an issue - since these are not credentials

    Actual behavior

PHP security vulnerabilities checker

Local PHP Security Checker The Local PHP Security Checker is a command line tool that checks if your PHP application depends on PHP packages with know

Jan 3, 2023
Web-Security-Academy - Web Security Academy, developed in GO

Web-Security-Academy - Web Security Academy, developed in GO

Feb 23, 2022
A fast and easy to use URL health checker ⛑️ Keep your links healthy during tough times
A fast and easy to use URL health checker ⛑️ Keep your links healthy during tough times

AreYouOK? A minimal, fast & easy to use URL health checker Who is AreYouOk made for ? OSS Package Maintainers ??️

Oct 7, 2022
log4jshell vulnerability checker tool

Description log4j-checker tool helps identify whether a certain system is running a vulnerable version of the log4j library. Download and run the tool

Dec 20, 2021
A mobile security hash generator using golang

Mobile Security Hash Generator Project scope This little script is my first experiment using Go. I wrote it for my friend @marcotrumpet because he nee

Oct 10, 2022
CLI client (and Golang module) for deps.dev API. Free access to dependencies, licenses, advisories, and other critical health and security signals for open source package versions.
CLI client (and Golang module) for deps.dev API. Free access to dependencies, licenses, advisories, and other critical health and security signals for open source package versions.

depsdev CLI client (and Golang module) for deps.dev API. Free access to dependencies, licenses, advisories, and other critical health and security sig

May 11, 2023
Dec 28, 2022
HTTP middleware for Go that facilitates some quick security wins.

Secure Secure is an HTTP middleware for Go that facilitates some quick security wins. It's a standard net/http Handler, and can be used with many fram

Jan 3, 2023
Gryffin is a large scale web security scanning platform.

Gryffin (beta) Gryffin is a large scale web security scanning platform. It is not yet another scanner. It was written to solve two specific problems w

Dec 27, 2022
set of web security test cases and a toolkit to construct new ones

Webseclab Webseclab contains a sample set of web security test cases and a toolkit to construct new ones. It can be used for testing security scanners

Jan 7, 2023
Tracee: Linux Runtime Security and Forensics using eBPF
Tracee: Linux Runtime Security and Forensics using eBPF

Tracee is a Runtime Security and forensics tool for Linux. It is using Linux eBPF technology to trace your system and applications at runtime, and analyze collected events to detect suspicious behavioral patterns.

Jan 5, 2023
Sqreen's Application Security Management for the Go language
Sqreen's Application Security Management for the Go language

Sqreen's Application Security Management for Go After performance monitoring (APM), error and log monitoring it’s time to add a security component int

Dec 27, 2022
A scalable overlay networking tool with a focus on performance, simplicity and security

What is Nebula? Nebula is a scalable overlay networking tool with a focus on performance, simplicity and security. It lets you seamlessly connect comp

Dec 29, 2022
How to systematically secure anything: a repository about security engineering
How to systematically secure anything: a repository about security engineering

How to Secure Anything Security engineering is the discipline of building secure systems. Its lessons are not just applicable to computer security. In

Jan 5, 2023
Convenience of containers, security of virtual machines

Convenience of containers, security of virtual machines With firebuild, you can build and deploy secure VMs directly from Dockerfiles and Docker image

Dec 28, 2022
MQTT安全测试工具 (MQTT Security Tools)
MQTT安全测试工具 (MQTT Security Tools)

███╗ ███╗ ██████╗ ████████╗████████╗███████╗ ████╗ ████║██╔═══██╗╚══██╔══╝╚══██╔══╝██╔════╝ ██╔████╔██║██║ ██║ ██║ ██║ ███████╗ ██║╚██╔╝█

Dec 21, 2022
GoPhish by default tips your hand to defenders and security solutions. T

GoPhish by default tips your hand to defenders and security solutions. The container here strips those indicators and makes other changes to hopefully evade detection during operations.

Jan 4, 2023
Go binary that finds .EXEs and .DLLs on the system that don't have security controls enabled

Go Hunt Weak PEs Go binary that finds .EXEs and .DLLs on the system that don't have security controls enabled (ASLR, DEP, CFG etc). Usage $ ./go-hunt-

Oct 28, 2021
One Time Passwords (OTPs) are an mechanism to improve security over passwords alone.

otp: One Time Password utilities Go / Golang Why One Time Passwords? One Time Passwords (OTPs) are an mechanism to improve security over passwords alo

Jan 7, 2023