euvd

package module
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2025 License: MIT Imports: 10 Imported by: 0

README

go-euvd

Go Reference Go Report Card

A comprehensive Go client library for the ENISA EU Vulnerability Database (EUVD) API, providing access to vulnerability data, security advisories, and threat intelligence.

[!IMPORTANT] Implementation Notes & API Behavior

  • Opinionated Data Handling: This library takes a pragmatic approach to data returned by the remote API. For example, some fields are returned as single strings with embedded \n newlines. The library automatically parses these into Go string slices, providing a more idiomatic and convenient interface for consumers.

  • Remote Search API Limitations: While this library fully implements the official EUVD API specification, it has been observed that the remote search functionality has issues. Certain query parameter combinations (e.g., using vendor together with toScore or fromScore) may result in some parameters being ignored or omitted by the remote service. This is a limitation of the upstream API, not the client library.

In case the mentioned shortcomings are implementation related, feel free to open an issue.


Data Source

The ENISA EU Vulnerability Database serves as the European Union's central repository. Api documentation is provided via Official API Documentation. API offers:

  • Real-time vulnerability data from multiple sources
  • Security advisories from vendors and security organizations
  • CVSS scores and exploitability metrics (EPSS)
  • Product and vendor mappings for affected systems
  • Exploitation status and timeline information

Key Features

  • Complete API Coverage - All EUVD endpoints supported
  • High Performance - Optimized HTTP client with connection pooling
  • 🔧 Flexible Configuration - Custom timeouts, loggers, and HTTP clients
  • 🪶 Zero External Dependencies - Maximum portability, following standard library and best Go practices

Getting Started

Installation
go get github.com/kaansk/go-euvd
Basic Usage
package main

import (
    "context"
    "fmt"
    "log"
    
    "github.com/kaansk/go-euvd"
)

func main() {
    // Create a client with default configuration
    client := euvd.NewClient()

    // Create a customized client
    logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
        Level: slog.LevelInfo,
    }))

    httpClient := &http.Client{
        Timeout: 60 * time.Second,
        Transport: &http.Transport{
            MaxIdleConns:        10,
            IdleConnTimeout:     30 * time.Second,
        },
    }

    client := euvd.NewClient(
        euvd.WithBaseURL("https://custom-euvd-api.com/api"),
        euvd.WithTimeout(45 * time.Second),
        euvd.WithLogger(logger),
        euvd.WithHTTPClient(httpClient),
    )    
    
    ctx := context.Background()
    
    // Get latest critical vulnerabilities
    vulnerabilities, err := client.GetLatestCriticalVulnerabilities(ctx)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Found %d critical vulnerabilities\n", len(vulnerabilities))
    for _, vuln := range vulnerabilities {
        fmt.Printf("- %s (Score: %.1f)\n", vuln.ID, vuln.BaseScore)
    }
}

API Endpoints

See the examples/ directory for up-to-date usage and endpoint coverage.


Devcontainer

A ready-to-use devcontainer is provided for rapid onboarding and consistent development environments. It includes:

  • Latest stable Go (fetched from official releases)
  • All recommended Go tools (gopls, golangci-lint, goimports, staticcheck, delve)
  • Non-root user
  • Minimal, reproducible setup based on Debian/Ubuntu

Documentation

Index

Constants

View Source
const (
	// API endpoints
	EndpointCritical  = "/criticalvulnerabilities"
	EndpointExploited = "/exploitedvulnerabilities"
	EndpointLatest    = "/lastvulnerabilities"
	EndpointSearch    = "/search"
	EndpointLookup    = "/enisaid"
	EndpointAdvisory  = "/advisory"

	// HTTP headers
	HeaderAccept    = "Accept"
	HeaderUserAgent = "User-Agent"

	// Default values
	DefaultBaseURL = "https://euvdservices.enisa.europa.eu/api"
	DefaultTimeout = 30 * time.Second
	UserAgentValue = "go-euvd/2.0"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	StatusCode int    `json:"statusCode"`
	Message    any    `json:"message"`
	Endpoint   string `json:"endpoint,omitempty"`
}

func NewAPIError

func NewAPIError(resp *http.Response) *APIError

func (*APIError) Error

func (e *APIError) Error() string

type Advisory

