Skip to content

Conversation

@fproulx-boostsecurity
Copy link
Contributor

Resolves the target file(s) an attacker should inject into when exploiting a pwn request vulnerability. Static targets use a lookup table (npm→package.json, make→Makefile, etc.), dynamic targets extract file paths via regex from step.run content.

The field is an array (lotp_targets) to handle cases where a single run: block references multiple scripts. URL-based references are filtered out to only surface local repository files.

Resolves the target file(s) an attacker should inject into when
exploiting a pwn request vulnerability. Static targets use a lookup
table (npm→package.json, make→Makefile, etc.), dynamic targets
extract file paths via regex from step.run content.

The field is an array (lotp_targets) to handle cases where a single
run: block references multiple scripts. URL-based references are
filtered out to only surface local repository files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a lotp_targets field to untrusted_checkout_exec findings to identify which files an attacker would need to inject into when exploiting a pwn request vulnerability. The implementation uses static lookup tables for tools with standard configuration files (e.g., npm→package.json) and dynamic regex-based extraction for tools that reference script files in their execution commands (e.g., bash→*.sh files). URL-based references are filtered out to surface only local repository files.

Changes:

  • Added LOTPTargets field to FindingMeta struct in results.go as a string array with JSON tag lotp_targets
  • Implemented target resolution logic in utils.rego with static mappings for 32 tools and dynamic patterns for bash, powershell, python, and chmod
  • Integrated target resolution into untrusted_checkout_exec findings for GitHub Actions, Azure DevOps, and Tekton pipelines
  • Added comprehensive test coverage including static targets, dynamic multi-file scenarios, and URL filtering

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
results/results.go Added LOTPTargets field to FindingMeta struct for storing target file paths
opa/rego/poutine/utils.rego Implemented lotp_targets resolution with static lookup table and dynamic regex patterns, including URL filtering and path normalization
opa/rego/rules/untrusted_checkout_exec.rego Integrated lotp_targets into findings via _lotp_targets_meta helper function across GitHub Actions, Azure DevOps, and Tekton
scanner/inventory_test.go Updated test expectations to verify lotp_targets for various tools including npm, pre-commit, bash, chmod, and vale
scanner/testdata/.github/workflows/test_new_fields.yml Added test workflow with multi-script bash execution to test dynamic target extraction

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +82 to +112
lotp_static_targets := {
"ant": "build.xml",
"bundler": "Gemfile",
"cargo": "Cargo.toml",
"checkov": ".checkov.yml",
"docker": "Dockerfile",
"eslint": "eslint.config.js",
"golangci-lint": ".golangci.yml",
"gomplate": ".gomplate.yaml",
"goreleaser": ".goreleaser.yaml",
"gradle": "build.gradle",
"make": "Makefile",
"maven": "pom.xml",
"mkdocs": "mkdocs.yml",
"msbuild": "Directory.Build.props",
"mypy": "mypy.ini",
"npm": "package.json",
"phpstan": "phpstan.neon",
"pip": "requirements.txt",
"pre-commit": ".pre-commit-config.yaml",
"rake": "Rakefile",
"rubocop": ".rubocop.yml",
"sonar-scanner": "sonar-project.properties",
"stylelint": ".stylelintrc.js",
"terraform": "main.tf",
"tflint": ".tflint.hcl",
"tofu": "main.tf",
"vale": ".vale.ini",
"webpack": "webpack.config.js",
"yarn": "package.json",
}
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some tools in the static targets mapping use only one specific config file name, but many of these tools support multiple config file formats and names. For example:

  • eslint supports: .eslintrc.js, .eslintrc.json, .eslintrc.yml, .eslintrc.yaml, .eslintrc, eslint.config.js, eslint.config.mjs, eslint.config.cjs, and package.json
  • stylelint supports: .stylelintrc.js, .stylelintrc.json, .stylelintrc.yml, .stylelintrc.yaml, .stylelintrc, stylelint.config.js, stylelint.config.cjs, and package.json
  • mypy supports: mypy.ini, .mypy.ini, pyproject.toml, and setup.cfg

While using the most common config file is a reasonable starting point, attackers could potentially use alternative config files that aren't listed here. Consider either:

  1. Expanding the mapping to support multiple possible target files per tool (e.g., making the value an array instead of a string)
  2. Adding a comment documenting that only the most common config file is listed for each tool
  3. Using dynamic patterns for tools with many config file variations

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants