Semgrep - Discovering Secrets in JavaScript
The process can be slow for larger applications.
Step 1: Gather URLs
-
Crawl with katana using "-sr" to save the responses.
~/go/bin/katana -u [url] -fs fqdn [-headless] -xhr -jc -jsl -sr -em js
Step 2: Rename all the files with the .js extension so semgrep applies the correct rules
Note: The responses will also include the headers and some may not actually be javascript files.
-
Use the following one liner to rename all the .txt files
find . -type f -name "*.txt" -exec bash -c 'mv "$0" "${0%.txt}.js"' {} \;
Step 3: Scan with Semgrep
-
Setup semgrep (Make an account to access pro rules)
-
Ensure there is an empty .semgrepignore file in the directory
.semgrepignore
# .semgrepignore -
Run a semgrep scan with pro rules
semgrep scan --dryrun --config "p/secrets" --config "p/gitleaks" --pro --text --text-output=semgrep.txt --timeout 0 --timeout-threshold 0 --max-target-bytes=-1
Parsing Semgrep output
#!/bin/bash
# Check if the correct number of arguments is provided
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <file_path>"
exit 1
fi
file_path="$1"
# Check if the file exists
if [ ! -f "$file_path" ]; then
echo "File not found: $file_path"
exit 1
fi
# Define ANSI color code for green
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Function to extract fields for each occurrence
extract_fields() {
local data=$1
local check_id=$(echo "$data" | jq -r '.check_id')
local start=$(echo "$data" | jq -r '.start | @json')
local end=$(echo "$data" | jq -r '.end | @json')
local location_path=$(echo "$data" | jq -r '.path')
local lines=$(echo "$data" | jq -r '.extra.lines')
local message=$(echo "$data" | jq -r '.extra.message')
local impact=$(echo "$data" | jq -r '.extra.metadata.impact')
local likelihood=$(echo "$data" | jq -r '.extra.metadata.likelihood')
local owasp=$(echo "$data" | jq -r '.extra.metadata.owasp | join(", ")')
if [ "$impact" == "HIGH" ] && ([[ "$likelihood" == "MEDIUM" ]] || [[ "$likelihood" == "HIGH" ]]); then
echo -e "${GREEN}Check ID:${NC} $check_id"
echo -e "${GREEN}Start:${NC} $start"
echo -e "${GREEN}End:${NC} $end"
echo -e "${GREEN}Location Path:${NC} $location_path"
echo -e "${GREEN}Lines:${NC} $lines"
echo -e "${GREEN}Message:${NC} $message"
echo -e "${GREEN}Impact:${NC} $impact"
echo -e "${GREEN}Likelihood:${NC} $likelihood"
echo -e "${GREEN}OWASP:${NC} $owasp"
echo
fi
}
# Loop through each item in the results array and extract fields
jq -c '.results[]' "$file_path" | while IFS= read -r item; do
extract_fields "$item"
done