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
4 changes: 2 additions & 2 deletions dist/detectors/dockerfile-capability.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function detectRemoteAdd(added) {
}
return [
{
kind: 'dockerfile_remote_add',
kind: 'capability_echo.dockerfile_remote_add',
surface: 'container',
severity: 'high',
file: added.file,
Expand All @@ -33,7 +33,7 @@ function detectPipeToShell(added) {
}
return [
{
kind: 'dockerfile_pipe_to_shell',
kind: 'capability_echo.dockerfile_pipe_to_shell',
surface: 'container',
severity: 'critical',
file: added.file,
Expand Down
8 changes: 4 additions & 4 deletions dist/detectors/js-capability.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function detectFetch(added, testFile) {
}
return [
{
kind: 'external_fetch_added',
kind: 'capability_echo.external_fetch_added',
surface: 'source',
severity: testFile ? 'low' : 'medium',
file: added.file,
Expand All @@ -71,7 +71,7 @@ function detectSecretExfil(added, testFile, secretVariables) {
}
return [
{
kind: 'source_secret_exfil_pattern',
kind: 'capability_echo.source_secret_exfil_pattern',
surface: 'source',
severity: testFile ? 'medium' : 'high',
file: added.file,
Expand Down Expand Up @@ -101,7 +101,7 @@ function detectSubprocess(added, testFile) {
}
return [
{
kind: 'subprocess_spawn_added',
kind: 'capability_echo.subprocess_spawn_added',
surface: 'source',
severity: testFile ? 'low' : 'high',
file: added.file,
Expand All @@ -118,7 +118,7 @@ function detectDynamicEval(added, testFile) {
}
return [
{
kind: 'dynamic_eval_added',
kind: 'capability_echo.dynamic_eval_added',
surface: 'source',
severity: testFile ? 'medium' : 'critical',
file: added.file,
Expand Down
4 changes: 2 additions & 2 deletions dist/detectors/package-deps.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function compareDeps(file, oldText, newText) {
}
if (HIGH_CAPABILITY_DEPS.has(name)) {
findings.push({
kind: 'high_capability_dep_added',
kind: 'capability_echo.high_capability_dep_added',
surface: 'package',
severity: 'high',
file,
Expand All @@ -63,7 +63,7 @@ function compareDeps(file, oldText, newText) {
}
if (TELEMETRY_DEPS.has(name)) {
findings.push({
kind: 'telemetry_dep_added',
kind: 'capability_echo.telemetry_dep_added',
surface: 'package',
severity: 'medium',
file,
Expand Down
6 changes: 3 additions & 3 deletions dist/detectors/package-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function compareScripts(file, oldScripts, newScripts, newText) {
}
const line = lineOfJsonKey(newText, key) ?? lineOfJsonStringValue(newText, newValue);
findings.push({
kind: 'lifecycle_script_added',
kind: 'capability_echo.lifecycle_script_added',
surface: 'package',
severity: 'high',
file,
Expand Down Expand Up @@ -95,7 +95,7 @@ function analyzeScriptContent(file, key, script, newText) {
const line = lineOfJsonStringValue(newText, script) ?? lineOfJsonKey(newText, key);
if (/(?:curl[^\n|]*\|\s*(?:ba)?sh|wget[^\n|]*\|\s*sh|Invoke-Expression|iex\s*\()/i.test(script)) {
findings.push({
kind: 'script_pipe_to_shell',
kind: 'capability_echo.script_pipe_to_shell',
surface: 'package',
severity: 'critical',
file,
Expand All @@ -107,7 +107,7 @@ function analyzeScriptContent(file, key, script, newText) {
}
if (/\b(curl|wget|npm publish)\b/i.test(script) || /\bnpx\b(?![^\s]*@\d+\.\d+\.\d+)/i.test(script)) {
findings.push({
kind: 'script_network_command',
kind: 'capability_echo.script_network_command',
surface: 'package',
severity: 'medium',
file,
Expand Down
10 changes: 5 additions & 5 deletions dist/detectors/py-capability.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function detectPyNetwork(added, testFile) {
}
return [
{
kind: 'external_fetch_added',
kind: 'capability_echo.external_fetch_added',
surface: 'source',
severity: testFile ? 'low' : 'medium',
file: added.file,
Expand All @@ -81,7 +81,7 @@ function detectPySecretExfil(added, testFile, secretVariables) {
}
return [
{
kind: 'source_secret_exfil_pattern',
kind: 'capability_echo.source_secret_exfil_pattern',
surface: 'source',
severity: testFile ? 'medium' : 'high',
file: added.file,
Expand Down Expand Up @@ -115,7 +115,7 @@ function detectPySubprocess(added, testFile) {
}
return [
{
kind: 'subprocess_spawn_added',
kind: 'capability_echo.subprocess_spawn_added',
surface: 'source',
severity: testFile ? 'low' : 'high',
file: added.file,
Expand All @@ -136,7 +136,7 @@ function detectPyDynamicExec(added, testFile) {
}
return [
{
kind: 'dynamic_eval_added',
kind: 'capability_echo.dynamic_eval_added',
surface: 'source',
severity: testFile ? 'medium' : 'critical',
file: added.file,
Expand All @@ -157,7 +157,7 @@ function detectPyUnsafeDeserialize(added, testFile) {
}
return [
{
kind: 'unsafe_deserialize_added',
kind: 'capability_echo.unsafe_deserialize_added',
surface: 'source',
severity: testFile ? 'medium' : 'critical',
file: added.file,
Expand Down
4 changes: 2 additions & 2 deletions dist/detectors/shell-capability.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function detectPipeToShell(added) {
}
return [
{
kind: 'shell_pipe_to_shell',
kind: 'capability_echo.shell_pipe_to_shell',
surface: 'source',
severity: 'critical',
file: added.file,
Expand All @@ -33,7 +33,7 @@ function detectExternalDownload(added) {
}
return [
{
kind: 'shell_external_download',
kind: 'capability_echo.shell_external_download',
surface: 'source',
severity: 'medium',
file: added.file,
Expand Down
22 changes: 11 additions & 11 deletions dist/detectors/workflow-permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function detectWritePermissions(added) {
if (githubTokenWritePermissionPattern.test(content)) {
return [
{
kind: 'workflow_permission_write',
kind: 'capability_echo.workflow_permission_write',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand All @@ -74,7 +74,7 @@ function detectWritePermissions(added) {
if (/^\s*permissions\s*:\s*(?:write|write-all|admin)\b/i.test(content)) {
return [
{
kind: 'workflow_permission_write',
kind: 'capability_echo.workflow_permission_write',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand All @@ -93,7 +93,7 @@ function detectPullRequestTarget(added) {
}
return [
{
kind: 'workflow_pull_request_target',
kind: 'capability_echo.workflow_pull_request_target',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand All @@ -110,7 +110,7 @@ function detectPullRequestHeadCheckoutOnTarget(added, hasPullRequestTarget) {
}
return [
{
kind: 'workflow_pr_head_checkout_on_target',
kind: 'capability_echo.workflow_pr_head_checkout_on_target',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand All @@ -137,7 +137,7 @@ function detectSelfHostedRunner(added) {
}
return [
{
kind: 'workflow_self_hosted_runner',
kind: 'capability_echo.workflow_self_hosted_runner',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand All @@ -163,7 +163,7 @@ function detectMutableActionRef(added) {
}
return [
{
kind: 'workflow_mutable_action_ref',
kind: 'capability_echo.workflow_mutable_action_ref',
surface: 'workflow',
severity: 'medium',
file: added.file,
Expand All @@ -189,7 +189,7 @@ function detectExternalCurl(added) {
}
return [
{
kind: 'workflow_external_curl',
kind: 'capability_echo.workflow_external_curl',
surface: 'workflow',
severity: 'medium',
file: added.file,
Expand All @@ -206,7 +206,7 @@ function detectSecretsInherit(added) {
}
return [
{
kind: 'workflow_secrets_inherit',
kind: 'capability_echo.workflow_secrets_inherit',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand All @@ -228,7 +228,7 @@ function detectSecretExfil(added, secretEnvVars) {
}
return [
{
kind: 'workflow_secret_exfil_pattern',
kind: 'capability_echo.workflow_secret_exfil_pattern',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand All @@ -251,7 +251,7 @@ function detectDockerHostControl(added) {
const content = added.content;
if (/\/var\/run\/docker\.sock(?::\/var\/run\/docker\.sock)?/i.test(content)) {
findings.push({
kind: 'workflow_docker_socket_mount',
kind: 'capability_echo.workflow_docker_socket_mount',
surface: 'workflow',
severity: 'critical',
file: added.file,
Expand All @@ -263,7 +263,7 @@ function detectDockerHostControl(added) {
}
if (/\bdocker\s+run\b.*\s--privileged(?:\s|$)/i.test(content)) {
findings.push({
kind: 'workflow_privileged_container',
kind: 'capability_echo.workflow_privileged_container',
surface: 'workflow',
severity: 'high',
file: added.file,
Expand Down
48 changes: 24 additions & 24 deletions dist/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,30 @@ const severityRank = {
critical: 4
};
const SUMMARY_LABELS = {
external_fetch_added: 'external network fetch calls',
source_secret_exfil_pattern: 'source secret exfiltration patterns',
subprocess_spawn_added: 'subprocess or shell spawn calls',
dynamic_eval_added: 'dynamic code execution',
shell_pipe_to_shell: 'shell pipe-to-shell downloads',
shell_external_download: 'shell external downloads',
dockerfile_remote_add: 'Dockerfile remote ADD instructions',
dockerfile_pipe_to_shell: 'Dockerfile pipe-to-shell builds',
workflow_permission_write: 'GitHub Actions write permissions',
workflow_pull_request_target: 'GitHub Actions pull_request_target triggers',
workflow_pr_head_checkout_on_target: 'GitHub Actions PR-head checkout under pull_request_target',
workflow_self_hosted_runner: 'GitHub Actions self-hosted runners',
workflow_mutable_action_ref: 'GitHub Actions mutable action references',
workflow_secrets_inherit: 'GitHub Actions inherited secrets',
workflow_external_curl: 'workflow external network requests',
workflow_secret_exfil_pattern: 'workflow secret exfiltration patterns',
workflow_docker_socket_mount: 'workflow Docker socket mounts',
workflow_privileged_container: 'workflow privileged containers',
lifecycle_script_added: 'npm lifecycle scripts',
script_pipe_to_shell: 'pipe-to-shell install scripts',
script_network_command: 'network or publish npm scripts',
high_capability_dep_added: 'high-capability dependency additions',
telemetry_dep_added: 'telemetry dependency additions',
unsafe_deserialize_added: 'unsafe deserialization'
'capability_echo.external_fetch_added': 'external network fetch calls',
'capability_echo.source_secret_exfil_pattern': 'source secret exfiltration patterns',
'capability_echo.subprocess_spawn_added': 'subprocess or shell spawn calls',
'capability_echo.dynamic_eval_added': 'dynamic code execution',
'capability_echo.shell_pipe_to_shell': 'shell pipe-to-shell downloads',
'capability_echo.shell_external_download': 'shell external downloads',
'capability_echo.dockerfile_remote_add': 'Dockerfile remote ADD instructions',
'capability_echo.dockerfile_pipe_to_shell': 'Dockerfile pipe-to-shell builds',
'capability_echo.workflow_permission_write': 'GitHub Actions write permissions',
'capability_echo.workflow_pull_request_target': 'GitHub Actions pull_request_target triggers',
'capability_echo.workflow_pr_head_checkout_on_target': 'GitHub Actions PR-head checkout under pull_request_target',
'capability_echo.workflow_self_hosted_runner': 'GitHub Actions self-hosted runners',
'capability_echo.workflow_mutable_action_ref': 'GitHub Actions mutable action references',
'capability_echo.workflow_secrets_inherit': 'GitHub Actions inherited secrets',
'capability_echo.workflow_external_curl': 'workflow external network requests',
'capability_echo.workflow_secret_exfil_pattern': 'workflow secret exfiltration patterns',
'capability_echo.workflow_docker_socket_mount': 'workflow Docker socket mounts',
'capability_echo.workflow_privileged_container': 'workflow privileged containers',
'capability_echo.lifecycle_script_added': 'npm lifecycle scripts',
'capability_echo.script_pipe_to_shell': 'pipe-to-shell install scripts',
'capability_echo.script_network_command': 'network or publish npm scripts',
'capability_echo.high_capability_dep_added': 'high-capability dependency additions',
'capability_echo.telemetry_dep_added': 'telemetry dependency additions',
'capability_echo.unsafe_deserialize_added': 'unsafe deserialization'
};
export function createReport(findings, context) {
return {
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"test": "node --test test/*.test.mjs"
},
"dependencies": {
"agent-gov-core": "github:Conalh/agent-gov-core#v0.1.2"
"agent-gov-core": "github:Conalh/agent-gov-core#v0.2.0"

Check warning on line 15 in package.json

View workflow job for this annotation

GitHub Actions / scope-review

TaskBound low scope creep

Changed dependency agent-gov-core from github:Conalh/agent-gov-core#v0.1.2 to github:Conalh/agent-gov-core#v0.2.0. Recommendation: Review whether the version change is in scope for the task.
},
"devDependencies": {
"@types/node": "^24.0.0",
Expand Down
4 changes: 2 additions & 2 deletions src/detectors/dockerfile-capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function detectRemoteAdd(added: AddedLine): Finding[] {

return [
{
kind: 'dockerfile_remote_add',
kind: 'capability_echo.dockerfile_remote_add',
surface: 'container',
severity: 'high',
file: added.file,
Expand All @@ -42,7 +42,7 @@ function detectPipeToShell(added: AddedLine): Finding[] {

return [
{
kind: 'dockerfile_pipe_to_shell',
kind: 'capability_echo.dockerfile_pipe_to_shell',
surface: 'container',
severity: 'critical',
file: added.file,
Expand Down
8 changes: 4 additions & 4 deletions src/detectors/js-capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function detectFetch(added: AddedLine, testFile: boolean): Finding[] {

return [
{
kind: 'external_fetch_added',
kind: 'capability_echo.external_fetch_added',
surface: 'source',
severity: testFile ? 'low' : 'medium',
file: added.file,
Expand All @@ -93,7 +93,7 @@ function detectSecretExfil(added: AddedLine, testFile: boolean, secretVariables:

return [
{
kind: 'source_secret_exfil_pattern',
kind: 'capability_echo.source_secret_exfil_pattern',
surface: 'source',
severity: testFile ? 'medium' : 'high',
file: added.file,
Expand Down Expand Up @@ -133,7 +133,7 @@ function detectSubprocess(added: AddedLine, testFile: boolean): Finding[] {

return [
{
kind: 'subprocess_spawn_added',
kind: 'capability_echo.subprocess_spawn_added',
surface: 'source',
severity: testFile ? 'low' : 'high',
file: added.file,
Expand All @@ -152,7 +152,7 @@ function detectDynamicEval(added: AddedLine, testFile: boolean): Finding[] {

return [
{
kind: 'dynamic_eval_added',
kind: 'capability_echo.dynamic_eval_added',
surface: 'source',
severity: testFile ? 'medium' : 'critical',
file: added.file,
Expand Down
Loading