feat: control-driven SAST — LUT + grounded LLM triage over tool findings #213
@@ -82,10 +82,7 @@ impl Scanner for SemgrepScanner {
|
|||||||
finding.file_path = Some(r.path);
|
finding.file_path = Some(r.path);
|
||||||
finding.line_number = Some(r.start.line);
|
finding.line_number = Some(r.start.line);
|
||||||
finding.code_snippet = Some(r.extra.lines);
|
finding.code_snippet = Some(r.extra.lines);
|
||||||
finding.cwe = r
|
finding.cwe = r.extra.metadata.as_ref().and_then(extract_cwe);
|
||||||
.extra
|
|
||||||
.metadata
|
|
||||||
.and_then(|m| m.get("cwe").and_then(|v| v.as_str()).map(|s| s.to_string()));
|
|
||||||
finding
|
finding
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@@ -124,10 +121,34 @@ struct SemgrepExtra {
|
|||||||
metadata: Option<serde_json::Value>,
|
metadata: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// semgrep emits `metadata.cwe` as a list of strings like
|
||||||
|
/// `"CWE-798: Use of Hard-coded Credentials"` (occasionally a bare string). Take
|
||||||
|
/// the first entry and normalise it to just the `CWE-NNN` id.
|
||||||
|
fn extract_cwe(metadata: &serde_json::Value) -> Option<String> {
|
||||||
|
let raw = metadata.get("cwe")?;
|
||||||
|
let text = match raw {
|
||||||
|
serde_json::Value::Array(items) => items.first()?.as_str()?,
|
||||||
|
serde_json::Value::String(s) => s.as_str(),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
let id = text.split(':').next().unwrap_or(text).trim();
|
||||||
|
(!id.is_empty()).then(|| id.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_cwe_handles_list_and_normalises() {
|
||||||
|
let md = serde_json::json!({"cwe": ["CWE-798: Use of Hard-coded Credentials"]});
|
||||||
|
assert_eq!(extract_cwe(&md).as_deref(), Some("CWE-798"));
|
||||||
|
let bare = serde_json::json!({"cwe": "CWE-89"});
|
||||||
|
assert_eq!(extract_cwe(&bare).as_deref(), Some("CWE-89"));
|
||||||
|
let none = serde_json::json!({"severity": "ERROR"});
|
||||||
|
assert_eq!(extract_cwe(&none), None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialize_semgrep_output() {
|
fn deserialize_semgrep_output() {
|
||||||
let json = r#"{
|
let json = r#"{
|
||||||
|
|||||||
Reference in New Issue
Block a user