cage

package module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2025 License: MIT Imports: 9 Imported by: 0

README

cage logo

Go reference Go version Go version License

cage

Installing

To use CAGE, first install the latest version of it using go get.

go get -u github.com/aegis-forge/cage@latest

Then, you can include it in your application as such:

import "github.com/aegis-forge/cage"

Usage

To check if a software package is vulnerable or not, you can use the following working example. In this case, we are checking if the GitHub Action tj-actions/branch-names@v7 is vulnerable or not.

package main

import (
	"encoding/json"
	"log"
	"time"
	
	"github.com/aegis-forge/cage"
)

func main() {
	advisories := cage.Github{}
	sources := []cage.Source{advisories}
	
	semver, err := cage.NewSemver("7")
	
	if err != nil {
		log.Fatal(err)
	}
	
	packg, err := cage.NewPackage("tj-actions", "branch-names", time.Now(), semver)
	
	if err != nil {
		log.Fatal(err)
	}
	
	vulns, err := packg.IsVulnerable(sources)
	
	if err != nil {
		log.Fatal(err)
	}
	
	parsed, err := json.MarshalIndent(vulns, "", "  ")
	
	log.Print(string(parsed))
}

[!NOTE] If you need to check a large number of Actions, you can add your own personal GitHub token. To do so, after initializing cage.Github{}, simply call the SetToken() method on the source and pass it your token

Output

By running the code above, you will get the following JSON-formatted output (as of 2025-08-25 11:38:58):

[
  {
    "id": "GHSA-gq52-6phf-x2r6",
    "cve": "CVE-2025-54416",
    "cwes": [
      "CWE-77"
    ],
    "cvss": 9.1,
    "published": "2025-07-25T19:28:22Z",
    "vulnerable_ranges": [
      {
        "start": "v0.0.0",
        "end": "v8.2.1",
        "left": true,
        "right": true
      }
    ],
    "patched_ranges": [
      {
        "start": "v9.0.0",
        "end": "",
        "left": true,
        "right": false
      }
    ]
  },
  {
    "id": "GHSA-8v8w-v8xg-79rf",
    "cve": "CVE-2023-49291",
    "cwes": [
      "CWE-20"
    ],
    "cvss": 9.3,
    "published": "2023-12-05T23:30:10Z",
    "vulnerable_ranges": [
      {
        "start": "v0.0.0",
        "end": "v7.0.7",
        "left": true,
        "right": false
      }
    ],
    "patched_ranges": [
      {
        "start": "v7.0.7",
        "end": "",
        "left": true,
        "right": false
      }
    ]
  }
]

Extend

CAGE can be extended by adding custom Sources. To do so, the new struct must include the methods included in the Source interface.

type Source interface {
	GetVulnerabilities(Package) ([]Vulnerability, error)
	CompareVulnerabilities([]Vulnerability, Package) ([]Vulnerability, error)
}

In the case of the GetVulnerabilities() method, it will be invoked by the Package in its method Package.IsVulnerable(). Given the name of the package passed, it retrieves all the vulnerabilities for that package from the source's database.

On the other hand, CompareVulnerabilities() is basically a custom rule to compare the Vulnerability objects to the Package.version field. It returns all detected vulnerabilities.

Vulnerability Sources

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Github

type Github struct {
	// contains filtered or unexported fields
}

Github is a source of vulnerabilities (https://github.com/advisories)

func (Github) CompareVulnerabilities

func (g Github) CompareVulnerabilities(vulns []Vulnerability, packg Package) ([]Vulnerability, error)

CompareVulnerabilities checks if the Package version is contained in the vulns slice.

func (Github) GetVulnerabilities

func (g Github) GetVulnerabilities(packg Package) ([]Vulnerability, error)

GetVulnerabilities retrieves all vulnerabilities for the given package version

func (*Github) SetToken

func (g *Github) SetToken(token string) error

SetToken sets the GitHub token and checks if its valid

type Package

type Package struct {
	// contains filtered or unexported fields
}

Package describes a specific version of a software package

func NewPackage

func NewPackage(vendor, product string, published time.Time, version Semver) (*Package, error)

NewPackage creates a new Package or returns an error if it is invalid

func (*Package) IsVulnerable

func (p *Package) IsVulnerable(sources []Source) ([]Vulnerability, error)

IsVulnerable checks if a package is vulnerable by checking the passed sources. If `nil` is passed as sources, Github will be used. If the package is vulnerable, then it will return a slice of Vulnerability structs.

type Semver

type Semver string

Semver is a type definition for a version that follows semantic versioning

func NewSemver

func NewSemver(version string) (Semver, error)

NewSemver creates a new Semver and checks if it's valid

func (Semver) After

func (s Semver) After(sv Semver) bool

Before checks if the passed Semver is bigger than the original Semver

func (Semver) Before

func (s Semver) Before(sv Semver) bool

Before checks if the passed Semver is smaller than the original Semver

func (Semver) Equals

func (s Semver) Equals(sv Semver) bool

Equals checks if the passed Semver is equal to the original Semver

func (Semver) IsValid

func (s Semver) IsValid() bool

IsValid checks if the Semver is valid

type Source

type Source interface {
	GetVulnerabilities(Package) ([]Vulnerability, error)
	CompareVulnerabilities([]Vulnerability, Package) ([]Vulnerability, error)
}

Source is an interface that describes the source of vulnerabilities

type VersionRange

type VersionRange struct {
	Start        Semver `json:"start"`
	End          Semver `json:"end"`
	IncludeLeft  bool   `json:"left"`
	IncludeRight bool   `json:"right"`
}

VersionRange is used to store ranges of versions. If `start` is empty, the range will be `< end`. If `end` is empty, then it means `== start`.

func NewVersionRange

func NewVersionRange(start, end Semver, left, right bool) (*VersionRange, error)

NewVersionRange creates a new [VersionRanges] and checks if it's valid

func NewVersionRangeString

func NewVersionRangeString(stringRange string) (*VersionRange, error)

NewVersionRangeString creates a range given a range string (e.g. `>= v1.0`)

func (*VersionRange) Contains

func (v *VersionRange) Contains(s Semver) bool

Contains checks if a Semver is contained in a VersionRange struct

func (*VersionRange) Equals

func (v *VersionRange) Equals(vr VersionRange) bool

Equals checks if two VersionRange are equal (i.e. same start and end)

type Vulnerability

type Vulnerability struct {
	Id               string         `json:"id"`
	Cve              string         `json:"cve"`
	Cwes             []string       `json:"cwes"`
	Cvss             float32        `json:"cvss"`
	Published        time.Time      `json:"published"`
	RangesVulnerable []VersionRange `json:"vulnerable_ranges"`
	RangesPatched    []VersionRange `json:"patched_ranges"`
}

Vulnerability represents a vulnerability of a software package

func NewVulnerability

func NewVulnerability(id, cve string, cwes []string, cvss float32,
	published string, rangesVulnerable, rangesPatched []VersionRange,
	timeFormat string) (*Vulnerability, error)

NewVulnerability creates a Vulnerability struct. If `timeFormat` is an empty string, then the default `2006-01-02 15:04:05 -0700` format is used.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL