Skip to main content

Fast and syntax-aware semantic code pattern search for many languages: like grep but for code

Project description

Semgrep

Homebrew r2c Community Slack

semgrep is a tool for easily detecting and preventing bugs and anti-patterns in your codebase. It combines the convenience of grep with the correctness of syntactical and semantic search. Developers, DevOps engineers, and security engineers use semgrep to write code with confidence.

Try it now: https://semgrep.live

Overview

Language support:

Python Javascript Go       Java   C         Typescript PHP    
Coming... Coming...

Example patterns:

Pattern Matches
$X == $X if (node.id == node.id): ...
requests.get(..., verify=False, ...) requests.get(url, timeout=3, verify=False)
os.system(...) from os import system; system('echo semgrep')
$ELEMENT.innerHTML el.innerHTML = "<img src='x' onerror='alert(`XSS`)'>";
$TOKEN.SignedString([]byte("...")) ss, err := token.SignedString([]byte("HARDCODED KEY"))

see more example patterns in the live registry viewer

Installation

On macOS, binaries are available via Homebrew:

brew install returntocorp/semgrep/semgrep

On Ubuntu, an install script is available on each release here

./semgrep-v0.8.0-ubuntu-generic.sh

To try semgrep without installation, you can also run it via Docker:

docker run --rm -v "${PWD}:/home/repo" returntocorp/semgrep --help

Usage

Example Usage

Here is a simple Python example, test.py. We want to retrieve an object by ID:

def get_node(node_id, nodes):
    for node in nodes:
        if node.id == node.id:  # Oops, supposed to be 'node_id'
            return node
    return None

This is a bug. Let's use semgrep to find bugs like it, using a simple search pattern: $X == $X. It will find all places in our code where the left- and right-hand sides of a comparison are the same expression:

$ semgrep --lang python --pattern '$X == $X' test.py
test.py
3:        if node.id == node.id:  # Oops, supposed to be 'node_id'

Configuration

For simple patterns use the --lang and --pattern flags. This mode of operation is useful for quickly iterating on a pattern on a single file or folder:

semgrep --lang javascript --pattern 'eval(...)' path/to/file.js

Configuration Files

For advanced configuration use the --config flag. This flag automagically handles a multitude of input configuration types:

  • --config <file|folder|yaml_url|tarball_url|registy_name>

In the absence of this flag, a default configuration is loaded from .semgrep.yml or multiple files matching .semgrep/**/*.yml.

Pattern Features

semgrep patterns make use of two primary features:

  • Metavariables like $X, $WIDGET, or $USERS_2. Metavariable names can only contain uppercase characters, or _, or digits, and must start with an uppercase character or _ - names like $x or $some_value are invalid. Metavariables are used to track a variable across a specific code scope.
  • The ... (ellipsis) operator. The ellipsis operator abstracts away sequences so you don't have to sweat the details of a particular code pattern.

For example,

$FILE = open(...)

will find all occurrences in your code where the result of an open() call is assigned to a variable.

Composing Patterns

You can also construct rules by composing multiple patterns together.

Let's consider an example:

rules:
  - id: open-never-closed
    patterns:
      - pattern: $FILE = open(...)
      - pattern-not-inside: |
          $FILE = open(...)
          ...
          $FILE.close()
    message: "file object opened without corresponding close"
    languages: [python]
    severity: ERROR

This rule looks for files that are opened but never closed. It accomplishes this by looking for the open(...) pattern and not a following close() pattern. The $FILE metavariable ensures that the same variable name is used in the open and close calls. The ellipsis operator allows for any arguments to be passed to open and any sequence of code statements in-between the open and close calls. We don't care how open is called or what happens up to a close call, we just need to make sure close is called.

For more information on rule fields like patterns and pattern-not-inside see the configuration documentation.

Equivalences

Equivalences are another key concept in semgrep. semgrep automatically searches for code that is semantically equivalent. For example, the following patterns are semantically equivalent. The pattern subprocess.Popen(...) will fire on both.

subprocess.Popen("ls")
from subprocess import Popen as sub_popen

result = sub_popen("ls")

For a full list of semgrep feature support by language see the language matrix.

Registry

As mentioned above, you may also specify a registry name as configuration. r2c provides a registry of configuration files. These rules have been tuned on thousands of repositories using our analysis platform.

semgrep --config r2c

Programmatic Usage

To integrate semgrep's results with other tools, you can get results in machine-readable JSON format with the --json option, or formatted according to the SARIF standard with the --sarif flag.

See our output documentation for details.

Resources

Contribution

semgrep is LGPL-licensed, feel free to help out: CONTRIBUTING.

semgrep is a frontend to a larger program analysis library named pfff. pfff began and was open-sourced at Facebook but is now archived. The primary maintainer now works at r2c. semgrep was originally named sgrep and was renamed to avoid collisons with existing projects.

Commercial Support

semgrep is proudly supported by r2c. We're hiring!

Interested in a fully-supported, hosted version of semgrep? Drop your email and we'll ping you!

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

semgrep-0.8.0b1.tar.gz (66.3 kB view details)

Uploaded Source

Built Distributions

semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-manylinux1_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.6 CPython 3.7 CPython 3.8 Python 3.6 Python 3.7 Python 3.8

semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-macosx_10_14_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.6 CPython 3.7 CPython 3.8 Python 3.6 Python 3.7 Python 3.8 macOS 10.14+ x86-64

File details

Details for the file semgrep-0.8.0b1.tar.gz.

File metadata

  • Download URL: semgrep-0.8.0b1.tar.gz
  • Upload date:
  • Size: 66.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/46.0.0 requests-toolbelt/0.8.0 tqdm/4.36.1 CPython/3.7.7

File hashes

Hashes for semgrep-0.8.0b1.tar.gz
Algorithm Hash digest
SHA256 82ba5564e725029c349dd4fc01367591a0cb0713542536e8644a32e0a260e8e3
MD5 205deaf2bcddd2f359c22c91fe43f5c3
BLAKE2b-256 729e837cfb806a017652a5e6a2b2584c7979937cc93ae5b1288fe3384c83db96

See more details on using hashes here.

File details

Details for the file semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-manylinux1_x86_64.whl.

File metadata

  • Download URL: semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.8 MB
  • Tags: CPython 3.6, CPython 3.7, CPython 3.8, Python 3.6, Python 3.7, Python 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/46.0.0 requests-toolbelt/0.8.0 tqdm/4.36.1 CPython/3.7.7

File hashes

Hashes for semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 fde2b502ba193b1c9a66f2ce4d61ea10f5b151fafbbebefabc24358a42cde550
MD5 2099481496a6863aef651ca9c32c0e24
BLAKE2b-256 f1d3d4432b9655aa290844986c16e561420dc44c162feecc98e178f01de6a0e0

See more details on using hashes here.

File details

Details for the file semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.6, CPython 3.7, CPython 3.8, Python 3.6, Python 3.7, Python 3.8, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/46.0.0 requests-toolbelt/0.8.0 tqdm/4.36.1 CPython/3.7.7

File hashes

Hashes for semgrep-0.8.0b1-cp36.cp37.cp38.py36.py37.py38-none-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 a37e7eb73cd2f0afcc7d7774f0898b3cc810e00aea97a018f5a277665b6a6bb5
MD5 3c0d9f9337fd5c169354591c97dfddf9
BLAKE2b-256 9fe0314e219054deea33108c00837e8862f83727fda9199571accb523fce809b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page