This repo is always a work in progress. Feel free to suggest improvements or requirements as well. Check out similar projects like @Deivitto's auditor-docker and @trailofbit's eth-security-toolbox.
The most important thing about these devcontainers is that we always try to find the best way to install the most popular tools, so they can all work seamlessly, and at the same time, add security by default. If you want to know more and really want to take advantage of these devcontainers, read below.
Important
Dev Containers can improve your workflow, but they are not a fully secure environment.
If you need to run untrusted or suspicious code, use GitHub Codespaces, GitPod, or a similar remote setup — never run it directly on your machine.
Caution
VS Code considerations:
VS Code does a lot to improve user experience, but that doesn't come without security tradeoffs. VS Code might allow API calls that can lead to running arbitrary commands on the host machine, and by default, it shares sockets such as the gpg-agent’s, which means keys stored outside the container can be used for signing. This opens the door to blind-signing commits scenarios, where a process inside the container may trigger signatures without the user’s full awareness. If you want to deep dive into these "tricks", we're working on an article covering the most relevant of them — stay tuned.
You can also run our prebuilt container intended for GitHub Codespaces:
You can use any prebuilt container using our Devcontainer Wizard:
We now offer multiple devcontainer configurations to suit different security and development needs:
Complete network hardening.
- Focus: Hardened workspace using tmpfs without network.
- Includes: Git, GitHub CLI; security tools available via Dockerfile
- Security: Capability dropping, AppArmor, no-new-privileges, multiple tmpfs mounts; not read-only
- Network: Uses bridge networking (no network isolation by default)
- Extensions: None configured by default (because it fails with
network-none
)
Use case: Use an hardened workspace without copying your environment.
- Focus: Security hardening with maintained network connectivity and security extensions
- Includes: Security tools, Foundry, Hardhat, audit tools via Dockerfile
- Security: Capability dropping, AppArmor, no-new-privileges, tmpfs workspace hardening
- Network: Uses bridge networking (no network isolation by default)
- Extensions: Comprehensive security extensions (Ethereum Security Bundle, Trail of Bits tools)
Use case: Do smart contract audits, security analysis, research workflows.
- Focus: Specialized audit tooling with Docker-in-Docker support
- Includes: Slither, Mythril, Crytic-compile, Foundry, Hardhat, Echidna
- Workspace: Host workspace bind-mounted into
/workspace
- Features: Docker-in-Docker, specialized audit extensions, focused toolchain
- Extensions: Solidity visual auditor, metrics, audit tools, GitLens
Use case: Use Hardhat and Foundry without setup. Basic development, resource-constrained environments.
- Focus: Core tools only, streamlined development environment
- Includes: Foundry, Hardhat, basic Solidity support, essential Python tools
- Security: Basic hardening, capability dropping, IPv6 disabled
- Workspace: Host workspace bind-mounted into
/workspace
- Extensions: Core development extensions only
Use case: Audit smart contracts using all the tools selected by Trail of Bits.
- Focus: All the tools in the ETH Security Toolbox.
- Includes: All the tools in the ETH Security Toolbox.
- Workspace: Host workspace bind-mounted into
/workspace
(no hardening) - Extensions: All the tools in the ETH Security Toolbox.
Intended for use with GitHub Codespaces, is like eth-security-toolbox
variant without runArgs
.
Use case: Maximum security hardening with read-only filesystem and ephemeral workspace.
- Focus: Strong hardening with read-only filesystem and ephemeral workspace
- Includes: Git, GitHub CLI; minimal by default
- Security: Read-only filesystem, capability dropping, extensive tmpfs mounts for VS Code and caches
- Network: No explicit network hardening by default (can be enabled via
--network=none
) - Extensions: None configured by default
Use case: Comprehensive development, learning, full-stack projects, research
- Focus: Full-featured development environment with comprehensive security tools
- Includes: Complete tool suite, all security tools, fuzzing tools, analysis tools
- Security: Comprehensive hardening; workspace hardened via tmpfs
- Workspace: Hardened workspace (tmpfs mount, not host-bound)
- Extensions: Full extension suite, all security and development tools
The project supports multiple devcontainer configurations for different use cases:
.devcontainer/
├── hardened/ # Hardened
├── airgapped/ # Enhanced security with flexibility
├── auditor/ # Specialized audit environment
├── minimal/ # Essential tools only
└── legacy/ # Complete toolchain (original)
- Choose your variant based on your needs (see above)
- Navigate to the variant directory:
cd .devcontainer/[variant-name]
- Open in VS Code:
code .
- Reopen in Container: Select the appropriate devcontainer when prompted
- Visual Studio Code.
- DevContainer extension by MS:
ms-vscode-remote.remote-containers
. - Must have installed on your local OS:
docker
anddocker-buildx
.
- Start the docker service, and make sure your user is in the
docker
group. Otherwise, add yourself to it but you'll have to log in back again. - Clone this repo and navigate to your preferred devcontainer variant:
git clone <this-repo> cd .devcontainer/[auditor|minimal|legacy-theredguild|legacy-minimal]
- Open the variant folder with VS Code: Running
code .
works well. - Select "Reopen in Container" and wait. This will build the container volume.
- First time setup: If this is your first time, you'll be prompted to press enter on a console log that triggers the terminal.
- Subsequent uses: Go to the extensions section, click the Remote Explorer tab and select the active devcontainer.
Pro Tip: Each variant has its own configuration, so you can switch between them by opening different variant folders in VS Code.
If you open the Command Palette (Ctrl+Shift+p or whatever your shortcut is) you can access several features:
- You can attach VS Code to a running container, where you can open any folder or Clone a repository.
- You can open new folders or workspaces of your liking inside the current volume.
- You can even clone a new repository in a new volume based on the same devcontainer.
Note: The features listed below are primarily for the Legacy The Red Guild variant. Each variant has its own tailored set of features. Check the specific variant's configuration for details.
- JuanBlanco.solidity
- tintinweb.solidity-visual-auditor
- tintinweb.solidity-metrics
- tintinweb.vscode-solidity-flattener
- tintinweb.vscode-vyper
- tintinweb.vscode-LLL
- streetsidesoftware.code-spell-checker
- gimenete.github-linker
- ryu1kn.partial-diff
- tintinweb.vscode-inline-bookmarks
- eamodio.gitlens
- tintinweb.vscode-ethover
- trailofbits.weaudit
- tintinweb.vscode-inline-bookmarks
- tintinweb.vscode-solidity-language
- tintinweb.graphviz-interactive-preview
- NomicFoundation.hardhat-solidity
- Olympixai.olympix
- trailofbits.contract-explorer
- tintinweb.vscode-decompiler
- Foundry: Really fast modular toolkit (forge, anvil, cast).
- Hardhat: Dev environment to develop, deploy, test and debug.
-
Fuzzing:
- Medusa: Parallelized, coverage-guided, mutational Solidity smart contract fuzzing, powered by go-ethereum.
- Echidna: Fuzz testing for Ethereum contracts (prebuilt binary).
- ityfuzz: Ethereum fuzzing tool for contract vulnerabilities.
-
Static Analysis:
- Slither: Static analysis for Solidity and Vyper.
- Slitherin: Slither detectors.
- Semgrep: Lightweight static analysis with custom rule definitions.
- Slither: Static analysis for Solidity and Vyper.
-
Symbolic execution:
- Mythril: A symbolic-execution-based securty analysis tool for EVM bytecode.
- Halmos: A symbolic testing tool for EVM smart contracts.
-
Decompilers:
- Panoramix: Smart contract decompiler.
-
Other:
- Slither-LSP: Language server for enhanced contract analysis.
- napalm: A project management utility for custom solidity vulnerability detectors. To include some default collections you need to install napalm-core manually.
- Heimdall: An advanced EVM smart contract toolkit specializing in bytecode analysis and extracting information from unverified contracts.
- Aderyn: Rust-based Solidity AST analyzer.
- solc-select: Solc version manager for multiple Solidity versions.
- vyper: Pythonic language for Ethereum smart contracts.
- Package Managers:
- asdf: Multiple runtime version manager.
- npm, pnpm, yarn: JavaScript package managers.
- pipx: Isolated Python package manager.
- cargo: Rust package manager.
- uv: Utility manager.
- nvm: Node.js version manager.
- JavaScript, Python, Go, Rust, Vyper, Solidity.
ZSH. Configured with Oh-My-ZSH and autocompletions for: medusa, anvil, cast, forge.
- building-secure-contracts: Repository with security-focused Solidity examples.
- Remember to disable telemetry.
Ctrl+Shift+P > Open Settings (UI) >
typetelemetry
and uncheck all the boxes. Alternatively you can add them directly by going toOpen Settings (JSON)
, example:
"telemetry.telemetryLevel": "off",
"gitlens.telemetry.enabled": false,
"partialDiff.enableTelemetry": false,
SELinux (Security-Enhanced Linux) is a mandatory access control (MAC) system that restricts processes and users to only the resources they are explicitly allowed to access, enhancing system security.
You can check if you have this already enabled by running sudo sestatus
If you don't have SELinux installed, and you really want up your game, and protect your host from
container escapes go ahead and install it. Find whichever guide convinves you the most! Afterward,
enable it inside /etc/docker/daemon.json
(it should be enabled by default afaik).
❯ cat /etc/docker/daemon.json
{
"selinux-enabled": true
}
seccomp is a Linux kernel feature that restricts the system calls that a process can make. It's a more restrictive security mechanism than SELinux.
To manually enable seccomp you can specify a profile like this:
"--security-opt", "seccomp=profile.json"
AppArmor is a Linux security module that enforces file and network access restrictions for applications through profiles. It sometimes can be more straighforward than SELinux.
You can check it has been enabled by running sudo apparmor_status
.
This has been enabled via the argument:
"--security-opt", "apparmor:docker-default"`
Capabilities in Linux are fine-grained permissions that allow processes to perform specific privileged operations without granting full root privileges. They break down the all-or-nothing nature of root access into smaller, specific rights, improving security.
We have done this by running the following argument:
"--cap-drop=ALL"
This allows us to reduce attack surface by limiting privileged operations. And avoid the need to run processes as full root.
A few examples:
CAP_NET_ADMIN
: Allows network administration (e.g., configuring interfaces).CAP_CHOWN
: Allows changing file ownership.
There's a flag that allows you to avoid getting the user more privilages than it already has. So if you want to use sudo or elevate privilages, you can restart your container after commenting the following line:
"--security-opt", "no-new-privileges",
This may be one of the safest configurations out there but a hard one to use, at least for development environments.
It's trickier because it limits a lot what you can do. But if you want to
experiment by yourself, you can start by enabling the "--read-only"
flag and troubleshooting under
the mount
section which volumes are mandatory needed as writable.
- Verifies natspec for: constructors, variables, functions, structs, errors, events, modifiers
- Finds misspelled or missing @param or @return's.
- Lets you enforce the need for @inheritdoc in public/external functions.
- Can integrate on your daily workflow, or just as a final check.
npx @defi-wonderland/natspec-smells --include "src/**/*.sol"
-
Install the package:
yarn add --dev @defi-wonderland/natspec-smells
-
Create a config file named
natspec-smells.config.js
, you can use the following as an example:/** * List of supported options: https://github.com/defi-wonderland/natspec-smells?tab=readme-ov-file#options */ /** @type {import('@defi-wonderland/natspec-smells').Config} */ module.exports = { include: 'src/**/*.sol', exclude: '(test|scripts)/**/*.sol', };
-
Run
yarn natspec-smells
Currently semgrep supports Solidity in experimental
mode. Some of the rules may not work until Solidity is in beta
at least.
Important: Some of the rules utilize the taint mode, which is restricted to the same function in the open-source version of semgrep. To take advantage of intra-procedural taint analysis, you must include the
--pro
flag with each command. Please note that this requires semgrep Pro.
- By cloning the repository:
$ semgrep --config solidity/security path/to/your/project
- By using semgrep registry:
$ semgrep --config p/smart-contracts path/to/your/project
To add a new devcontainer variant:
- Create a new directory in
.devcontainer/
- Add your configuration files:
Dockerfile
(if custom build needed)devcontainer.json
(required)- Any additional configuration files
- Update the CI workflow in
.github/workflows/main.yml
to include your variant - Test locally before submitting a PR
- Update this README to document your new variant
- Naming: Use descriptive, lowercase names (e.g.,
auditor
,minimal
) - Configuration: Keep variants focused on specific use cases
- Documentation: Document what each variant is best for
- Testing: Ensure your variant passes CI/CD checks
# Hadolint
hadolint Dockerfile
# Dockerfile linter
dockerfile-lint -f Dockerfile
# Trivy misconfiguration
trivy config .
# Checkov
checkov -f Dockerfile
# First authenticate, open the link.
snyk auth --auth-type=token
# Run Snyk
snyk container test app:latest --file=Dockerfile
# Scan images with Dockle
dockle theredguild/devsecops-toolkit:minimal
dockle goodwithtech/dockle-test:v2
asdf
is a versatile version manager for programming languages and tools. It allows you to install
and manage multiple versions of tools like Go, Python, Node.js, and more, all in one place. It's
especially useful for projects requiring specific tool versions.
Add the plugin for the language or tool you need:
asdf plugin add <language/tool>
asdf plugin list all
Golang: asdf plugin add golang
Node.js: asdf plugin add nodejs
asdf install golang 1.20.5
asdf install nodejs 18.15.0
asdf global golang 1.20.5
asdf local golang 1.19.2
uv
is a fast Python package installer and resolver, written in Rust. It's designed to be a drop-in replacement for pip, pip-tools, and virtualenv, offering significantly faster performance and better dependency resolution. It's especially useful for Python projects requiring fast package management and reliable dependency resolution.
Install and manage multiple Python versions:
# Install a specific Python version
uv python install 3.11.5
uv python install 3.12.0
# List installed Python versions
uv python list
# Use a specific Python version
uv python use 3.11.5
# Create a new virtual environment
uv venv
# Create a virtual environment with a specific Python version
uv venv --python 3.11.5
# Activate the virtual environment
source .venv/bin/activate # On Unix/macOS
# or
.venv\Scripts\activate # On Windows
# Install a single package
uv add requests
# Install packages with specific versions
uv add "fastapi>=0.100.0" "uvicorn[standard]"
# Install development dependencies
uv add --dev pytest black flake8
# Install from requirements.txt
uv pip install -r requirements.txt
# Install tools globally (similar to pipx)
uv tool install black
uv tool install flake8
uv tool install mypy
# Initialize a new Python project
uv init my-project
cd my-project
# Add dependencies to pyproject.toml
uv add requests fastapi
# Install all project dependencies
uv sync
# Generate requirements.txt
uv export --format requirements-txt > requirements.txt
# Install the latest version
nvm install --lts
# Install version 14
nvm install 14
# Use a specific version
nvm use 12.22.7
# List current installations
nvm ls
- Article (references this repo's branch article): Where do you run your code?
- Article (references this repo's branch article): Where do you run your code II? - hardening
- Workshop: Come and build your own devContainer! @ the-mu