socketsecurity 2.2.81__tar.gz → 2.2.83__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/CHANGELOG.md +4 -0
  2. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/PKG-INFO +1 -1
  3. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/docs/cli-reference.md +2 -1
  4. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/pyproject.toml +1 -1
  5. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/__init__.py +1 -1
  6. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/config.py +15 -0
  7. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/git_interface.py +6 -0
  8. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/messages.py +20 -9
  9. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/socketcli.py +13 -7
  10. socketsecurity-2.2.83/tests/unit/test_disable_ignore.py +138 -0
  11. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/uv.lock +1 -1
  12. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/CODEOWNERS +0 -0
  13. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
  14. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  15. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
  16. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  17. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/workflows/docker-stable.yml +0 -0
  18. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/workflows/e2e-test.yml +0 -0
  19. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/workflows/pr-preview.yml +0 -0
  20. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/workflows/python-tests.yml +0 -0
  21. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/workflows/release.yml +0 -0
  22. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/workflows/version-check.yml +0 -0
  23. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.github/zizmor.yml +0 -0
  24. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.gitignore +0 -0
  25. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.hooks/sync_version.py +0 -0
  26. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.pre-commit-config.yaml +0 -0
  27. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/.python-version +0 -0
  28. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/Dockerfile +0 -0
  29. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/LICENSE +0 -0
  30. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/Makefile +0 -0
  31. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/README.md +0 -0
  32. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/docs/ci-cd.md +0 -0
  33. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/docs/development.md +0 -0
  34. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/docs/troubleshooting.md +0 -0
  35. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/examples/config/sarif-dashboard-parity.json +0 -0
  36. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/examples/config/sarif-dashboard-parity.toml +0 -0
  37. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/examples/config/sarif-diff-ci-cd.json +0 -0
  38. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/examples/config/sarif-diff-ci-cd.toml +0 -0
  39. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/examples/config/sarif-instance-detail.json +0 -0
  40. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/examples/config/sarif-instance-detail.toml +0 -0
  41. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/instructions/gitlab-commit-status/uat.md +0 -0
  42. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/pytest.ini +0 -0
  43. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/scripts/build_container.sh +0 -0
  44. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/scripts/build_container_flexible.sh +0 -0
  45. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/scripts/deploy-test-docker.sh +0 -0
  46. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/scripts/deploy-test-pypi.sh +0 -0
  47. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/scripts/docker-entrypoint.sh +0 -0
  48. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/scripts/run.sh +0 -0
  49. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/session.md +0 -0
  50. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socket.yml +0 -0
  51. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/__init__.py +0 -0
  52. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/alert_selection.py +0 -0
  53. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/classes.py +0 -0
  54. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/cli_client.py +0 -0
  55. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/exceptions.py +0 -0
  56. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/helper/__init__.py +0 -0
  57. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/helper/socket_facts_loader.py +0 -0
  58. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/lazy_file_loader.py +0 -0
  59. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/logging.py +0 -0
  60. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/resource_utils.py +0 -0
  61. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/scm/__init__.py +0 -0
  62. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/scm/base.py +0 -0
  63. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/scm/client.py +0 -0
  64. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/scm/github.py +0 -0
  65. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/scm/gitlab.py +0 -0
  66. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/scm_comments.py +0 -0
  67. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/socket_config.py +0 -0
  68. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/tools/reachability.py +0 -0
  69. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/core/utils.py +0 -0
  70. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/output.py +0 -0
  71. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/__init__.py +0 -0
  72. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/base.py +0 -0
  73. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/formatters/__init__.py +0 -0
  74. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/formatters/slack.py +0 -0
  75. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/jira.py +0 -0
  76. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/manager.py +0 -0
  77. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/slack.py +0 -0
  78. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/teams.py +0 -0
  79. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/socketsecurity/plugins/webhook.py +0 -0
  80. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/__init__.py +0 -0
  81. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/conftest.py +0 -0
  82. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/create_diff_input.json +0 -0
  83. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/test_diff_alerts.py +0 -0
  84. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/test_diff_generation.py +0 -0
  85. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/test_has_manifest_files.py +0 -0
  86. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/test_package_and_alerts.py +0 -0
  87. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/test_sdk_methods.py +0 -0
  88. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/core/test_supporting_methods.py +0 -0
  89. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/create_response.json +0 -0
  90. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/diff/stream_diff.json +0 -0
  91. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
  92. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/head_scan/metadata.json +0 -0
  93. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
  94. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
  95. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/new_scan/metadata.json +0 -0
  96. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
  97. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/repos/repo_info_error.json +0 -0
  98. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/repos/repo_info_no_head.json +0 -0
  99. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/repos/repo_info_success.json +0 -0
  100. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/data/settings/security-policy.json +0 -0
  101. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/fixtures/simple-npm/index.js +0 -0
  102. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/fixtures/simple-npm/package.json +0 -0
  103. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/fixtures/simple-pypi/requirements.txt +0 -0
  104. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/validate-gitlab.sh +0 -0
  105. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/validate-json.sh +0 -0
  106. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/validate-reachability.sh +0 -0
  107. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/validate-sarif.sh +0 -0
  108. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/e2e/validate-scan.sh +0 -0
  109. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/__init__.py +0 -0
  110. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_alert_selection.py +0 -0
  111. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_cli_config.py +0 -0
  112. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_client.py +0 -0
  113. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_config.py +0 -0
  114. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_gitlab_auth.py +0 -0
  115. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_gitlab_auth_fallback.py +0 -0
  116. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_gitlab_commit_status.py +0 -0
  117. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_gitlab_format.py +0 -0
  118. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_output.py +0 -0
  119. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/tests/unit/test_slack_plugin.py +0 -0
  120. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/workflows/bitbucket-pipelines.yml +0 -0
  121. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/workflows/buildkite.yml +0 -0
  122. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/workflows/github-actions.yml +0 -0
  123. {socketsecurity-2.2.81 → socketsecurity-2.2.83}/workflows/gitlab-ci.yml +0 -0
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.2.83
4
+
5
+ - Fixed branch detection in detached-HEAD CI checkouts. When `git name-rev --name-only HEAD` returned an output with a suffix operator (e.g. `remotes/origin/master~1`, `master^0`), the `~N`/`^N` was previously passed through as the branch name and rejected by the Socket API as an invalid Git ref. The suffix is now stripped before the prefix split, producing the bare branch name.
6
+
3
7
  ## 2.2.71
4
8
 
5
9
  - Added `strace` to the Docker image for debugging purposes.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socketsecurity
3
- Version: 2.2.81
3
+ Version: 2.2.83
4
4
  Summary: Socket Security CLI for CI/CD
5
5
  Project-URL: Homepage, https://socket.dev
6
6
  Author-email: Douglas Coburn <douglas@socket.dev>
@@ -151,7 +151,7 @@ socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--workspace WORKSPACE] [--
151
151
  [--excluded-ecosystems EXCLUDED_ECOSYSTEMS] [--default-branch] [--pending-head] [--generate-license] [--enable-debug]
152
152
  [--enable-json] [--enable-sarif] [--sarif-file <path>] [--sarif-scope {diff,full}] [--sarif-grouping {instance,alert}] [--sarif-reachability {all,reachable,potentially,reachable-or-potentially}] [--enable-gitlab-security] [--gitlab-security-file <path>]
153
153
  [--disable-overview] [--exclude-license-details] [--allow-unverified] [--disable-security-issue]
154
- [--ignore-commit-files] [--disable-blocking] [--enable-diff] [--scm SCM] [--timeout TIMEOUT] [--include-module-folders]
154
+ [--ignore-commit-files] [--disable-blocking] [--disable-ignore] [--enable-diff] [--scm SCM] [--timeout TIMEOUT] [--include-module-folders]
155
155
  [--reach] [--reach-version REACH_VERSION] [--reach-timeout REACH_ANALYSIS_TIMEOUT]
156
156
  [--reach-memory-limit REACH_ANALYSIS_MEMORY_LIMIT] [--reach-ecosystems REACH_ECOSYSTEMS] [--reach-exclude-paths REACH_EXCLUDE_PATHS]
157
157
  [--reach-min-severity {low,medium,high,critical}] [--reach-skip-cache] [--reach-disable-analytics] [--reach-output-file REACH_OUTPUT_FILE]
@@ -306,6 +306,7 @@ The CLI will automatically install `@coana-tech/cli` if not present. Use `--reac
306
306
  |:-------------------------|:---------|:--------|:----------------------------------------------------------------------|
307
307
  | `--ignore-commit-files` | False | False | Ignore commit files |
308
308
  | `--disable-blocking` | False | False | Disable blocking mode |
309
+ | `--disable-ignore` | False | False | Disable support for `@SocketSecurity ignore` commands in PR comments. When set, alerts cannot be suppressed via comments and ignore instructions are hidden from comment output. |
309
310
  | `--strict-blocking` | False | False | Fail on ANY security policy violations (blocking severity), not just new ones. Only works in diff mode. See [Strict Blocking Mode](#strict-blocking-mode) for details. |
310
311
  | `--enable-diff` | False | False | Enable diff mode even when using `--integration api` (forces diff mode without SCM integration) |
311
312
  | `--scm` | False | api | Source control management type |
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "socketsecurity"
9
- version = "2.2.81"
9
+ version = "2.2.83"
10
10
  requires-python = ">= 3.11"
11
11
  license = {"file" = "LICENSE"}
12
12
  dependencies = [
@@ -1,3 +1,3 @@
1
1
  __author__ = 'socket.dev'
2
- __version__ = '2.2.81'
2
+ __version__ = '2.2.83'
3
3
  USER_AGENT = f'SocketPythonCLI/{__version__}'
@@ -91,6 +91,7 @@ class CliConfig:
91
91
  files: str = None
92
92
  ignore_commit_files: bool = False
93
93
  disable_blocking: bool = False
94
+ disable_ignore: bool = False
94
95
  strict_blocking: bool = False
95
96
  integration_type: IntegrationType = "api"
96
97
  integration_org_slug: Optional[str] = None
@@ -201,6 +202,7 @@ class CliConfig:
201
202
  'files': args.files,
202
203
  'ignore_commit_files': args.ignore_commit_files,
203
204
  'disable_blocking': args.disable_blocking,
205
+ 'disable_ignore': args.disable_ignore,
204
206
  'strict_blocking': args.strict_blocking,
205
207
  'integration_type': args.integration,
206
208
  'pending_head': args.pending_head,
@@ -693,6 +695,19 @@ def create_argument_parser() -> argparse.ArgumentParser:
693
695
  action="store_true",
694
696
  help=argparse.SUPPRESS
695
697
  )
698
+ advanced_group.add_argument(
699
+ "--disable-ignore",
700
+ dest="disable_ignore",
701
+ action="store_true",
702
+ help="Disable support for @SocketSecurity ignore commands in PR comments. "
703
+ "Alerts cannot be suppressed via comments when this flag is set."
704
+ )
705
+ advanced_group.add_argument(
706
+ "--disable_ignore",
707
+ dest="disable_ignore",
708
+ action="store_true",
709
+ help=argparse.SUPPRESS
710
+ )
696
711
  advanced_group.add_argument(
697
712
  "--strict-blocking",
698
713
  dest="strict_blocking",
@@ -1,3 +1,4 @@
1
+ import re
1
2
  import urllib.parse
2
3
  import os
3
4
 
@@ -108,6 +109,11 @@ class Git:
108
109
  # Try git name-rev first (most reliable for detached HEAD)
109
110
  result = self.repo.git.name_rev('--name-only', 'HEAD')
110
111
  if result and result != 'undefined':
112
+ # Strip name-rev suffix operators (~N, ^N, or combinations
113
+ # like master~3^2). These characters are forbidden in git
114
+ # ref names, so cutting at the first occurrence can never
115
+ # truncate a real branch name.
116
+ result = re.split(r'[~^]', result, maxsplit=1)[0]
111
117
  # Clean up the result (remove any prefixes like 'remotes/origin/')
112
118
  git_detected_branch = result.split('/')[-1]
113
119
  log.debug(f"Branch detected from git name-rev: {git_detected_branch}")
@@ -850,6 +850,8 @@ class Messages:
850
850
  <tbody>
851
851
  """
852
852
 
853
+ show_ignore = not (config and getattr(config, 'disable_ignore', False))
854
+
853
855
  # Loop through security alerts (non-license), dynamically generating rows
854
856
  for alert in security_alerts:
855
857
  severity_icon = Messages.get_severity_icon(alert.severity)
@@ -858,6 +860,12 @@ class Messages:
858
860
  # Generate proper manifest URL
859
861
  manifest_url = Messages.get_manifest_file_url(diff, alert.manifests, config)
860
862
  # Generate a table row for each alert
863
+ ignore_html = (
864
+ f"<p><em>Mark as acceptable risk:</em> To ignore this alert only in this pull request, reply with:<br/>"
865
+ f"<code>@SocketSecurity ignore {alert.pkg_name}@{alert.pkg_version}</code><br/>"
866
+ f"Or ignore all future alerts with:<br/>"
867
+ f"<code>@SocketSecurity ignore-all</code></p>"
868
+ ) if show_ignore else ""
861
869
  comment += f"""
862
870
  <!-- start-socket-alert-{alert.pkg_name}@{alert.pkg_version} -->
863
871
  <tr>
@@ -870,16 +878,13 @@ class Messages:
870
878
  <summary>{alert.pkg_name}@{alert.pkg_version} - {alert.title}</summary>
871
879
  <p><strong>Note:</strong> {alert.description}</p>
872
880
  <p><strong>Source:</strong> <a href="{manifest_url}">Manifest File</a></p>
873
- <p>ℹ️ Read more on:
874
- <a href="{alert.purl}">This package</a> |
875
- <a href="{alert.url}">This alert</a> |
881
+ <p>ℹ️ Read more on:
882
+ <a href="{alert.purl}">This package</a> |
883
+ <a href="{alert.url}">This alert</a> |
876
884
  <a href="https://socket.dev/alerts/malware">What is known malware?</a></p>
877
885
  <blockquote>
878
886
  <p><em>Suggestion:</em> {alert.suggestion}</p>
879
- <p><em>Mark as acceptable risk:</em> To ignore this alert only in this pull request, reply with:<br/>
880
- <code>@SocketSecurity ignore {alert.pkg_name}@{alert.pkg_version}</code><br/>
881
- Or ignore all future alerts with:<br/>
882
- <code>@SocketSecurity ignore-all</code></p>
887
+ {ignore_html}
883
888
  </blockquote>
884
889
  </details>
885
890
  </td>
@@ -917,14 +922,20 @@ class Messages:
917
922
 
918
923
  # Generate proper manifest URL for license violations
919
924
  license_manifest_url = Messages.get_manifest_file_url(diff, first_alert.manifests, config)
920
-
925
+
926
+ license_ignore_html = (
927
+ f"<p><em>Mark the package as acceptable risk:</em> To ignore this alert only in this pull request, reply with the comment "
928
+ f"<code>@SocketSecurity ignore {first_alert.pkg_name}@{first_alert.pkg_version}</code>. "
929
+ f"You can also ignore all packages with <code>@SocketSecurity ignore-all</code>. "
930
+ f"To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.</p>"
931
+ ) if show_ignore else ""
921
932
  comment += f""" </ul>
922
933
  <p><strong>From:</strong> <a href="{license_manifest_url}">Manifest File</a></p>
923
934
  <p>ℹ️ Read more on: <a href="{first_alert.purl}">This package</a> | <a href="https://socket.dev/alerts/license">What is a license policy violation?</a></p>
924
935
  <blockquote>
925
936
  <p><em>Next steps:</em> Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at <strong>support@socket.dev</strong>.</p>
926
937
  <p><em>Suggestion:</em> Find a package that does not violate your license policy or adjust your policy to allow this package's license.</p>
927
- <p><em>Mark the package as acceptable risk:</em> To ignore this alert only in this pull request, reply with the comment <code>@SocketSecurity ignore {first_alert.pkg_name}@{first_alert.pkg_version}</code>. You can also ignore all packages with <code>@SocketSecurity ignore-all</code>. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.</p>
938
+ {license_ignore_html}
928
939
  </blockquote>
929
940
  </details>
930
941
  </td>
@@ -486,10 +486,13 @@ def main_code():
486
486
  # 3. Updates the comment to remove ignored alerts
487
487
  # This is completely separate from the main scanning functionality
488
488
  log.info("Comment initiated flow")
489
-
490
- comments = scm.get_comments_for_pr()
491
- log.debug("Removing comment alerts")
492
- scm.remove_comment_alerts(comments)
489
+
490
+ if not config.disable_ignore:
491
+ comments = scm.get_comments_for_pr()
492
+ log.debug("Removing comment alerts")
493
+ scm.remove_comment_alerts(comments)
494
+ else:
495
+ log.info("Ignore commands disabled (--disable-ignore), skipping comment processing")
493
496
 
494
497
  elif scm is not None and scm.check_event_type() != "comment" and not force_api_mode:
495
498
  log.info("Push initiated flow")
@@ -497,10 +500,13 @@ def main_code():
497
500
  log.info("Starting comment logic for PR/MR event")
498
501
  diff = core.create_new_diff(scan_paths, params, no_change=should_skip_scan, save_files_list_path=config.save_submitted_files_list, save_manifest_tar_path=config.save_manifest_tar, base_paths=base_paths, explicit_files=sbom_files_to_submit)
499
502
  comments = scm.get_comments_for_pr()
500
- log.debug("Removing comment alerts")
501
-
503
+
502
504
  # FIXME: this overwrites diff.new_alerts, which was previously populated by Core.create_issue_alerts
503
- diff.new_alerts = Comments.remove_alerts(comments, diff.new_alerts)
505
+ if not config.disable_ignore:
506
+ log.debug("Removing comment alerts")
507
+ diff.new_alerts = Comments.remove_alerts(comments, diff.new_alerts)
508
+ else:
509
+ log.info("Ignore commands disabled (--disable-ignore), all alerts will be reported")
504
510
  log.debug("Creating Dependency Overview Comment")
505
511
 
506
512
  overview_comment = Messages.dependency_overview_template(diff)
@@ -0,0 +1,138 @@
1
+ """Tests for the --disable-ignore flag."""
2
+
3
+ import pytest
4
+ from dataclasses import dataclass
5
+
6
+ from socketsecurity.config import CliConfig
7
+ from socketsecurity.core.classes import Comment, Diff, Issue
8
+ from socketsecurity.core.messages import Messages
9
+ from socketsecurity.core.scm_comments import Comments
10
+
11
+
12
+ # --- CLI flag parsing tests ---
13
+
14
+ class TestDisableIgnoreFlag:
15
+ def test_flag_defaults_to_false(self):
16
+ config = CliConfig.from_args(["--api-token", "test"])
17
+ assert config.disable_ignore is False
18
+
19
+ def test_flag_parsed_with_dashes(self):
20
+ config = CliConfig.from_args(["--api-token", "test", "--disable-ignore"])
21
+ assert config.disable_ignore is True
22
+
23
+ def test_flag_parsed_with_underscores(self):
24
+ config = CliConfig.from_args(["--api-token", "test", "--disable_ignore"])
25
+ assert config.disable_ignore is True
26
+
27
+ def test_flag_independent_of_disable_blocking(self):
28
+ config = CliConfig.from_args([
29
+ "--api-token", "test",
30
+ "--disable-ignore",
31
+ "--disable-blocking",
32
+ ])
33
+ assert config.disable_ignore is True
34
+ assert config.disable_blocking is True
35
+
36
+
37
+ # --- Alert suppression tests ---
38
+
39
+ def _make_alert(**overrides) -> Issue:
40
+ defaults = dict(
41
+ pkg_name="lodash",
42
+ pkg_version="4.17.21",
43
+ pkg_type="npm",
44
+ severity="high",
45
+ title="Known Malware",
46
+ description="Test description",
47
+ type="malware",
48
+ url="https://socket.dev/test",
49
+ manifests="package.json",
50
+ props={},
51
+ key="test-key",
52
+ purl="pkg:npm/lodash@4.17.21",
53
+ error=True,
54
+ warn=False,
55
+ ignore=False,
56
+ monitor=False,
57
+ suggestion="Remove this package",
58
+ next_step_title="Next steps",
59
+ emoji="🚨",
60
+ )
61
+ defaults.update(overrides)
62
+ return Issue(**defaults)
63
+
64
+
65
+ def _make_comment(body: str, comment_id: int = 1) -> Comment:
66
+ return Comment(
67
+ id=comment_id,
68
+ body=body,
69
+ body_list=body.split("\n"),
70
+ reactions={"+1": 0},
71
+ user={"login": "test-user", "id": 123},
72
+ )
73
+
74
+
75
+ class TestRemoveAlertsRespectedByFlag:
76
+ """Verify that Comments.remove_alerts behaves correctly so the
77
+ disable_ignore conditional in socketcli.py has the right effect."""
78
+
79
+ def test_remove_alerts_suppresses_matching_alert(self):
80
+ """Without --disable-ignore, matching alerts are removed."""
81
+ alert = _make_alert()
82
+ ignore_comment = _make_comment("SocketSecurity ignore npm/lodash@4.17.21")
83
+ comments = Comments.check_for_socket_comments({ignore_comment.id: ignore_comment})
84
+ result = Comments.remove_alerts(comments, [alert])
85
+ assert len(result) == 0
86
+
87
+ def test_alerts_preserved_when_no_ignore_comments(self):
88
+ """With --disable-ignore the caller skips remove_alerts entirely,
89
+ which is equivalent to passing empty comments."""
90
+ alert = _make_alert()
91
+ result = Comments.remove_alerts({}, [alert])
92
+ assert len(result) == 1
93
+ assert result[0].pkg_name == "lodash"
94
+
95
+ def test_ignore_all_suppresses_all_alerts(self):
96
+ alert1 = _make_alert()
97
+ alert2 = _make_alert(pkg_name="express", pkg_version="4.18.2",
98
+ purl="pkg:npm/express@4.18.2")
99
+ ignore_comment = _make_comment("SocketSecurity ignore-all")
100
+ comments = Comments.check_for_socket_comments({ignore_comment.id: ignore_comment})
101
+ result = Comments.remove_alerts(comments, [alert1, alert2])
102
+ assert len(result) == 0
103
+
104
+
105
+ # --- Comment output tests ---
106
+
107
+ @dataclass
108
+ class _FakeConfig:
109
+ disable_ignore: bool = False
110
+ scm: str = "github"
111
+
112
+
113
+ class TestSecurityCommentIgnoreInstructions:
114
+ def _make_diff_with_alert(self) -> Diff:
115
+ diff = Diff()
116
+ diff.id = "test-scan-id"
117
+ diff.diff_url = "https://socket.dev/test"
118
+ diff.new_alerts = [_make_alert()]
119
+ return diff
120
+
121
+ def test_ignore_instructions_shown_by_default(self):
122
+ diff = self._make_diff_with_alert()
123
+ config = _FakeConfig(disable_ignore=False)
124
+ comment = Messages.security_comment_template(diff, config)
125
+ assert "@SocketSecurity ignore" in comment
126
+ assert "Mark as acceptable risk" in comment
127
+
128
+ def test_ignore_instructions_hidden_when_disabled(self):
129
+ diff = self._make_diff_with_alert()
130
+ config = _FakeConfig(disable_ignore=True)
131
+ comment = Messages.security_comment_template(diff, config)
132
+ assert "@SocketSecurity ignore" not in comment
133
+ assert "Mark as acceptable risk" not in comment
134
+
135
+ def test_ignore_instructions_shown_when_config_is_none(self):
136
+ diff = self._make_diff_with_alert()
137
+ comment = Messages.security_comment_template(diff, config=None)
138
+ assert "@SocketSecurity ignore" in comment
@@ -1168,7 +1168,7 @@ wheels = [
1168
1168
 
1169
1169
  [[package]]
1170
1170
  name = "socketsecurity"
1171
- version = "2.2.81"
1171
+ version = "2.2.82"
1172
1172
  source = { editable = "." }
1173
1173
  dependencies = [
1174
1174
  { name = "bs4" },
File without changes