Skip to content
Draft
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
1 change: 1 addition & 0 deletions src/commands/ci/handle-ci.mts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export async function handleCi(autoManifest: boolean): Promise<void> {
pendingHead: true,
pullRequest: 0,
reach: {
excludePaths: [],
reachAnalysisMemoryLimit: 0,
reachAnalysisTimeout: 0,
reachConcurrency: 1,
Expand Down
4 changes: 2 additions & 2 deletions src/commands/install/socket-completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@ FLAGS=(
[repos update]="--default-branch --homepage --interactive --org --repo-description --repo-name --visibility"
[repos view]="--interactive --org --repo-name"
[scan]=""
[scan create]="--auto-manifest --branch --commit-hash --commit-message --committers --cwd --default-branch --interactive --json --markdown --org --pull-request --reach --reach-analysis-memory-limit --reach-analysis-timeout --reach-disable-analytics --reach-ecosystems --reach-exclude-paths --read-only --repo --report --set-as-alerts-page --tmp"
[scan create]="--auto-manifest --branch --commit-hash --commit-message --committers --cwd --default-branch --exclude-paths --interactive --json --markdown --org --pull-request --reach --reach-analysis-memory-limit --reach-analysis-timeout --reach-disable-analytics --reach-ecosystems --reach-exclude-paths --read-only --repo --report --set-as-alerts-page --tmp"
[scan del]="--interactive --org"
[scan diff]="--depth --file --interactive --org"
[scan list]="--branch --direction --from-time --interactive --json --markdown --org --page --per-page --repo --sort --until-time"
[scan metadata]="--interactive --org"
[scan reach]="--reach-analysis-memory-limit --reach-analysis-timeout --reach-disable-analytics --reach-ecosystems --reach-exclude-paths"
[scan reach]="--exclude-paths --reach-analysis-memory-limit --reach-analysis-timeout --reach-disable-analytics --reach-ecosystems --reach-exclude-paths"
[scan report]="--fold --interactive --license --org --report-level --short"
[scan view]="--interactive --org --stream"
[threat-feed]="--direction --eco --filter --interactive --json --markdown --org --page --per-page"
Expand Down
11 changes: 9 additions & 2 deletions src/commands/scan/cmd-scan-create.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import path from 'node:path'
import { joinAnd } from '@socketsecurity/registry/lib/arrays'
import { logger } from '@socketsecurity/registry/lib/logger'

import { assertNoNegationPatterns } from './exclude-paths.mts'
import { handleCreateNewScan } from './handle-create-new-scan.mts'
import { outputCreateNewScan } from './output-create-new-scan.mts'
import { reachabilityFlags } from './reachability-flags.mts'
import { excludePathsFlag, reachabilityFlags } from './reachability-flags.mts'
import { suggestOrgSlug } from './suggest-org-slug.mts'
import { suggestTarget } from './suggest_target.mts'
import { validateReachabilityTarget } from './validate-reachability-target.mts'
Expand Down Expand Up @@ -171,6 +172,7 @@ async function run(
hidden,
flags: {
...generalFlags,
...excludePathsFlag,
...reachabilityFlags,
},
help: command => `
Expand All @@ -181,7 +183,7 @@ async function run(
${getFlagApiRequirementsOutput(`${parentName}:${CMD_NAME}`)}

Options
${getFlagListOutput(generalFlags)}
${getFlagListOutput({ ...generalFlags, ...excludePathsFlag })}

Reachability Options (when --reach is used)
${getFlagListOutput(reachabilityFlags)}
Expand Down Expand Up @@ -279,6 +281,7 @@ async function run(
setAsAlertsPage: boolean
tmp: boolean
// Reachability flags.
excludePaths: string[] | undefined
reach: boolean
reachAnalysisMemoryLimit: number
reachAnalysisTimeout: number
Expand Down Expand Up @@ -463,6 +466,9 @@ async function run(
logger.error('')
}

const excludePaths = cmdFlagValueToArray(cli.flags['excludePaths'])
assertNoNegationPatterns(excludePaths)

const reachExcludePaths = cmdFlagValueToArray(cli.flags['reachExcludePaths'])

// Validation helpers for better readability.
Expand Down Expand Up @@ -608,6 +614,7 @@ async function run(
pendingHead: Boolean(pendingHead),
pullRequest: Number(pullRequest),
reach: {
excludePaths,
reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit),
reachAnalysisTimeout: Number(reachAnalysisTimeout),
reachConcurrency: Number(reachConcurrency),
Expand Down
55 changes: 55 additions & 0 deletions src/commands/scan/cmd-scan-create.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('socket scan create', async () => {
--committers Committers
--cwd working directory, defaults to process.cwd()
--default-branch Set the default branch of the repository to the branch of this full-scan. Should only need to be done once, for example for the "main" or "master" branch.
--exclude-paths List of glob patterns to exclude from the scan, including SCA/SBOM manifest discovery and (when --reach is enabled) Tier 1 reachability analysis. Patterns are matched relative to the project root. Bare directory names are auto-extended to recursive globs (e.g. \`tests\` becomes \`tests/**\`). Trailing slashes are stripped. Negation patterns (\`!path\`) are not supported. Accepts a comma-separated value or multiple flags.
--interactive Allow for interactive elements, asking for input. Use --no-interactive to prevent any input questions, defaulting them to cancel/no.
--json Output as JSON
--markdown Output as Markdown
Expand Down Expand Up @@ -185,6 +186,34 @@ describe('socket scan create', async () => {
},
)

cmdit(
[
'scan',
'create',
FLAG_ORG,
'fakeOrg',
'target',
FLAG_DRY_RUN,
'--repo',
'xyz',
'--branch',
'abc',
'--exclude-paths',
'tests',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should succeed when --exclude-paths is used without --reach',
async cmd => {
const { code, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(
code,
'should exit with code 0 when --exclude-paths is used standalone',
).toBe(0)
},
)

cmdit(
[
'scan',
Expand Down Expand Up @@ -437,6 +466,32 @@ describe('socket scan create', async () => {
},
)

cmdit(
[
'scan',
'create',
FLAG_ORG,
'fakeOrg',
'test/fixtures/commands/scan/simple-npm',
FLAG_DRY_RUN,
'--repo',
'xyz',
'--branch',
'abc',
'--reach',
'--exclude-paths',
'tests',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should succeed when --exclude-paths is used with --reach',
async cmd => {
const { code, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(code, 'should exit with code 0 when all flags are valid').toBe(0)
},
)

cmdit(
[
'scan',
Expand Down
9 changes: 7 additions & 2 deletions src/commands/scan/cmd-scan-reach.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import path from 'node:path'
import { joinAnd } from '@socketsecurity/registry/lib/arrays'
import { logger } from '@socketsecurity/registry/lib/logger'

import { assertNoNegationPatterns } from './exclude-paths.mts'
import { handleScanReach } from './handle-scan-reach.mts'
import { reachabilityFlags } from './reachability-flags.mts'
import { excludePathsFlag, reachabilityFlags } from './reachability-flags.mts'
import { suggestTarget } from './suggest_target.mts'
import { validateReachabilityTarget } from './validate-reachability-target.mts'
import constants from '../../constants.mts'
Expand Down Expand Up @@ -74,6 +75,7 @@ async function run(
hidden,
flags: {
...generalFlags,
...excludePathsFlag,
...reachabilityFlags,
},
help: command =>
Expand All @@ -88,7 +90,7 @@ async function run(
${getFlagListOutput(generalFlags)}

Reachability Options
${getFlagListOutput(reachabilityFlags)}
${getFlagListOutput({ ...excludePathsFlag, ...reachabilityFlags })}

Runs the Socket reachability analysis without creating a scan in Socket.
The output is written to .socket.facts.json in the current working directory
Expand Down Expand Up @@ -167,8 +169,10 @@ async function run(
const dryRun = !!cli.flags['dryRun']

// Process comma-separated values for isMultiple flags.
const excludePaths = cmdFlagValueToArray(cli.flags['excludePaths'])
const reachEcosystemsRaw = cmdFlagValueToArray(cli.flags['reachEcosystems'])
const reachExcludePaths = cmdFlagValueToArray(cli.flags['reachExcludePaths'])
assertNoNegationPatterns(excludePaths)

// Validate ecosystem values.
const reachEcosystems: PURL_Type[] = []
Expand Down Expand Up @@ -272,6 +276,7 @@ async function run(
outputKind,
outputPath: outputPath || '',
reachabilityOptions: {
excludePaths,
reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit),
reachAnalysisTimeout: Number(reachAnalysisTimeout),
reachConcurrency: Number(reachConcurrency),
Expand Down
68 changes: 68 additions & 0 deletions src/commands/scan/cmd-scan-reach.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe('socket scan reach', async () => {
--output Path to write the reachability report to (must end with .json). Defaults to .socket.facts.json in the current working directory.

Reachability Options
--exclude-paths List of glob patterns to exclude from the scan, including SCA/SBOM manifest discovery and (when --reach is enabled) Tier 1 reachability analysis. Patterns are matched relative to the project root. Bare directory names are auto-extended to recursive globs (e.g. \`tests\` becomes \`tests/**\`). Trailing slashes are stripped. Negation patterns (\`!path\`) are not supported. Accepts a comma-separated value or multiple flags.
--reach-analysis-memory-limit The maximum memory in MB to use for the reachability analysis. The default is 8192MB.
--reach-analysis-timeout Set timeout for the reachability analysis. Split analysis runs may cause the total scan time to exceed this timeout significantly.
--reach-concurrency Set the maximum number of concurrent reachability analysis runs. It is recommended to choose a concurrency level that ensures each analysis run has at least the --reach-analysis-memory-limit amount of memory available. NPM reachability analysis does not support concurrent execution, so the concurrency level is ignored for NPM.
Expand Down Expand Up @@ -295,6 +296,50 @@ describe('socket scan reach', async () => {
'scan',
'reach',
FLAG_DRY_RUN,
'--exclude-paths',
'node_modules,dist',
'--org',
'fakeOrg',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should accept --exclude-paths with comma-separated values',
async cmd => {
const { code, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(code, 'should exit with code 0').toBe(0)
},
)

cmdit(
[
'scan',
'reach',
FLAG_DRY_RUN,
'--exclude-paths',
'node_modules',
'--exclude-paths',
'dist',
'--org',
'fakeOrg',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should accept multiple --exclude-paths flags',
async cmd => {
const { code, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(code, 'should exit with code 0').toBe(0)
},
)

cmdit(
[
'scan',
'reach',
FLAG_DRY_RUN,
'--exclude-paths',
'build',
'--reach-exclude-paths',
'node_modules,dist',
'--org',
Expand All @@ -310,6 +355,29 @@ describe('socket scan reach', async () => {
},
)

cmdit(
[
'scan',
'reach',
FLAG_DRY_RUN,
'--exclude-paths',
'!tests/keep',
'--org',
'fakeOrg',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should reject --exclude-paths negation patterns',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
const output = stdout + stderr
expect(output).toContain(
"--exclude-paths does not support negation patterns. Got: '!tests/keep'.",
)
expect(code, 'should exit with non-zero code').not.toBe(0)
},
)

cmdit(
[
'scan',
Expand Down
1 change: 1 addition & 0 deletions src/commands/scan/create-scan-from-github.mts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ async function scanOneRepo(
pendingHead: true,
pullRequest: 0,
reach: {
excludePaths: [],
reachAnalysisMemoryLimit: 0,
reachAnalysisTimeout: 0,
reachConcurrency: 1,
Expand Down
Loading