type Advisory struct {
	ID                    string                  `json:"id"`
	Description           string                  `json:"description"`
	Summary               string                  `json:"summary"`
	DatePublished         *time.Time              `json:"datePublished,omitempty"`
	DateUpdated           *time.Time              `json:"dateUpdated,omitempty"`
	BaseScore             float64                 `json:"baseScore"`
	References            []string                `json:"references"`
	Aliases               []string                `json:"aliases"`
	Source                *Source                 `json:"source,omitempty"`
	AdvisoryProduct       []AdvisoryProduct       `json:"advisoryProduct"`
	EnisaIdAdvisories     []EnisaIdAdvisory       `json:"enisaIdAdvisories"`
	VulnerabilityAdvisory []VulnerabilityAdvisory `json:"vulnerabilityAdvisory"`
}

Advisory represents a security advisory

func (*Advisory) UnmarshalJSON

func (a *Advisory) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom JSON unmarshaling for Advisory

type AdvisoryEuvd

type AdvisoryEuvd struct {
	ID               string          `json:"id"`
	Description      string          `json:"description"`
	DatePublished    *time.Time      `json:"datePublished,omitempty"`
	DateUpdated      *time.Time      `json:"dateUpdated,omitempty"`
	BaseScore        float64         `json:"baseScore"`
	BaseScoreVersion string          `json:"baseScoreVersion"`
	BaseScoreVector  string          `json:"baseScoreVector"`
	References       []string        `json:"references"`
	Aliases          []string        `json:"aliases"`
	Assigner         string          `json:"assigner"`
	EPSS             float64         `json:"epss"`
	EnisaIdVendor    []EnisaIdVendor `json:"enisaIdVendor"`
}

AdvisoryEuvd represents EUVD information within an advisory

func (*AdvisoryEuvd) UnmarshalJSON

func (ae *AdvisoryEuvd) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom JSON unmarshaling for AdvisoryEuvd

type AdvisoryEuvdRaw

type AdvisoryEuvdRaw struct {
	ID               string          `json:"id"`
	Description      string          `json:"description"`
	DatePublished    string          `json:"datePublished"`
	DateUpdated      string          `json:"dateUpdated"`
	BaseScore        float64         `json:"baseScore"`
	BaseScoreVersion string          `json:"baseScoreVersion"`
	BaseScoreVector  string          `json:"baseScoreVector"`
	References       string          `json:"references"`
	Aliases          string          `json:"aliases"`
	Assigner         string          `json:"assigner"`
	EPSS             float64         `json:"epss"`
	EnisaIdVendor    []EnisaIdVendor `json:"enisaIdVendor"`
}

type AdvisoryProduct

type AdvisoryProduct struct {
	ID      string  `json:"id"`
	Product Product `json:"product"`
}

AdvisoryProduct represents a product associated with an advisory

type AdvisoryRaw

type AdvisoryRaw struct {
	ID                    string                  `json:"id"`
	Description           string                  `json:"description"`
	Summary               string                  `json:"summary"`
	DatePublished         string                  `json:"datePublished"`
	DateUpdated           string                  `json:"dateUpdated"`
	BaseScore             float64                 `json:"baseScore"`
	References            string                  `json:"references"`
	Aliases               string                  `json:"aliases"`
	Source                *Source                 `json:"source,omitempty"`
	AdvisoryProduct       []AdvisoryProduct       `json:"advisoryProduct"`
	EnisaIdAdvisories     []EnisaIdAdvisory       `json:"enisaIdAdvisories"`
	VulnerabilityAdvisory []VulnerabilityAdvisory `json:"vulnerabilityAdvisory"`
}

type AdvisoryVulnerability

type AdvisoryVulnerability struct {
	ID                  string                `json:"id"`
	Description         string                `json:"description"`
	DatePublished       *time.Time            `json:"datePublished,omitempty"`
	DateUpdated         *time.Time            `json:"dateUpdated,omitempty"`
	Status              string                `json:"status"`
	BaseScore           float64               `json:"baseScore"`
	BaseScoreVersion    string                `json:"baseScoreVersion"`
	BaseScoreVector     string                `json:"baseScoreVector"`
	References          []string              `json:"references"`
	EnisaId             []string              `json:"enisa_id"`
	Assigner            string                `json:"assigner"`
	EPSS                float64               `json:"epss"`
	VulnerabilityVendor []VulnerabilityVendor `json:"vulnerabilityVendor"`
}

AdvisoryVulnerability represents vulnerability details within an advisory

func (*AdvisoryVulnerability) UnmarshalJSON

