Lava

Lava is an open source vulnerability scanner that makes it easy to run security checks in your local and CI/CD environments.

Lava logo

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 Desktop
  • DockerdRancherDesktop: 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 ControlDescription
SASTStatic Application Security Testing. It's the analysis of source code.
SCASoftware Composition Analysis. For instance, detection of outdated dependencies.
IaC securityStatic analysis of Infrastructure as Code manifests. For instance, AWS CloudFormation templates or Terraform configurations.
Secret detectionSearch for secrets leaked in the code.
DASTDynamic Application Security Testing. They perform the scan from outside while the application is running in its environment.
Finding collectionThis 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.
ReconChecktypes focused on reconnaissance activities. For instance, port scanning and service discovery.
Data analysisChecktypes focused on processing data sets to extract information considered relevant from an information security point of view.

Enabled by default

ChecktypeDescriptionSecurity Control
vulcan-semgrepFinds potential issues in source code from a Git repository using Semgrep. Official Documentation: https://semgrep.dev/docsSAST
vulcan-trivyScan docker images and Git repositories using aquasec/trivy. Official Documentation: https://aquasecurity.github.io/trivy/latestSCA, IaC security, Secret detection
vulcan-retirejsCheck web pages for vulnerable JavaScript libraries. Official Documentation: https://retirejs.github.io/retire.jsSCA
vulcan-nucleiScan web addresses with projectdiscovery/nuclei. Official Documentation: https://docs.projectdiscovery.io/tools/nucleiDAST
vulcan-zapRuns an OWASP ZAP passive or active scan. Official Documentation: https://www.zaproxy.org/docsDAST

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

ChecktypeDescriptionSecurity Control
vulcan-aws-alertsDetects general issues for an AWS account.DAST
vulcan-aws-trusted-advisorRuns an AWS Trusted Advisor check against an AWS account.DAST
vulcan-blast-radiusCalculates the blast radius of an asset.Data analysis
vulcan-burpRuns a Burp Suite Enterprise Edition scan.DAST
vulcan-dmarcChecks if a domain have valid DNS configuration for DMARC.DAST
vulcan-drupalChecks for some vulnerable versions of Drupal.DAST
vulcan-exposed-bgpChecks for exposed BGP port on Internet routers.DAST
vulcan-exposed-dbChecks if an asset has database well known ports open.DAST
vulcan-exposed-httpChecks if an asset has HTTP well known ports open.Recon
vulcan-exposed-memcachedChecks if the asset contains an exposed Memcached server.DAST
vulcan-exposed-router-portsChecks if an asset has routers well known ports open.DAST
vulcan-exposed-servicesChecks if a host has any open ports by scanning the 1000 most common TCP and UDP ports.Recon
vulcan-exposed-sshChecks SSH server configuration for compliance with Mozilla OpenSSH guidelines.DAST
vulcan-github-alertsRetrieves existing vulnerability alerts for a Github repository.Finding collection
vulcan-gitleaksFinds potential secrets in source code from a Git repository using gitleaks.Secret detection
vulcan-heartbleedChecks if an asset is vulnerable to Heartbleed.DAST
vulcan-host-discoveryPerforms a quick Nmap ping scan that identifies which hosts are up.Recon
vulcan-http-headersAnalyzes the HTTP headers using Mozilla Observatory.DAST
vulcan-ipv6Checks for IPv6 presence.Recon
vulcan-masscanChecks if a host has any open port by scanning the whole TCP port range using masscan.Recon
vulcan-mxChecks for MX DNS Records.Recon
vulcan-nessusRuns a Nessus scan.DAST
vulcan-prowlerRuns Prowler against an AWS account.DAST
vulcan-smtp-open-relayCheck for testing SMTP Open Relay.DAST
vulcan-spfChecks if a domain has a SPF record on DNS.DAST
vulcan-tenableRetrieves findings from assets scanned by Tenable.io.Finding collection
vulcan-vulnersRuns the nmap-script vulners against the target opened ports.DAST
vulcan-wpscanRuns 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.