Coder Social home page Coder Social logo

appthreat / sast-scan Goto Github PK

View Code? Open in Web Editor NEW
144.0 12.0 21.0 2.32 MB

Fully open-source SAST scanner supporting a range of languages and frameworks. Integrates with major CI pipelines and IDE such as Azure DevOps, Google CloudBuild, VS Code and Visual Studio. No server required!

Home Page: https://appthreat.io

License: MIT License

Dockerfile 8.44% Python 91.42% Shell 0.14%
docker static-analysis sarif azure-devops sast

sast-scan's Introduction

Introduction

  ___            _____ _                    _
 / _ \          |_   _| |                  | |
/ /_\ \_ __  _ __ | | | |__  _ __ ___  __ _| |_
|  _  | '_ \| '_ \| | | '_ \| '__/ _ \/ _` | __|
| | | | |_) | |_) | | | | | | | |  __/ (_| | |_
\_| |_/ .__/| .__/\_/ |_| |_|_|  \___|\__,_|\__|
      | |   | |
      |_|   |_|

This repo builds appthreat/sast-scan (and quay.io/appthreat/sast-scan), a container image with a number of bundled open-source static analysis security testing (SAST) tools. This is like a Swiss Army knife for DevSecOps engineers.

Docker Repository on Quay

Features

  • No messy configuration and no server required
  • Scanning is performed directly in the CI and is extremely quick. Full scan often takes only couple of minutes
  • Gorgeous HTML reports that you can proudly share with your colleagues, and the security team
  • Automatic exit code 1 (build breaker) with critical and high vulnerabilities
  • There are a number of small things that will bring a smile to any DevOps team

Bundled tools

Programming Language Tools
ansible ansible-lint
apex pmd
aws cfn-lint, cfn_nag
bash shellcheck
bom cdxgen
credscan gitleaks
depscan dep-scan
go gosec, staticcheck
java cdxgen, gradle, find-sec-bugs, pmd
jsp pmd
json jq, jsondiff, jsonschema
kotlin detekt
kubernetes kube-score
nodejs cdxgen, NodeJsScan, eslint, yarn
puppet puppet-lint
plsql pmd
python bandit, cdxgen, pipenv
ruby cyclonedx-ruby
rust cdxgen, cargo-audit
terraform tfsec
Visual Force (vf) pmd
Apache Velocity (vm) pmd
yaml yamllint

Bundled languages/runtime

  • jq
  • Go 1.12
  • Python 3.6
  • OpenJDK 11 (jre)
  • Ruby 2.5.5
  • Rust
  • Node.js 10
  • Yarnpkg

Some reports get converted into an open-standard called SARIF. Please see the section on Viewing reports for various viewer options for this.

Tools enabled for SARIF conversion

  • Bash - shellcheck
  • Credscan - gitleaks
  • Python - bandit
  • Node.js - NodeJsScan
  • pmd, find-sec-bugs
  • Go - gosec, staticcheck
  • Terraform - tfsec

Usage

sast-scan is ideal for use with CI and also as a pre-commit hook for local development.

Integration with Azure DevOps

Refer to the document

Integration with GitHub action

This tool can be used with GitHub actions using this action. All the supported languages can be used.

This repo self-tests itself with sast-scan! Check the GitHub workflow file of this repo.

- name: Self sast-scan
  uses: AppThreat/[email protected]
  with:
    output: reports
    type: python,bash
- name: Upload scan reports
  uses: actions/[email protected]
  with:
    name: sast-scan-reports
    path: reports

Integration with Google CloudBuild

Use this custom builder to add sast-scan as a build step.

The full steps are reproduced below.

  1. Add the custom builder to your project
git clone https://github.com/CloudBuildr/google-custom-builders.git
cd google-custom-builders/sast-scan
gcloud builds submit --config cloudbuild.yaml .
  1. Use it in cloudbuild.yaml
steps:
  - name: "gcr.io/$PROJECT_ID/sast-scan"
    args: ["--type", "python"]

Integration with CircleCI

Refer to the document

Integration with GitLab CI

A sample project with config can be found here

sast:
  stage: test
  image: 
    name: appthreat/sast-scan
  script:
    - scan --src ${CI_PROJECT_DIR} --type nodejs --out_dir ${CI_PROJECT_DIR}/reports
  artifacts:
    paths:
      - $CI_PROJECT_DIR/reports/

Custom integration

SARIF reports produced by sast-scan can be integrated with other compatible tools. It can also be easily imported into databases such as BigQuery for visualization purposes. Refer to integration document for detailed explanation on the SARIF format.

Scanning projects locally

Scan python project

docker run --rm -e "WORKSPACE=${PWD}" -v "$PWD:/app:cached" quay.io/appthreat/sast-scan scan --src /app --type python

On Windows the command changes slightly depending on the terminal.

cmd

docker run --rm -e "WORKSPACE=%cd%" -e "GITHUB_TOKEN=%GITHUB_TOKEN%" -v "%cd%:/app:cached" quay.io/appthreat/sast-scan scan

powershell and powershell core

docker run --rm -e "WORKSPACE=$(pwd)" -e "GITHUB_TOKEN=$env:GITHUB_TOKEN" -v "$(pwd):/app:cached" quay.io/appthreat/sast-scan scan

WSL bash

docker run --rm -e "WORKSPACE=${PWD}" -e "GITHUB_TOKEN=${GITHUB_TOKEN}" -v "$PWD:/app:cached" quay.io/appthreat/sast-scan scan 

git-bash

docker run --rm -e "WORKSPACE=${PWD}" -e "GITHUB_TOKEN=${GITHUB_TOKEN}" -v "/$PWD:/app:cached" quay.io/appthreat/sast-scan scan 

Don't forget the slash (/) before $PWD for git-bash!

Scan multiple projects

docker run --rm -e "WORKSPACE=${PWD}" -v "$PWD:/app:cached" quay.io/appthreat/sast-scan scan --src /app --type credscan,nodejs,python,yaml --out_dir /app/reports

Scan java project

For java and jvm language based projects, it is important to compile the projects before invoking sast-scan in the dev and CI workflow.

docker run --rm -e "WORKSPACE=${PWD}" -v ~/.m2:/.m2 -v <source path>:/app quay.io/appthreat/sast-scan scan --src /app --type java

# For gradle project
docker run --rm -e "WORKSPACE=${PWD}" -v ~/.gradle:/.gradle -v <source path>:/app quay.io/appthreat/sast-scan scan --src /app --type java

Scan python project (Without any telemetry)

docker run --rm -e "WORKSPACE=${PWD}" -e "DISABLE_TELEMETRY=true" -v $PWD:/app quay.io/appthreat/sast-scan scan --src /app --type python

Automatic project detection

Feel free to skip --type to enable auto-detection. Or pass comma-separated values if the project has multiple types.

Invoking built-in tools

Bandit

docker run --rm -v <source path>:/app quay.io/appthreat/sast-scan bandit -r /app

Viewing reports

Reports would be produced in the directory specified for --out_dir. In the above examples, it is set to reports which will be a directory under the source code root directory.

Some of the reports would be converted to a standard called SARIF. Such reports would end with the extension .sarif. To open and view the sarif files require a viewer such as:

Example reports:

Online viewer can be used to manually upload the .sarif files as shown.

Online viewer

Azure DevOps SARIF plugin can be integrated to show the analysis integrated with the build run as shown.

Azure DevOps integration

Build breaker

Alternatives

GitLab SAST uses numerous single purpose analyzers and Go based converters to produce a custom json format. This model has the downside of increasing build times since multiple container images should get downloaded and hence is not suitable for CI environments such as Azure Pipelines, CodeBuild and Google CloudBuild. Plus the license used by GitLab is not opensource even though the analyzers merely wrap existing oss tools!

MIR SWAMP is a free online service for running both oss and commercial static analysis for a number of languages simillar to sast-scan. There is a free SWAMP-in-a-box offering but the setup is a bit cumbersome. They use a xml format called SCARF with a number of perl based converters. SARIF, in contrast, is json based and is much easier to work with for integration and UI purposes. By adopting python, sast-scan is a bit easy to work with for customisation.

Sponsors

AppThreat is funded and supported by ShiftLeft. For general discussions and suggestions, please feel free to use either the GitHub issues or ShiftLeft discussion forum

sast-scan's People

Contributors

fatih avatar prabhu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sast-scan's Issues

Use uriBaseId to specify root for relative urls

For some tools that generate relative urls such as gitleaks, pmd the code auto-prefixes workspace for each result to make the location absolute. As per SARIF specification, it should be possible to specify uriBaseId and retain relative urls.

https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/sarif-v2.1.0-cs01.html#_Toc16012377 - section 3.4.14

This should also improve performance by a few seconds since we dont have to do things like this.

https://github.com/AppThreat/sast-scan/blob/master/lib/convert.py#L261
https://github.com/AppThreat/sast-scan/blob/master/lib/xml_parser.py#L50

Universal suppressions support

It appears like only certain tools (bandit, gosec) respect the #nosec comment to filter out false positives. Find Security Bugs seems to be using @SuppressFBWarnings annotation. It will be nice to at least document the annotation and comments required to filter the check.

Has the Terraform dropped out ?

I seem to be unable to run it.

sast:
stage: test
image:
name: appthreat/sast-scan
script:
- scan --src ${TF_ROOT} --type Terraform --out_dir ${CI_PROJECT_DIR}/reports
artifacts:
paths:
- $CI_PROJECT_DIR/reports/

Improve windows experience

Windows is not short of choice for terminals.

  • cmd
  • powershell
  • powershell core
  • WSL 1
  • WSL 2
  • Git Bash

Let's test sast-scan on each of the model and document the level of support.

nodejsscan exception: "No such file or directory"

TL;DR

sast-scan passes a full path to nodejsscan for the output, and nodejsscan can't handle it. nodejsscan run outside of sast-scan handles the same parameters fine. Does the Docker image have a different version of nodejsscan?

Problem

I'm using sast-scan in GitLab CICD to scan a node project. I've tried a few different parameters, but no matter what I specify for out_dir I get a "No such file or directory" error. Here's what I have in my .gitlab-ci.yml file:

sast:
  stage: test
  image: 
    name: appthreat/sast-scan
  script:
    - scan --src src --type nodejs --out_dir .
  artifacts:
    paths:
      - nodejsscan-report.json

And here's the output:

$ scan --src src --type nodejs --out_dir .
  ___            _____ _                    _
 / _ \          |_   _| |                  | |
/ /_\ \_ __  _ __ | | | |__  _ __ ___  __ _| |_
|  _  | '_ \| '_ \| | | '_ \| '__/ _ \/ _` | __|
| | | | |_) | |_) | | | | | | | |  __/ (_| | |_
\_| |_/ .__/| .__/\_/ |_| |_|_|  \___|\__,_|\__|
      | |   | |
      |_|   |_|
INFO [2020-04-10 12:53:54,342] Scanning src using scan plugins ['nodejs']
INFO [2020-04-10 12:53:54,342] ================================================================================
INFO [2020-04-10 12:53:54,343] ⚡︎ Executing "nodejsscan --output ./nodejsscan-report.json -d src"
ERROR [2020-04-10 12:53:54,610] Received exception: [Errno 2] No such file or directory: './nodejsscan-report.json'

What I've Tried

I've tried different directories, and get the same results. As soon as it's a path to a directory, nodesjsscan shows that error.

I've tried not specifying --out_dir, but then sast-scan constructs a full path src/reports/nodejsscan-report.json that it passes to nodejsscan and I get the same error.

I tried bypassing sast-scan entirely and calling nodejsscan directly so I could specify the parameters directly:

sast:
  stage: test
  image: 
    name: opensecurity/nodejsscan:cli
    entrypoint:
      - "/usr/bin/env"
      - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  script:
    - python /usr/src/app/cli.py -d src -o sast-report.json
  artifacts:
    paths:
      - sast-report.json

That works. Note that there's no path in the output parameter.

I tried running nodejsscan locally with the parameters that sast-scan passes:

$ nodejsscan --output ./nodejsscan-report.json -d src

That works.

Where I'm Confused

The sast-scan image on docker hub was built 3 days ago. The version of nodejsscan on PyPI is 3.7, same as I'm running locally, released Jan 18, 2020. I'm looking at the code where the error seems to be thrown, and that hasn't changed in over a year.

Support for html view

SARIF is great for portability and viewing the reports directly on Azure Pipelines and VS code. However, most devs are stuck with amateur CI products such as GitHub actions, Google CloudBuild to name a few :)

To help such devs, I think we need a html view that doesn't suck. There is a free web component from Microsoft. It's kinda nice but needs some more work to make it usable - like rendering the metadata about the run, tool and codebase for a start.

gitleaks report is lacking full path for filename

It currently only includes the filename and is missing the full or relative path. This makes the rendered sarif file less friendly since the user can not select the filename to navigate to the correct location.

Time to look at open-source dependency scanning

Now that SAST scanning is sufficiently mature and stable, it's time to look at open-source dependency scanning.

Our sast-scan container images already bundles a number of dependency scanning tools such as dependency-check, retire.js, ossaudit and so on. They operate differently and produce reports in their formats.

Some challenges that need to be solved:

  • Dependency-check (and the likes of trivy) is downloading all the CVE/NVD data each time for each run. Because of the added complexity with our container-based execution, effort is required to cache such data and mount the volume to the docker image and so on. Over a http proxy this would incur additional penalty. I am going to look at the pros and cons of splitting our container image into a separate sast-scan and oss-scan image
  • Tools such as retire.js, ossaudit and so on use the oss sonatype backend which requires a separate API key to make it usable. Currently, we are not requesting and injecting this api key. I want to spend time figuring out a way to do an efficient oss scan that neither involves downloading all the data nor requires a proprietary database such as sonatype!
  • Investigate and identify a common format to represent dependency vulnerabilities. Strong contender is grafeas

