Lava
Lava is an open source vulnerability scanner that makes it easy to run security checks in your local and CI/CD environments.
Lava is part of the Vulcan ecosystem and it is built on top of the same components that power Vulcan. Thus, Lava continuously benefits from Vulcan improvements. In fact, Lava is compatible with the vulcan-checks catalog shipped with Vulcan.
The default Lava configuration covers the following security controls:
- SAST (Static Application Security Testing).
- SCA (Software Composition Analysis).
- IaC security (Infrastructure as Code Security).
- Secret detection.
- DAST (Dynamic Application Security Testing).
For more details, visit the Security controls section of the documentation.
Install
Binary distributions
Official binary distributions are available at https://github.com/adevinta/lava/releases.
Install from source
Install the Lava command with go install
.
go install github.com/adevinta/lava/cmd/lava@latest
GitHub Actions
GitHub Actions are provided to make it easy to run Lava from a GitHub Actions workflow. Visit the GitHub Actions section of the documentation for more details.
Documentation
Lava is self-documented.
Run lava help
to get more information about the available commands
and other related topics.
Contributing
This project is in an early stage, we are not accepting external contributions yet.
To contribute, please read the contribution guidelines.
Quick start
This guide is a brief introduction about how to start using Lava in your projects.
Install Lava
There are two supported options to install Lava:
- Binary distributions
- Source code
Binary distributions
Install the latest Lava command with the following command:
$ curl -LsSf https://github.com/adevinta/lava/releases/latest/download/lava_linux_amd64.tar.gz \
| tar -xz -C /usr/local/bin lava
Official binary distributions are available at https://github.com/adevinta/lava/releases.
Install from source
Install the latest Lava command with go install
.
$ go install github.com/adevinta/lava/cmd/lava@latest
Initialize a new Lava project
Lava requires a configuration file (usually named lava.yaml
) that
defines the parameters of the security scan. For instance, enabled
security checks, scan targets and reporting parameters.
$ lava init
The lava init
command produces a minimal configuration file that can
be used as base for further customization.
lava: v0.0.0
checktypes:
- https://github.com/adevinta/lava-resources/releases/download/checktypes/v0/checktypes.json
targets:
- identifier: .
type: Path
agent:
parallel: 4
report:
severity: high
log: error
For more details, see Configuration file format.
Run a local scan
Once the configuration file is in place, just run lava scan
.
$ lava scan
STATUS
- vulcansec/vulcan-trivy → .: FINISHED
- vulcansec/vulcan-semgrep → .: FINISHED
SUMMARY
CRITICAL: 0
HIGH: 2
MEDIUM: 0
LOW: 1
INFO: 0
Number of excluded vulnerabilities not included in the summary table: 0
VULNERABILITIES
...
Note that depending on the container runtime being used, it might be
necessary to customize the environment variable LAVA_RUNTIME
:
Dockerd
: Docker Engine (default)DockerdDockerDesktop
: Docker DesktopDockerdRancherDesktop
: Rancher Desktop (dockerd backend)DockerdPodmanDesktop
: Podman Desktop (dockerd compatibility layer)
For more details, see Run scan and Environment variables.
Integrate Lava with GitHub Actions
Lava provides the GitHub Action adevinta/lava-action.
Create a new workflow in the .github/workflows
directory in your
repository with the following content.
name: Lava
on: [push, pull_request]
permissions:
contents: read
jobs:
lava:
name: Lava
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run Lava Action
uses: adevinta/lava-action@v0
Security controls
Behind the scenes Lava uses other security tools and custom security checks to perform a security scan. Tools are integrated through what is called "checktypes".
Checktypes are part of the Vulcan ecosystem and both Vulcan and Lava share the same collection located at https://github.com/adevinta/vulcan-checks.
Type of security controls
The following table lists all the security controls covered by Lava's checktype collection.
Security Control | Description |
---|---|
SAST | Static Application Security Testing. It's the analysis of source code. |
SCA | Software Composition Analysis. For instance, detection of outdated dependencies. |
IaC security | Static analysis of Infrastructure as Code manifests. For instance, AWS CloudFormation templates or Terraform configurations. |
Secret detection | Search for secrets leaked in the code. |
DAST | Dynamic Application Security Testing. They perform the scan from outside while the application is running in its environment. |
Finding collection | This category refers to checktypes that do not run the analysis themselves. Instead, they collect the findings from 3rd party systems like Tenable.io or Vulners. |
Recon | Checktypes focused on reconnaissance activities. For instance, port scanning and service discovery. |
Data analysis | Checktypes focused on processing data sets to extract information considered relevant from an information security point of view. |
Enabled by default
Checktype | Description | Security Control |
---|---|---|
vulcan-semgrep | Finds potential issues in source code from a Git repository using Semgrep. Official Documentation: https://semgrep.dev/docs | SAST |
vulcan-trivy | Scan docker images and Git repositories using aquasec/trivy. Official Documentation: https://aquasecurity.github.io/trivy/latest | SCA, IaC security, Secret detection |
vulcan-retirejs | Check web pages for vulnerable JavaScript libraries. Official Documentation: https://retirejs.github.io/retire.js | SCA |
vulcan-nuclei | Scan web addresses with projectdiscovery/nuclei. Official Documentation: https://docs.projectdiscovery.io/tools/nuclei | DAST |
vulcan-zap | Runs an OWASP ZAP passive or active scan. Official Documentation: https://www.zaproxy.org/docs | DAST |
Since the check versions are updated regularly in an automatic way, the best way to know the version that Lava is using is checking the source code of each check.
Disabled by default
Checktype | Description | Security Control |
---|---|---|
vulcan-aws-alerts | Detects general issues for an AWS account. | DAST |
vulcan-aws-trusted-advisor | Runs an AWS Trusted Advisor check against an AWS account. | DAST |
vulcan-blast-radius | Calculates the blast radius of an asset. | Data analysis |
vulcan-burp | Runs a Burp Suite Enterprise Edition scan. | DAST |
vulcan-dmarc | Checks if a domain have valid DNS configuration for DMARC. | DAST |
vulcan-drupal | Checks for some vulnerable versions of Drupal. | DAST |
vulcan-exposed-bgp | Checks for exposed BGP port on Internet routers. | DAST |
vulcan-exposed-db | Checks if an asset has database well known ports open. | DAST |
vulcan-exposed-http | Checks if an asset has HTTP well known ports open. | Recon |
vulcan-exposed-memcached | Checks if the asset contains an exposed Memcached server. | DAST |
vulcan-exposed-router-ports | Checks if an asset has routers well known ports open. | DAST |
vulcan-exposed-services | Checks if a host has any open ports by scanning the 1000 most common TCP and UDP ports. | Recon |
vulcan-exposed-ssh | Checks SSH server configuration for compliance with Mozilla OpenSSH guidelines. | DAST |
vulcan-github-alerts | Retrieves existing vulnerability alerts for a Github repository. | Finding collection |
vulcan-gitleaks | Finds potential secrets in source code from a Git repository using gitleaks. | Secret detection |
vulcan-heartbleed | Checks if an asset is vulnerable to Heartbleed. | DAST |
vulcan-host-discovery | Performs a quick Nmap ping scan that identifies which hosts are up. | Recon |
vulcan-http-headers | Analyzes the HTTP headers using Mozilla Observatory. | DAST |
vulcan-ipv6 | Checks for IPv6 presence. | Recon |
vulcan-masscan | Checks if a host has any open port by scanning the whole TCP port range using masscan. | Recon |
vulcan-mx | Checks for MX DNS Records. | Recon |
vulcan-nessus | Runs a Nessus scan. | DAST |
vulcan-prowler | Runs Prowler against an AWS account. | DAST |
vulcan-smtp-open-relay | Check for testing SMTP Open Relay. | DAST |
vulcan-spf | Checks if a domain has a SPF record on DNS. | DAST |
vulcan-tenable | Retrieves findings from assets scanned by Tenable.io. | Finding collection |
vulcan-vulners | Runs the nmap-script vulners against the target opened ports. | DAST |
vulcan-wpscan | Runs Wordpress scan. | DAST |
Configuration file format
Each Lava project is defined by a configuration file (usually named lava.yaml) that defines the parameters of the security scan.
A Lava configuration file is a YAML document that supports environment variable substitution with ${ENVVAR_NAME} notation.
Example
A Lava configuration file is a YAML document as shown in the following example.
lava: v0.0.0
checktypes:
- checktypes.json
targets:
- identifier: .
type: GitRepository
- identifier: ${DOCKER_IMAGE}
type: DockerImage
agent:
parallel: 4
report:
severity: high
exclusions:
- description: Ignore test certificates.
summary: 'Secret Leaked in Git Repository'
resource: '/testdata/certs/'
log: error
This help topic describes every configuration parameter in detail.
lava
The "lava" field describes the minimum required version of the Lava command. For instance,
lava: v0.0.0
Using a Lava command whose version is lower than the minimum version required by the configuration file returns an error.
This field is mandatory.
checktypes
The "checktypes" field contains a list of URLs that point to checktype catalogs.
If the URL omits the scheme, it is considered a file path relative to the current working directory of the Lava command. For instance,
checktypes:
- checktypes.json
HTTP and HTTPS URLs are supported. For instance,
checktypes:
- https://example.com/checktypes.json
At least one catalog must be specified.
targets
The "targets" field contains the list of targets to scan. Every target is defined by the following properties:
- identifier: string that identifies the target. For instance, a path, a URL, a container image, etc. It is mandatory.
- type: the asset type of the target. Valid values are "AWSAccount", "DockerImage", "GitRepository", "IP", "IPRange", "DomainName", "Hostname", "WebAddress" and "Path". It is mandatory.
- options: map of target-specific options. These options are merged with the options coming from the checktype catalog.
For instance,
targets:
- identifier: .
type: GitRepository
options:
branch: master
At least one target must be specified.
agent
The "agent" field contains the configuration passed to the Vulcan agent that Lava runs internally. The agent accepts the following properties:
- pullPolicy: policy used to decide when to pull a required container image. Valid values are "Always", "IfNotPresent" and "Never". If not specified, "IfNotPresent" is used.
- parallel: maximum number of checks that can run in parallel. If not specified, this limit is set to one.
- vars: map with the environment variables passed to the executed checktypes.
- registries: configuration of the required container registries. It requires the following properties: "server", "username" and "password".
The sample below is a full agent configuration:
agent:
pullPolicy: Always
parallel: 4
vars:
DEBUG: true
registries:
- server: example.com
username: user
password: ${REGISTRY_PASSWORD}
It is important to note that Lava is able to use the credentials from the container runtime CLIs installed in the system. So, if these CLIs are already logged in, it is not necessary to configure the registry in the configuration file.
report
The "report" field describes how to report the findings. It supports the following properties.
- severity: minimum severity required to exit with error. Valid values are "critical", "high", "medium", "low" and "info". If not specified, "high" is used.
- show: minimum severity required to show a finding. Valid values are "critical", "high", "medium", "low" and "info". If not specified, the severity value is used.
- format: output format. Valid values are "human" and "json". If not specified, "human" is used.
- output: path of the output file. If not specified, stdout is used.
- metrics: path of the file where the metrics report will be written. If not specified, then the metrics report is not generated. For more details, use "lava help metrics".
- exclusions: list of rules that define what findings should be excluded from the report. It allows to ignore findings because of accepted risks, false positives, etc.
- errorOnStaleExclusions: boolean specifying whether Lava should exit with error when stale exclusions are detected. If not specified, the default value is false.
The sample below is a full report configuration:
report:
severity: high
show: low
format: json
output: findings.json
metrics: metrics.json
exclusions:
- description: Ignore test certificates.
summary: 'Secret Leaked in Git Repository'
resource: '/testdata/certs/'
errorOnStaleExclusions: true
The exclusion rules support the following filters:
- target: regular expression that matches the name of the affected target.
- resource: regular expression that matches the name of the affected resource.
- fingerprint: context in where the vulnerability has been found.
- summary: regular expression that matches the summary of the vulnerability.
- expiration: is the date on which the exclusion becomes inactive. The format is YYYY/MM/DD.
A finding is excluded if it matches all the filters of an exclusion rule.
It is possible to provide a human-friendly description of an exclusion rule using its "description" property.
log
The "log" field describes the logging level of the Lava command. Valid values are "debug", "info", "warn" and "error". If not specified, "info" is used. For instance,
log: error
Checktype catalog file format
A checktype is a program that integrates a third-party tool (e.g. Trivy, Semgrep, etc.) or implements a custom detection for a given vulnerability. A check is a concrete instance of a checktype that is run against a specific target with a specific set of options.
Checktypes are organized in catalogs. A checktype catalog is a collection of checktypes with their metadata and default options. This help topic describes the checktype catalog format in detail.
The list of enabled checktype catalogs is specified in the Lava configuration file. For more details, use "lava help lava.yaml".
A checktype can cover one or multiple security controls like DAST (Dynamic Application Security Testing), SAST (Static Application Security Testing), SCA (Software Composition Analysis), secret detection, etc. For instance, the vulcan-trivy checktype covers SAST for IaC, SCA and secret detection.
For more details about the security controls covered by Lava, visit https://adevinta.github.io/lava-docs/controls.html.
The "lava init" command generates a configuration file that points to a remote catalog curated by the Adevinta Security Team to provide a balanced configuration. This catalog is continuously updated to improve the quality of the results, support new types of projects, etc. By default, the configuration file pins the "v0" version, which means that every Lava execution benefits from these updates.
A checktype catalog is a JSON document as shown in the following example:
{
"checktypes": [
{
"name": "vulcan-example",
"description": "Description of the checktype",
"image": "vulcan-example:latest",
"timeout": 600,
"options": {
"branch": "example",
"depth": 1,
"check_option_1": "value_option_1",
"check_option_2": ["item1, item2"],
},
"required_vars": [
"REQUIRED_VARIABLE_1",
"REQUIRED_VARIABLE_2"
],
"assets": [
"GitRepository"
]
}
]
}
A checktype catalog entry specifies the following parameters:
- name: Name of the checktype.
- description: Description of the checktype.
- image: Name of the image needed to run the check.
- timeout: Timeout of the check.
- required_vars: Environment variables passed to the check. They are defined in the checktype's manifest.toml file.
- assets: Asset types accepted as target by the check. They are defined in the checktype's manifest.toml file.
- options:
- depth: Number of commits to fetch when the asset type is a git repository.
- branch: Branch to check out when the asset type is a git repository.
- Others options defined in the checktype's manifest.toml file of the check.
Users may provide a custom catalog if it complies with the JSON Schema defined at https://adevinta.github.io/lava-docs/specs/checktype_catalog.json.
A public collection of checktypes is maintained at https://github.com/adevinta/vulcan-checks and their corresponding Docker images are pushed to https://hub.docker.com/u/vulcansec. Every checktype includes a manifest.toml file, which contains all the information required to configure a check.
Users may also develop their own checktypes. For more details, visit https://adevinta.github.io/vulcan-docs/developing-checks.
Metrics collection
After a security scan has finished, Lava can generate a metrics file with security, operational and configuration information. This data is serialized as JSON.
For more details about how to enable this functionality, use "lava help lava.yaml".
Example
A Lava metrics file is a JSON document as shown in the following example.
{
"checktype_urls": [
"https://example.com/checktypes.json"
],
"checktypes": {
"vulcan-example": {
"name": "vulcan-example",
"description": "Example Vulcan checktype",
"image": "vulcan-example:latest",
"assets": ["GitRepository"]
}
},
"lava_version": "v0.4.2",
"config_version": "v0.0.0",
"duration": 10.986237086,
"excluded_vulnerability_count": 3,
"exclusion_count": 2,
"exit_code": 0,
"severity": "high",
"start_time": "2023-12-14T14:45:31.925307331+01:00",
"targets": [
{
"Identifier": ".",
"AssetType": "GitRepository",
"Options": null
}
],
"vulnerability_count": {
"low": 1
}
}
Collected data
A Lava metrics file contains the following data:
- checktype_urls: List of URLs pointing to checktype catalogs.
- checktypes: Checktype catalog used during the scan. It is computed by merging all the checktype catalogs specified in checktype_urls.
- lava_version: Version of the Lava command.
- config_version: Minimum version of Lava required by the configuration file.
- duration: Duration of the scan.
- excluded_vulnerability_count: Number of vulnerabilities excluded due to matching one or more exclusion rules.
- exclusion_count: Number of exclusion rules.
- exit_code: Exit code returned by the Lava command.
- severity: Minimum severity required to report a finding.
- start_time: When the scan started.
- targets: List of targets to scan.
- vulnerability_count: Number of vulnerabilities grouped by severity.
GitHub Actions
The following GitHub Actions are provided to make it easy to run Lava from a GitHub Actions workflow.
Run scan
Usage:
lava scan [flags]
Run a scan using the provided config file.
The -c flag allows to specify a configuration file. By default, "lava scan" looks for a configuration file with the name "lava.yaml" in the current directory.
The exit code of the command depends on the correct execution of the security scan and the highest severity among all the vulnerabilities that have been found.
- 0: No vulnerabilities found
- 1: Command error
- 2: Syntax error
- 3: Check error
- 4: Stale exclusions
- 100: Informational vulnerabilities found
- 101: Low severity vulnerabilities found
- 102: Medium severity vulnerabilities found
- 103: High severity vulnerabilities found
- 104: Critical severity vulnerabilities found
Those vulnerabilities that has been excluded in the configuration are not considered in the computation of the exit code. In other words, vulnerabilities with a severity that is lower than "report.severity" and vulnerabilities that match one or more "report.exclusions" rules are ignored.
Lava supports several container runtimes. The environment variable LAVA_RUNTIME allows to select which one is in use. For more details, use "lava help environment".
Run single check
Usage:
lava run [flags] checktype target
Run a checktype against a target.
Run accepts two arguments: the checktype to run and the target of the scan. The checktype is a container image reference (e.g. "vulcansec/vulcan-trivy:edge") or a path pointing to a directory with the source code of a checktype. The target is any of the targets supported by the -type flag.
The -type flag determines the type of the provided target. Valid values are "AWSAccount", "DockerImage", "GitRepository", "IP", "IPRange", "DomainName", "Hostname", "WebAddress" and "Path". If not specified, "Path" is used. For more details, use "lava help lava.yaml".
The -timeout flag sets the timeout of the checktype execution. This flag accepts a value acceptable to time.ParseDuration. If not specified, "600s" is used.
The -opt and -optfile flags specify the checktype options. The -opt flag accepts a string with the options. The -optfile flag accepts a path to an options file. The options must be provided in JSON format and follow the checktype manifest.
The -var flag sets the environment variables passed to the checktype. The environment variables must be provided using the format "name[=value]". If there is no equal sign, the value of the variable is got from the environment. This flag can be specified multiple times.
The -pull flag determines the pull policy for container images. Valid values are "Always" (always download the image), "IfNotPresent" (pull the image if it not present in the local cache) and "Never" (never pull the image). If not specified, "IfNotPresent" is used. If the checktype is a path, only "IfNotPresent" and "Never" are allowed.
The -registry flag specifies the container registry. If the registry requires authentication, the credentials are provided using the -user flag. The -user flag accepts the credentials with the format "username[:[password]]". The username and password are split around the first instance of the colon. So the username cannot contain a colon. If there is no colon, the password is read from the standard input.
The -severity flag determines the minimum severity required to exit with error. Valid values are "critical", "high", "medium", "low" and "info". If not specified, "high" is used.
The -show flag determines the minimum severity required to show a finding. Valid values are "critical", "high", "medium", "low" and "info". If not specified, the severity value is used.
The -o flag specifies the output file to write the results of the scan. If not specified, the standard output is used. The format of the output is defined by the -fmt flag. The -fmt flag accepts the values "human" for human-readable output and "json" for JSON-encoded output. If not specified, "human" is used.
The -metrics flag specifies the file to write the security, operational and configuration metrics of the scan. For more details, use "lava help metrics".
The -log flag defines the logging level. Valid values are "debug", "info", "warn" and "error". If not specified, "info" is used.
Lava supports several container runtimes. The environment variable LAVA_RUNTIME allows to select which one is in use. For more details, use "lava help environment".
Path checktype
When the specified checktype is a path that points to a directory, Lava assumes that the directory contains the source code of the checktype.
The directory must contains at least the following files:
- Dockerfile
- Go source code (*.go)
Lava will build the Go source code and then it will create a Docker image based on the Dockerfile file found in the directory. The reference of the generated image has the format "name:lava-run". Where name is the name of the directory pointed by the specified path. If the path is "/", the string "lava-checktype" is used. If the path is ".", the name of the current directory is used.
Thus, the following command:
lava run /path/to/vulcan-trivy .
would generate a Docker image with the reference "vulcan-trivy:lava-run".
Finally, the generated Docker image is used as checktype to run a scan against the provided target with the specified options.
This mode requires a working Go toolchain in PATH.
Examples
Run the checktype "vulcansec/vulcan-trivy:edge" against the current directory:
lava run vulcansec/vulcan-trivy:edge .
Run the checktype "vulcansec/vulcan-trivy:edge" against the current directory with the options stored in the "options.json" file:
lava run -optfile=options.json vulcansec/vulcan-trivy:edge .
Build and run the checktype in the path "/path/to/vulcan-trivy" against the current directory:
lava run /path/to/vulcan-trivy .
Run the checktype "vulcansec/vulcan-nuclei:edge" against the remote "WebAddress" target "https://example.com":
lava run -type=WebAddress vulcansec/vulcan-nuclei:edge https://example.com
Run the checktype "vulcansec/vulcan-nuclei:edge" against the local "WebAddress" target "http://localhost:1234". Write the results in JSON format to the "output.json" file. Also write security, operational and configuration metrics to the "metrics.json" file:
lava run -o output.json -fmt=json -metrics=metrics.json \
-type=WebAddress vulcansec/vulcan-nuclei:edge http://localhost:1234
Init Lava project
Usage:
lava init [flags]
Initializes a Lava project.
This command creates a default Lava configuration file.
The -c flag allows to specify the name of the configuration file. By default, a file with the name "lava.yaml" is created in the current directory.
The -f flag allows to overwrite the output configuration file if it exists.
Print Lava version
Usage:
lava version
Version prints the version of the Lava command.
Environment variables
The lava command consults environment variables for configuration. If an environment variable is unset or empty, the lava command uses a sensible default setting.
General-purpose environment variables:
LAVA_FORCECOLOR
Forces colorized output. By default, colorized output
is disabled if the lava command is not executed from a
terminal, it is executed from a "dumb" terminal or the
NO_COLOR environment variable is set.
LAVA_RUNTIME
Controls the container runtime used by the lava
command. Valid values are "Dockerd" and
"DockerdDockerDesktop". If not specified, "Dockerd" is
used. The values "DockerdRancherDesktop" and
"DockerdPodmanDesktop" are also valid, but they are
considered experimental.
Latest Lava release
Official binary distributions are available at https://github.com/adevinta/lava/releases.
Download the latest Lava release.