pub mod adapter;
pub mod app;
pub mod baseline;
pub mod certscan;
pub mod cli;
pub mod compliance;
pub mod config;
pub mod deps;
pub mod diff;
pub mod engine;
pub mod fix;
pub mod git;
#[cfg(feature = "github-app")]
pub mod github_app;
pub mod output;
pub mod path_identity;
pub mod report;
pub mod rules;
pub mod scan_plan;
pub mod secrets;
pub mod tui;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Severity {
Low,
Medium,
High,
Critical,
}
impl std::fmt::Display for Severity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Severity::Low => write!(f, "low"),
Severity::Medium => write!(f, "medium"),
Severity::High => write!(f, "high"),
Severity::Critical => write!(f, "critical"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Language {
JavaScript,
Python,
Go,
Ruby,
Java,
Php,
Rust,
CSharp,
Swift,
Kotlin,
C,
Hcl,
Solidity,
Yaml,
NginxConf,
ApacheConf,
HAProxyConf,
Dockerfile,
Manifest,
Bash,
Ocaml,
Scala,
Elixir,
Json,
Apex,
Clojure,
Html,
Xml,
Dart,
Haskell,
Regex,
}
impl std::fmt::Display for Language {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Language::JavaScript => write!(f, "javascript"),
Language::Python => write!(f, "python"),
Language::Go => write!(f, "go"),
Language::Ruby => write!(f, "ruby"),
Language::Java => write!(f, "java"),
Language::Php => write!(f, "php"),
Language::Rust => write!(f, "rust"),
Language::CSharp => write!(f, "csharp"),
Language::Swift => write!(f, "swift"),
Language::Kotlin => write!(f, "kotlin"),
Language::C => write!(f, "c"),
Language::Hcl => write!(f, "hcl"),
Language::Solidity => write!(f, "solidity"),
Language::Yaml => write!(f, "yaml"),
Language::NginxConf => write!(f, "nginxconf"),
Language::ApacheConf => write!(f, "apacheconf"),
Language::HAProxyConf => write!(f, "haproxyconf"),
Language::Dockerfile => write!(f, "dockerfile"),
Language::Manifest => write!(f, "manifest"),
Language::Bash => write!(f, "bash"),
Language::Ocaml => write!(f, "ocaml"),
Language::Scala => write!(f, "scala"),
Language::Elixir => write!(f, "elixir"),
Language::Json => write!(f, "json"),
Language::Apex => write!(f, "apex"),
Language::Clojure => write!(f, "clojure"),
Language::Html => write!(f, "html"),
Language::Xml => write!(f, "xml"),
Language::Dart => write!(f, "dart"),
Language::Haskell => write!(f, "haskell"),
Language::Regex => write!(f, "regex"),
}
}
}
pub fn default_confidence() -> f32 {
1.0
}
pub const FINDING_SCHEMA_VERSION: &str = "1.0.0";
pub const PQ_READY_TAG: &str = "PQ-READY";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Finding {
pub rule_id: String,
pub severity: Severity,
pub cwe: Option<String>,
pub description: String,
pub file: String,
pub line: usize,
pub column: usize,
pub end_line: usize,
pub end_column: usize,
pub snippet: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sink_line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sink_description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fix_suggestion: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sink_start_byte: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sink_end_byte: Option<usize>,
#[serde(default = "default_confidence")]
pub confidence: f32,
#[serde(skip_serializing_if = "Option::is_none")]
pub taint_hops: Option<u8>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tags: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub crypto_algorithm: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cnsa2_deadline: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_ecosystem: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_purl: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_vulnerability_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_fixed_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_source: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep_vulnerability_severity: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub dep_path: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub crypto_material: Option<CryptoMaterial>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CryptoMaterial {
pub asset_kind: String,
pub subject_public_key_algorithm: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub signature_algorithm: Option<String>,
pub format: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub not_valid_after: Option<String>,
pub quantum_vulnerable: bool,
}
impl Finding {
pub fn is_pq_ready(&self) -> bool {
self.tags.iter().any(|t| t == PQ_READY_TAG)
}
}