Railroader is not working yet

From within a Ruby project

docker run --rm --tmpfs /tmp -e "WORKSPACE=${PWD}" -v $PWD:/app appthreat/sast-scan scan --src /app --out_dir /app/reports --type ruby

Leads to the following error

INFO [2020-01-12 16:53:28,438] ♒︎ Executing "railroader --skip-files .git,.svn,.mvn,.idea,dist,bin,obj,backup,docs,tests,test,tmp,reports -o /app/reports/ruby-report.json -q /app"
/usr/local/share/gems/gems/sexp_processor-4.13.0/lib/sexp.rb:222:in `line': setting s(:args).line nil (ArgumentError)
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/ruby_parser/bm_sexp.rb:43:in `deep_clone'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/ruby_parser/bm_sexp.rb:30:in `each'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/processors/alias_processor.rb:50:in `process_safely'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/processor.rb:93:in `process_initializer'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/scanner.rb:185:in `process_initializer'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/scanner.rb:179:in `block in process_initializers'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/scanner.rb:302:in `block in track_progress'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/scanner.rb:299:in `each'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/scanner.rb:299:in `track_progress'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/scanner.rb:177:in `process_initializers'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/scanner.rb:47:in `process'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader.rb:354:in `scan'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader.rb:77:in `run'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/commandline.rb:133:in `run_railroader'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/commandline.rb:118:in `regular_report'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/commandline.rb:142:in `run_report'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/commandline.rb:35:in `run'
	from /usr/local/share/gems/gems/railroader-4.3.8/lib/railroader/commandline.rb:20:in `start'
	from /usr/local/share/gems/gems/railroader-4.3.8/bin/railroader:8:in `<top (required)>'
	from /usr/local/bin/railroader:23:in `load'
	from /usr/local/bin/railroader:23:in `<main>'

Referenced issue: david-a-wheeler/railroader#7

the process stop when running 'cdxgen' command

INFO [2020-01-13 18:17:30,174] Scanning /app using scan plugins ['python']
INFO [2020-01-13 18:17:30,175] ⚡︎ Executing "cdxgen -o /app/reports/bom-report.xml /app"

when I run docker run --rm --tmpfs /tmp -v xxx:/app appthreat/sast-scan scan --src /app --type python --out_dir /app/reports, docker pull very fast, but the process stop at this scene for a very long time, and the network is ok.

Add staticcheck to golang type

I see the Dockerfile is installing staticcheck tool, however I dont see it running on the golang type:

sast-scan/lib/config.py

Lines 122 to 129 in 4ea2ce4

"golang": [
"gosec",
"-fmt=json",
"-confidence=medium",
"-severity=medium",
"-no-fail",
"-out=%(report_fname_prefix)s.json",
"./...",

Is it because the SARIF converter is not yet ready for staticcheck?

Thanks

Unable to find repo details from the local repository

Hello,

I am getting the error "Unable to find repo details from the local repository" but there is in fact a file .sastscanrc in /app.

I can see that a file findsecbugs-report.xml was generated but there is just one finding.

1. Why there is hust one finding? it seems the scanners stopped prematurely.
2. Also, how can I get findsecbugs-report.xml exported to a SARIF?

docker run --rm -e "WORKSPACE=%cd%" -v "C:\maven\apache-maven-3.6.3\bin" -v "C:\source_code\app":/app appthreat/sast-scan scan --src /app --type java


/ _ \ |_ | | | |
/ /
\ _ __ _ __ | | | |__ _ __ ___ __ | |
| _ | '_ | '_ | | | '_ | '/ _ / ` | __|
| | | | |
) | |) | | | | | | | | __/ (| | |_
_| |_/ .
/| ./_/ || ||_| _|_,|_|
| | | |
|
| |_|

INFO [2020-04-01 13:26:44,486] Scanning /app using scan plugins ['credscan', 'java']
INFO [2020-04-01 13:26:44,494] ================================================================================
INFO [2020-04-01 13:26:44,496] ⚡︎ Executing "gitleaks --depth=2 --repo-path=/app --redact --timeout=2m --report=/app/reports/credscan-report.json --report-format=json"
INFO[2020-04-01T13:26:44Z] no leaks found, skipping writing report
INFO[2020-04-01T13:26:44Z] No leaks detected. 0 commits audited in 353 milliseconds 67 microseconds
INFO [2020-04-01 13:26:44,896] ================================================================================
INFO [2020-04-01 13:26:44,897] ⚡︎ Executing "java -jar /opt/spotbugs/lib/spotbugs.jar -textui -include /usr/local/src/spotbugs/include.xml -exclude /usr/local/src/spotbugs/exclude.xml -noClassOk -auxclasspathFromFile /tmp/tmpl891l6xd -sourcepath /app -quiet -medium -xml:withMessages -effort:max -nested:false -output /app/reports/findsecbugs-report.xml /app"WARNING [2020-04-01 13:27:02,662] Unable to find repo details from the local repository. Consider adding a local .sastscanrc file with the url details.
WARNING [2020-04-01 13:27:02,680] Project type is not supported: java

Thanks,

Make build break logic a configurable parameter

Certain CI such as Google CloudBuild lack a way to specify continue on error for build steps. Build break logic should therefore be configurable.

Dear Google,

If you are reading this ticket please invest and improve CloudBuild since it's currently looking inferior to even GitHub actions.

Improve visual studio integration on Windows

It appears like Visual Studio 2019 with SARIF viewer extension is not working quite well.

  • Visual Studio is expecting the version attribute to be at the top! When we do to_json(sarif schema) the attributes are getting sorted alphabetically so the runs attribute is on the top and version is at the bottom. We need to find a workaround for this
  • Our url encode is encoding and converting the backslash () to %5C thus confusing the extension

Attached is an example.

findsecbugs-report.sarif.txt

Let's do pull request scanning

Commercial folks are able to scan pull requests and add the results directly as a comment. Let's implement this feature entirely in actions without involving any server!

Instead of bloating the container, we can perhaps start with a new action for this feature.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.