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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .circleci/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ workflows:
name: detect_secrets_git_no_revision
base_branch: <<pipeline.git.branch>>
filters: *filters
- security/analyze_code:
name: analyze_code_diff
path: ~/project/sample
filters: *filters
- security/analyze_code:
name: analyze_code_full
full_scan: true
rules: p/cwe-top-25
filters: *filters
- orb-tools/pack:
filters: *release-filters
- orb-tools/publish:
Expand All @@ -70,5 +79,7 @@ workflows:
- scan_dependencies_command
- detect_secrets_dir
- detect_secrets_git_base_revision
- analyze_code_diff
- analyze_code_full
context: orb-publishing
filters: *release-filters
17 changes: 17 additions & 0 deletions src/examples/sast.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
description: |
The "analyze_code" job runs a static analysis tool to scan the codebase for vulnerabilities.
By default, a diff-aware scanning is performed meaning only file changes in the last commit
are scanned, or files scoped to the pull request if a short-lived branch is in question.
There is an option to scan all files inside a repository, change a base branch,
and enforce a different set of scan rules.
usage:
version: 2.1
orbs:
security: studion/security@x.y.z
workflows:
test_codebase:
jobs:
- security/analyze_code:
path: ~/workspace
full_scan: true
base_branch: prod
19 changes: 19 additions & 0 deletions src/executors/semgrep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
description: >
A Docker executor using official Semgrep image based on Alpine Linux.

parameters:
tag:
type: string
default: latest
description: >
Choose a specific semgrep/semgrep image tag:
https://hub.docker.com/r/semgrep/semgrep/tags
resource_class:
type: enum
enum: ['small', 'medium', 'medium+', 'large', 'xlarge', '2xlarge', '2xlarge+']
default: 'medium'
description: Choose the executor resource class

docker:
- image: semgrep/semgrep:<<parameters.tag>>
resource_class: <<parameters.resource_class>>
45 changes: 45 additions & 0 deletions src/jobs/analyze_code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
description: >
Run static analysis, or SAST, to find vulnerabilities in the codebase. Utilizes the Semgrep "scan"
command to do the analysis, for details hot it works see https://semgrep.dev/docs/cli-reference.

executor: semgrep

parameters:
path:
type: string
default: '.'
description: The path to the directory to scan.
full_scan:
type: boolean
default: false
description: >
The flag indicating whether to scan the full directory vs just files changed from the last commit,
or the whole branch if it is a short-lived branch, i.e. pull request.
verbose:
type: boolean
default: false
description: The flag indicates whether to show more details about rules, files, etc.
rules:
type: string
default: p/default p/owasp-top-ten p/r2c-security-audit p/eslint
description: >
The space-separated list of Semgrep rules, e.g. YAML configuration file, URL of the configuration
file, or Semgrep registry entry name.
base_branch:
type: string
default: ''
description: >
The name of the base branch for this scan. Usually some long-lived branch, e.g. default branch.

steps:
- checkout
- run:
name: Analyze code
working_directory: <<parameters.path>>
environment:
DIR_PATH: <<parameters.path>>
FULL_SCAN: <<parameters.full_scan>>
VERBOSE: <<parameters.verbose>>
RULES: <<parameters.rules>>
BASE_BRANCH_OVERRIDE: <<parameters.base_branch>>
command: <<include(scripts/analyze-code.sh)>>
59 changes: 59 additions & 0 deletions src/scripts/analyze-code.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

########### DEFAULTS ###########

ARGS="--experimental --error --strict --metrics off"

########### VERBOSE ###########

if [ "$VERBOSE" -eq 1 ]; then
ARGS="$ARGS --verbose"
fi

########### CONFIG ###########

function join() {
local separator="$1"
shift
local first="$1"
shift
printf "%s" "$first" "${@/#/$separator}"
}

IFS=' ' read -ra RULE_ARRAY <<< "$RULES"

ARGS="$ARGS --config $(join ' --config ' "${RULE_ARRAY[@]}")"

########### BASELINE COMMIT ###########

BASE_BRANCH=$(git rev-parse --abbrev-ref origin/HEAD | cut -c8-)
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

if [[ -n $BASE_BRANCH_OVERRIDE ]]; then
BASE_BRANCH=$BASE_BRANCH_OVERRIDE
fi

if [[ -n $CIRCLE_BRANCH ]]; then
CURRENT_BRANCH=$CIRCLE_BRANCH
fi

BASELINE_COMMIT=""

if [ "$FULL_SCAN" -eq 0 ] && [[ "$BASE_BRANCH" = "$CURRENT_BRANCH" ]]; then
# Usually when changes are merged back into a long-lived branch, e.g. trunk
BASELINE_COMMIT=$(git rev-parse HEAD~1)
elif [ "$FULL_SCAN" -eq 0 ] && [[ "$BASE_BRANCH" != "$CURRENT_BRANCH" ]]; then
# Usually a short-lived branch, in other words a pull request
BASELINE_COMMIT="$(git rev-parse "$BASE_BRANCH")"
fi

if [[ -n $BASELINE_COMMIT ]]; then
ARGS="$ARGS --baseline-commit $BASELINE_COMMIT"
fi

########### COMMAND ###########

echo "Running Semgrep scan, at path '$DIR_PATH', with following arguments:"
echo "$ARGS"

eval semgrep "$ARGS"