Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ let advisories = manager.query_ossindex(&purls).await?;

## Filtering Options

Filter vulnerabilities by severity, EPSS score, or KEV status:
Filter vulnerabilities by severity, EPSS score, KEV status, or CWE IDs:

```rust
use vulnera_advisors::{MatchOptions, Severity};
Expand All @@ -114,18 +114,45 @@ let options = MatchOptions::high_severity();
// Only actively exploited (KEV)
let options = MatchOptions::exploited_only();

// Custom filters
// Filter by CWE IDs (e.g., XSS vulnerabilities)
let options = MatchOptions::with_cwes(vec!["CWE-79".to_string()]);

// Filter by multiple CWEs (injection vulnerabilities)
let options = MatchOptions::with_cwes(vec![
"CWE-79".to_string(), // XSS
"CWE-89".to_string(), // SQL Injection
"CWE-78".to_string(), // OS Command Injection
]);

// Custom filters with CWE
let options = MatchOptions {
min_cvss: Some(7.0),
min_epss: Some(0.5),
kev_only: false,
min_severity: Some(Severity::Medium),
cwe_ids: Some(vec!["CWE-79".to_string(), "CWE-89".to_string()]),
include_enrichment: true,
};

let vulns = manager.matches_with_options("npm", "lodash", "4.17.20", &options).await?;
```

### CWE Filtering

Filter advisories by Common Weakness Enumeration (CWE) identifiers:

| Use Case | CWE IDs |
| -------------------- | --------- |
| Cross-Site Scripting | `CWE-79` |
| SQL Injection | `CWE-89` |
| OS Command Injection | `CWE-78` |
| Path Traversal | `CWE-22` |
| Deserialization | `CWE-502` |
| SSRF | `CWE-918` |

CWE IDs are automatically normalized - all formats work:
- `"CWE-79"`, `"cwe-79"`, `"79"` all match the same CWE

## Remediation Suggestions

Get safe version recommendations when vulnerabilities are detected:
Expand Down Expand Up @@ -168,11 +195,11 @@ let remediation = manager

### Upgrade Impact Classification

| Impact | Description |
|--------|-------------|
| `patch` | Bug fix only (x.y.Z) |
| Impact | Description |
| ------- | ----------------------------------------- |
| `patch` | Bug fix only (x.y.Z) |
| `minor` | New features, backward compatible (x.Y.z) |
| `major` | Breaking changes (X.y.z) |
| `major` | Breaking changes (X.y.z) |

## Environment Variables

Expand Down
68 changes: 68 additions & 0 deletions examples/test_cwe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! Example: Test CWE filtering functionality
//!
//! Run with: cargo run --example test_cwe

use vulnera_advisor::{MatchOptions, Severity};

fn main() {
println!("=== CWE Filtering Test ===\n");

// Test 1: Default options (no CWE filter)
let default_opts = MatchOptions::default();
println!("1. Default options:");
println!(" cwe_ids: {:?}", default_opts.cwe_ids);
println!(" kev_only: {}", default_opts.kev_only);
println!();

// Test 2: Filter for XSS vulnerabilities (CWE-79)
let xss_opts = MatchOptions::with_cwes(vec!["CWE-79".to_string()]);
println!("2. XSS filter (CWE-79):");
println!(" cwe_ids: {:?}", xss_opts.cwe_ids);
println!(" include_enrichment: {}", xss_opts.include_enrichment);
println!();

// Test 3: Filter for multiple injection vulnerabilities
let injection_opts = MatchOptions::with_cwes(vec![
"CWE-79".to_string(), // XSS
"CWE-89".to_string(), // SQL Injection
"CWE-78".to_string(), // OS Command Injection
]);
println!("3. Injection filter (CWE-79, CWE-89, CWE-78):");
println!(" cwe_ids: {:?}", injection_opts.cwe_ids);
println!();

// Test 4: Combined filters (CWE + Severity + KEV)
let critical_xss = MatchOptions {
cwe_ids: Some(vec!["CWE-79".to_string()]),
min_severity: Some(Severity::High),
kev_only: true,
include_enrichment: true,
..Default::default()
};
println!("4. Critical XSS (High severity + KEV):");
println!(" cwe_ids: {:?}", critical_xss.cwe_ids);
println!(" min_severity: {:?}", critical_xss.min_severity);
println!(" kev_only: {}", critical_xss.kev_only);
println!();

// Test 5: OWASP Top 10 related CWEs
let owasp_top10 = MatchOptions::with_cwes(vec![
"CWE-79".to_string(), // A03: Injection (XSS)
"CWE-89".to_string(), // A03: Injection (SQLi)
"CWE-287".to_string(), // A07: Identification and Authentication Failures
"CWE-352".to_string(), // A01: Broken Access Control (CSRF)
"CWE-611".to_string(), // A05: Security Misconfiguration (XXE)
"CWE-502".to_string(), // A08: Software and Data Integrity Failures
]);
println!("5. OWASP Top 10 related CWEs:");
println!(" cwe_ids: {:?}", owasp_top10.cwe_ids);
println!();

println!("=== All tests completed ===");
println!("\nTo use with VulnerabilityManager:");
println!(" let manager = VulnerabilityManager::new(config).await?;");
println!(" let options = MatchOptions::with_cwes(vec![\"CWE-79\".to_string()]);");
println!(
" let xss_vulns = manager.matches_with_options(\"npm\", \"pkg\", \"1.0.0\", &options).await?;"
);
}
96 changes: 87 additions & 9 deletions scripts/test.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,78 @@ echo ""
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