func (av *AdvisoryVulnerability) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom JSON unmarshaling for AdvisoryVulnerability

type AdvisoryVulnerabilityRaw

type AdvisoryVulnerabilityRaw struct {
	ID                  string                `json:"id"`
	Description         string                `json:"description"`
	DatePublished       string                `json:"datePublished"`
	DateUpdated         string                `json:"dateUpdated"`
	Status              string                `json:"status"`
	BaseScore           float64               `json:"baseScore"`
	BaseScoreVersion    string                `json:"baseScoreVersion"`
	BaseScoreVector     string                `json:"baseScoreVector"`
	References          string                `json:"references"`
	EnisaId             string                `json:"enisa_id"`
	Assigner            string                `json:"assigner"`
	EPSS                float64               `json:"epss"`
	VulnerabilityVendor []VulnerabilityVendor `json:"vulnerabilityVendor"`
}

type Client

type Client struct {
	BaseURL    string        `json:"baseURL"`
	Timeout    time.Duration `json:"timeout"`
	HTTPClient *http.Client  `json:"-"` // Not serializable
	Logger     *slog.Logger  `json:"-"` // Not serializable
	UserAgent  string        `json:"userAgent"`
}

Client represents the EUVD API client

func NewClient

func NewClient(opts ...ClientOption) *Client

NewClient creates a new EUVD client with optional configuration

func (*Client) GetAdvisoryByID

func (c *Client) GetAdvisoryByID(ctx context.Context, id string) (*Advisory, error)

GetAdvisoryByID retrieves a specific advisory by its ID

func (*Client) GetLatestCriticalVulnerabilities

func (c *Client) GetLatestCriticalVulnerabilities(ctx context.Context) ([]Vulnerability, error)

GetLatestCriticalVulnerabilities retrieves the latest vulnerabilities with high severity scores (max 8 records)

func (*Client) GetLatestExploitedVulnerabilities

func (c *Client) GetLatestExploitedVulnerabilities(ctx context.Context) ([]Vulnerability, error)

GetLatestExploitedVulnerabilities retrieves the latest vulnerabilities that are currently being exploited (max 8 records)

func (*Client) GetLatestVulnerabilities

func (c *Client) GetLatestVulnerabilities(ctx context.Context) ([]Vulnerability, error)

GetLatestVulnerabilities retrieves the most recently published vulnerabilities

func (*Client) LookupByID

func (c *Client) LookupByID(ctx context.Context, id string) (*Vulnerability, error)

LookupByID retrieves a specific vulnerability by its EUVD identifier

func (*Client) SearchVulnerabilities

func (c *Client) SearchVulnerabilities(ctx context.Context, opts *SearchOptions) ([]Vulnerability, error)

SearchVulnerabilities performs a filtered search for vulnerabilities Only integer values are allowed for fromScore and toScore (ENISA API quirk). Query parameters are encoded in the standard way.

type ClientOption

type ClientOption func(*Client)

ClientOption is a function type for configuring the EUVD client

func WithBaseURL

func WithBaseURL(baseURL string) ClientOption

WithBaseURL sets a custom base URL for the EUVD API

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) ClientOption

WithHTTPClient sets a custom HTTP client

func WithLogger

func WithLogger(logger *slog.Logger) ClientOption

WithLogger sets a custom logger

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout sets the request timeout

func WithUserAgent

func WithUserAgent(userAgent string) ClientOption

WithUserAgent sets a custom User-Agent header

type EnisaIdAdvisory

type EnisaIdAdvisory struct {
	ID      string       `json:"id"`
	EnisaId AdvisoryEuvd `json:"enisaId"`
}

EnisaIdAdvisory represents ENISA ID information within an advisory

type EnisaIdProduct

type EnisaIdProduct struct {
	ID             string  `json:"id"`
	Product        Product `json:"product"`
	ProductVersion string  `json:"product_version"`
}

type EnisaIdVendor

type EnisaIdVendor struct {
	ID     string `json:"id"`
	Vendor Vendor `json:"vendor"`
}

type EnisaIdVulnerability

type EnisaIdVulnerability struct {
	ID            string           `json:"id"`
	Vulnerability VulnerabilityRef `json:"vulnerability"`
}

type Product

type Product struct {
	Name string `json:"name"`
}

type SearchOptions

