Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# =========================== Build stage ===========================
FROM astral/uv:python3.12-bookworm-slim AS builder
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=0

WORKDIR /app
COPY pyproject.toml /app/pyproject.toml
COPY uv.lock /app/uv.lock
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-install-project --no-dev --extra test

COPY codesectools /app/codesectools
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-dev --extra test

# =========================== Base ===========================
FROM python:3.12-slim-bookworm

ARG UID=1000
ARG GID=1000

SHELL ["/bin/bash", "-c"]

RUN apt update -qq && \
DEBIAN_FRONTEND=noninteractive \
apt install \
sudo \
curl git \
cloc \
openjdk-17-jdk-headless maven \
build-essential bear \
-y -qq --no-install-recommends && \
rm -rf /var/lib/apt/lists/*

RUN groupadd -g $GID codesectools && \
useradd -l -u $UID -g codesectools -m codesectools -s /bin/bash && \
echo "codesectools ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/codesectools && \
chmod 0440 /etc/sudoers.d/codesectools

USER codesectools
WORKDIR /home/codesectools

RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/home/codesectools/.local/bin:$PATH"

# =========================== SAST tools ===========================
RUN uv venv sasts
ENV PATH="/home/codesectools/sasts:$PATH"
ENV PATH="/home/codesectools/sasts/bin:$PATH"

# Semgrep Community Edition
RUN uv pip install --no-cache semgrep

# Bearer
RUN curl -sfL https://raw.githubusercontent.com/Bearer/bearer/main/contrib/install.sh | BINDIR=/home/codesectools/sasts sh

# SpotBugs
RUN curl -sL https://github.com/spotbugs/spotbugs/releases/download/4.9.8/spotbugs-4.9.8.tgz | tar -xzvf - && \
mv spotbugs-* /home/codesectools/sasts/spotbugs && \
curl -sL https://search.maven.org/remotecontent?filepath=com/h3xstream/findsecbugs/findsecbugs-plugin/1.14.0/findsecbugs-plugin-1.14.0.jar > /home/codesectools/sasts/spotbugs/plugin/findsecbugs-plugin-1.14.0.jar
ENV PATH="/home/codesectools/sasts/spotbugs/bin:$PATH"

# Cppcheck
RUN sudo apt update -qq && \
DEBIAN_FRONTEND=noninteractive sudo apt install cppcheck -y -qq --no-install-recommends && \
sudo rm -rf /var/lib/apt/lists/*

# =========================== CodeSecTools ===========================
COPY --from=builder --chown=codesectools:codesectools /app /app
ENV PATH="/app/.venv/bin:$PATH"

# https://github.com/sarugaku/shellingham/issues/87
RUN find /app -path "*/shellingham/__init__.py" -exec sed -i 's#raise ShellDetectionFailure()#return ("bash", "/bin/bash")#g' {} \; && \
cstools --install-completion
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Export variables
export UID := $(shell id -u)
export GID := $(shell id -g)

# Add a help target to a Makefile that will allow all targets to be self documenting
# https://gist.github.com/prwhite/8168133
all:
Expand All @@ -17,19 +21,17 @@ profile: ## Run profiling

test: ## Run tests in a Docker container
@docker compose build 1>/dev/null
@docker compose run --rm no-sast
@docker compose run --rm with-sast
@docker compose run --rm test

test-force: ## Run tests in a Docker container while ignoring any stored state
@docker volume rm codesectools_pytest-cache 2>&1 1>/dev/null || true
@docker volume rm codesectools_cstools-cache 2>&1 1>/dev/null || true
@docker compose build 1>/dev/null
@docker compose run --rm no-sast
@docker compose run --rm with-sast
@docker compose run --rm test

test-debug: ## Spawn an interactive shell in the test container to debug
@docker compose build
@docker compose run --rm with-sast /bin/bash
@docker compose run --rm test /bin/bash

docs-serve: ## Serve the documentation locally
@mkdocs serve --livereload
75 changes: 53 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ A framework for code security that provides abstractions for static analysis too
- [SAST Tool Integration Status](#sast-tool-integration-status)
- [Usage](#usage)
- [Command-line interface](#command-line-interface)
- [Docker](#docker)
- [Python API](#python-api)

<!--start-include-->
Expand Down Expand Up @@ -59,28 +60,58 @@ For more details on the design and integration of SAST tools and datasets in Cod

```bash
$ cstools

Usage: cstools [OPTIONS] COMMAND [ARGS]...

CodeSecTools: A framework for code security that provides abstractions for static analysis tools and datasets to support their integration,
testing, and evaluation.

╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --debug -d Show debugging messages and disable pretty exceptions. │
│ --version -v Show the tool's version. │
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ status Display the availability of SAST tools and datasets. │
│ allsast Run all available SAST tools together. │
│ bearer Bearer SAST │
│ coverity Coverity Static Analysis │
│ semgrepce Semgrep Community Edition Engine │
│ snykcode Snyk Code │
│ spotbugs SpotBugs │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Usage: cstools [OPTIONS] COMMAND [ARGS]...

CodeSecTools CLI.

╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --debug -d Show debugging messages and disable pretty exceptions. │
│ --version -v Show the tool's version. │
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ status Display the availability of SAST tools and datasets. │
│ allsast Run all available SAST tools together. │
│ bearer Bearer SAST │
│ coverity Coverity Static Analysis │
│ cppcheck Cppcheck │
│ semgrepce Semgrep Community Edition Engine │
│ snykcode Snyk Code │
│ spotbugs SpotBugs │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```

#### Docker

A Docker image is available with only free and offline SAST tools pre-installed.

```bash
UID=$(id -u) GID=$(id -g) docker compose build main
docker run -it -v $HOME/.codesectools:/home/codesectools/.codesectools codesectools /bin/bash
```

Mount necessary directories if you want to include:

- a target (`-v ./myproject:/home/codesectools/myproject`)
- existing CodeSecTools data (`-v $HOME/.codesectools:/home/codesectools/.codesectools`)

A better way is to use the CLI:

```bash
$ cstools -d docker --help

Usage: cstools docker [OPTIONS]

Start the Docker environment for the specified target (current directory by default).

╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --target PATH The directory to mount inside the container. [default: .] │
│ --isolation --no-isolation Enable network isolation for the container (disables host network sharing). [default: no-isolation] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

```

#### Python API
Expand Down
22 changes: 22 additions & 0 deletions codesectools/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""

import os
import shutil
from pathlib import Path
from typing import Optional

Expand Down Expand Up @@ -201,5 +202,26 @@ def download(

cli.add_typer(build_all_sast_cli())

if shutil.which("docker"):

@cli.command()
def docker(
target: Annotated[
Path, typer.Option(help="The directory to mount inside the container.")
] = Path("."),
isolation: Annotated[
bool,
typer.Option(
help="Enable network isolation for the container (disables host network sharing)."
),
] = False,
) -> None:
"""Start the Docker environment for the specified target (current directory by default)."""
from codesectools.shared.docker import AnalysisEnvironment

env = AnalysisEnvironment(isolation=isolation)
env.start(target=target.resolve())


for _, sast_data in SASTS_ALL.items():
cli.add_typer(sast_data["cli_factory"].build_cli())
Loading