FAILED=0
SKIPPED=0

# Parse arguments
VERBOSE=false
SKIP_OPTIONAL=false
while [[ "$#" -gt 0 ]]; do
case $1 in
-v|--verbose) VERBOSE=true ;;
--skip-optional) SKIP_OPTIONAL=true ;;
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -v, --verbose Show full output for each test"
echo " --skip-optional Skip optional checks (audit, machete)"
echo " -h, --help Show this help message"
exit 0
;;
*) echo "Unknown parameter: $1"; exit 1 ;;
esac
shift
done

# Function to run a test
run_test() {
local name=$1
local cmd=$2

echo -n "▶ $name ... "
if eval "$cmd" > /dev/null 2>&1; then
echo -e "${GREEN}✓${NC}"
if $VERBOSE; then
echo ""
if eval "$cmd"; then
echo -e "${GREEN}✓ Passed${NC}"
else
echo -e "${RED}✗ Failed${NC}"
FAILED=$((FAILED + 1))
fi
else
echo -e "${RED}✗${NC}"
FAILED=$((FAILED + 1))
if eval "$cmd" > /dev/null 2>&1; then
echo -e "${GREEN}✓${NC}"
else
echo -e "${RED}✗${NC}"
FAILED=$((FAILED + 1))
fi
fi
}

# Function to run an optional test (skips if tool not found)
run_optional_test() {
local name=$1
local tool=$2
local cmd=$3

if $SKIP_OPTIONAL; then
echo -e "▶ $name ... ${YELLOW}skipped${NC}"
SKIPPED=$((SKIPPED + 1))
return
fi

if ! command -v "$tool" &> /dev/null; then
echo -e "▶ $name ... ${YELLOW}skipped (${tool} not installed)${NC}"
SKIPPED=$((SKIPPED + 1))
return
fi

run_test "$name" "$cmd"
}

# Function to run a test with output
run_test_verbose() {
local name=$1
Expand All @@ -44,6 +98,8 @@ run_test_verbose() {
fi
}

echo -e "${BLUE}=== Core Checks ===${NC}"

# Check formatting
run_test "Formatting (cargo fmt)" "cargo fmt -- --check"

Expand All @@ -53,32 +109,54 @@ run_test "Linting (cargo clippy)" "cargo clippy --all-targets --all-features --
# Check for common mistakes
run_test "Cargo check" "cargo check --all-targets --all-features"

echo ""
echo -e "${BLUE}=== Tests ===${NC}"

# Unit tests
run_test "Unit tests" "cargo test --lib"

# Doc tests
run_test "Doc tests" "cargo test --doc"

# CWE filtering tests (matches all tests with 'cwe' in name)
run_test "CWE filtering tests" "cargo test --lib cwe"

echo ""
echo -e "${BLUE}=== Documentation ===${NC}"

# Build documentation
run_test "Documentation" "cargo doc --no-deps --all-features"

# Security audit
run_test "Security audit" "cargo audit"
echo ""
echo -e "${BLUE}=== Optional Checks ===${NC}"

# Check for deprecated dependencies
run_test "Check for unused dependencies" "cargo machete"
# Security audit (optional - requires cargo-audit)
run_optional_test "Security audit" "cargo-audit" "cargo audit"

# Check for unused dependencies (optional - requires cargo-machete)
run_optional_test "Unused dependencies" "cargo-machete" "cargo machete"

# Check for outdated dependencies (optional - requires cargo-outdated)
run_optional_test "Outdated dependencies" "cargo-outdated" "cargo outdated --exit-code 1"

echo ""
echo "======================================"
if [ $FAILED -eq 0 ]; then
echo -e "${GREEN}✓ All tests passed!${NC}"
if [ $SKIPPED -gt 0 ]; then
echo -e "${GREEN}✓ All tests passed!${NC} (${YELLOW}$SKIPPED skipped${NC})"
else
echo -e "${GREEN}✓ All tests passed!${NC}"
fi
echo ""
echo "You can now:"
echo " • Run 'cargo publish --dry-run' to test publishing"
echo " • Commit and push your changes"
exit 0
else
echo -e "${RED}✗ $FAILED test(s) failed${NC}"
if [ $SKIPPED -gt 0 ]; then
echo -e "${YELLOW} $SKIPPED test(s) skipped${NC}"
fi
echo ""
echo "Please fix the issues above before committing."
exit 1
Expand Down
Loading