type SearchOptions struct {
	// Search parameters
	Assigner string `json:"assigner,omitempty"`
	Product  string `json:"product,omitempty"`
	Vendor   string `json:"vendor,omitempty"`
	Text     string `json:"text,omitempty"`

	// Date range
	FromDate time.Time `json:"fromDate,omitempty"`
	ToDate   time.Time `json:"toDate,omitempty"`

	// Score range (0-10)
	FromScore int `json:"fromScore,omitempty"`
	ToScore   int `json:"toScore,omitempty"`

	// EPSS range (0-100)
	FromEPSS int `json:"fromEPSS,omitempty"`
	ToEPSS   int `json:"toEPSS,omitempty"`

	// Exploitation status - use Bool(true) or Bool(false)
	Exploited bool `json:"-"`

	// Pagination
	Page int `json:"page,omitempty"`
	Size int `json:"size,omitempty"`
}

type SearchResponse

type SearchResponse struct {
	Items []Vulnerability `json:"items"`
	Total int             `json:"total"`
}

SearchResponse represents the response from the search endpoint

type Source

type Source struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

Source represents the source of an advisory

type Vendor

type Vendor struct {
	Name string `json:"name"`
}

type Vulnerability

type Vulnerability struct {
	ID                   string                 `json:"id"`
	Description          string                 `json:"description,omitempty"`
	DatePublished        *time.Time             `json:"datePublished,omitempty"`
	DateUpdated          *time.Time             `json:"dateUpdated,omitempty"`
	BaseScore            float64                `json:"baseScore,omitempty"`
	BaseScoreVersion     string                 `json:"baseScoreVersion,omitempty"`
	BaseScoreVector      string                 `json:"baseScoreVector,omitempty"`
	References           []string               `json:"references,omitempty"`
	Aliases              []string               `json:"aliases,omitempty"`
	Assigner             string                 `json:"assigner,omitempty"`
	EPSS                 float64                `json:"epss,omitempty"`
	ExploitedSince       *time.Time             `json:"exploitedSince,omitempty"`
	EnisaIdProduct       []EnisaIdProduct       `json:"enisaIdProduct,omitempty"`
	EnisaIdVendor        []EnisaIdVendor        `json:"enisaIdVendor,omitempty"`
	EnisaIdVulnerability []EnisaIdVulnerability `json:"enisaIdVulnerability,omitempty"`
	EnisaIdAdvisory      []EnisaIdAdvisory      `json:"enisaIdAdvisory,omitempty"`
}

Vulnerability represents a vulnerability record from the EUVD API

func (*Vulnerability) IsExploited

func (v *Vulnerability) IsExploited() bool

IsExploited returns true if the vulnerability is currently being exploited

func (*Vulnerability) UnmarshalJSON

func (v *Vulnerability) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom unmarshaling to convert newline-delimited strings to arrays

type VulnerabilityAdvisory

type VulnerabilityAdvisory struct {
	ID            string                `json:"id"`
	Vulnerability AdvisoryVulnerability `json:"vulnerability"`
}

VulnerabilityAdvisory represents vulnerability information within an advisory

type VulnerabilityProduct

type VulnerabilityProduct struct {
	ID             string  `json:"id"`
	Product        Product `json:"product"`
	ProductVersion string  `json:"product_version"`
}

type VulnerabilityRef

type VulnerabilityRef struct {
	ID                   string                 `json:"id"`
	Description          string                 `json:"description,omitempty"`
	DatePublished        string                 `json:"datePublished,omitempty"`
	DateUpdated          string                 `json:"dateUpdated,omitempty"`
	Status               string                 `json:"status,omitempty"`
	BaseScore            float64                `json:"baseScore,omitempty"`
	BaseScoreVersion     string                 `json:"baseScoreVersion,omitempty"`
	BaseScoreVector      string                 `json:"baseScoreVector,omitempty"`
	References           string                 `json:"references,omitempty"`
	EnisaID              string                 `json:"enisa_id,omitempty"`
	Assigner             string                 `json:"assigner,omitempty"`
	EPSS                 float64                `json:"epss,omitempty"`
	ExploitedSince       string                 `json:"exploitedSince,omitempty"`
	VulnerabilityProduct []VulnerabilityProduct `json:"vulnerabilityProduct,omitempty"`
	VulnerabilityVendor  []VulnerabilityVendor  `json:"vulnerabilityVendor,omitempty"`
}

type VulnerabilityVendor

type VulnerabilityVendor struct {
	ID     string `json:"id"`
	Vendor Vendor `json:"vendor"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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