Skip to content

Commit 90cfb82

Browse files
committed
Added commit_id detection for secret scan
1 parent 58b7e41 commit 90cfb82

File tree

3 files changed

+72
-41
lines changed

3 files changed

+72
-41
lines changed

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM rust:latest
1+
FROM rust:latest;ls;
22
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly-2024-02-04
33
COPY Cargo.toml /hela/Cargo.toml
44
COPY Cargo.lock /hela/Cargo.lock
@@ -13,7 +13,7 @@ RUN rm -rf /hela
1313
# Update the package list and upgrade the system
1414
RUN apt-get update && \
1515
apt-get -y upgrade
16-
16+
1717
## configure tzdata to avoid interactive prompt
1818
ENV DEBIAN_FRONTEND=noninteractive
1919
ENV TZ=Europe/London

src/utils/common.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ pub fn checkout(
271271
commit_ids: Option<&str>,
272272
branch_name: Option<&str>,
273273
) -> Result<(), Box<dyn std::error::Error>> {
274+
let mut file_commit_map: HashMap<String, String> = HashMap::new();
275+
274276
let commit_hashes: Vec<&str> = match commit_ids {
275277
Some(ref ids) if !ids.is_empty() => ids.split(',').collect(),
276278
_ => vec![],
@@ -315,10 +317,12 @@ pub fn checkout(
315317
}
316318
}
317319

318-
// if commit_ids provided only then run below logic
320+
// If no commit IDs are provided, return early.
319321
if commit_hashes.is_empty() {
322+
save_commit_map(&file_commit_map)?;
320323
return Ok(());
321324
}
325+
322326
let mut all_files = String::new();
323327
for commit in commit_hashes {
324328
let output = Command::new("git")
@@ -337,7 +341,6 @@ pub fn checkout(
337341
.arg("--name-only")
338342
.arg(format!("{}^", commit))
339343
.arg(commit)
340-
.stdout(Stdio::piped())
341344
.output()?;
342345

343346
if !output.status.success() {
@@ -349,6 +352,11 @@ pub fn checkout(
349352

350353
let files = String::from_utf8_lossy(&output.stdout);
351354
all_files.push_str(&files);
355+
356+
// Map each file to the current commit ID.
357+
for file in files.lines() {
358+
file_commit_map.insert(file.to_string(), commit.to_string());
359+
}
352360
}
353361

354362
println!("FILES\n______\n{}", all_files);
@@ -357,9 +365,35 @@ pub fn checkout(
357365

358366
delete_empty_directories(&cloned_path)?;
359367

368+
// Save the commit map to /tmp/commit_map.json.
369+
save_commit_map(&file_commit_map)?;
370+
360371
Ok(())
361372
}
362373

374+
// Function to save the commit map to /tmp/commit_map.json.
375+
fn save_commit_map(
376+
file_commit_map: &HashMap<String, String>,
377+
) -> Result<(), Box<dyn std::error::Error>> {
378+
let commit_map_path = "/tmp/commit_map.json";
379+
let file = File::create(commit_map_path)?;
380+
serde_json::to_writer(file, file_commit_map)?;
381+
println!("Commit map saved to: {}", commit_map_path);
382+
Ok(())
383+
}
384+
385+
pub fn get_commit_of_file(file_path: &str) -> Result<String, Box<dyn std::error::Error>> {
386+
let relative_path = file_path.split("/").collect::<Vec<&str>>()[3..]
387+
.join("/")
388+
.replace("\"", "");
389+
let commit_map_path = "/tmp/commit_map.json";
390+
let file = File::open(commit_map_path)?;
391+
let file_commit_map: HashMap<String, String> = serde_json::from_reader(file)?;
392+
let binding = "".to_string();
393+
let commit_id = file_commit_map.get(&relative_path).unwrap_or(&binding);
394+
Ok(commit_id.to_string())
395+
}
396+
363397
fn delete_except(files: &str, base_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
364398
let files_to_keep: Vec<PathBuf> = files
365399
.lines()

src/utils/pipeline.rs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use serde_json::{json, Value};
33
use std::{collections::HashMap, process::exit};
44

55
use crate::utils::common::{
6-
bulk_check_hash_exists, insert_job_info, slack_alert, upload_to_defect_dojo,
6+
bulk_check_hash_exists, get_commit_of_file, insert_job_info, slack_alert, upload_to_defect_dojo,
77
};
88

99
use super::common::{self, execute_command, print_error, redact_github_token};
@@ -194,7 +194,6 @@ pub async fn pipeline_failure(
194194

195195
let hashes: Vec<String> = message_to_hash.keys().cloned().collect();
196196
let existing_hashes_result = bulk_check_hash_exists(&hashes, &mongo_uri).await;
197-
198197
// Handle the Result properly
199198
let existing_hashes = match existing_hashes_result {
200199
Ok(hashes) => hashes,
@@ -446,35 +445,29 @@ pub async fn pipeline_failure(
446445
let mut secret_result = HashMap::new();
447446
secret_result.insert(
448447
"file",
449-
result["SourceMetadata"]["Data"]["Filesystem"]["file"].to_string(),
448+
result["SourceMetadata"]["Data"]["Filesystem"]["file"]
449+
.as_str()
450+
.unwrap_or("")
451+
.to_string(),
450452
);
451453
secret_result.insert("line", number_string);
452-
secret_result.insert("raw", result["Raw"].to_string());
454+
secret_result.insert("raw", result["Raw"].as_str().unwrap_or("").to_string());
453455
secret_result.insert(
454456
"detector_name",
455-
result["DetectorName"].to_string().to_uppercase(),
457+
result["DetectorName"].as_str().unwrap_or("").to_uppercase(),
458+
);
459+
secret_result.insert(
460+
"decoder_name",
461+
result["DecoderName"].as_str().unwrap_or("").to_string(),
456462
);
457-
secret_result.insert("decoder_name", result["DecoderName"].to_string());
458463
secret_result
459464
};
460465
secret_results.push(secret_result);
461-
if !detected_detectors.contains(
462-
&result["DetectorName"]
463-
.as_str()
464-
.unwrap()
465-
.to_string()
466-
.to_uppercase(),
467-
) {
468-
detected_detectors.push(
469-
result["DetectorName"]
470-
.as_str()
471-
.unwrap()
472-
.to_string()
473-
.to_uppercase(),
474-
);
466+
let detector_name = result["DetectorName"].as_str().unwrap_or("").to_uppercase();
467+
if !detected_detectors.contains(&detector_name) {
468+
detected_detectors.push(detector_name);
475469
}
476470
}
477-
478471
detected_detectors = detected_detectors
479472
.iter()
480473
.map(|x| x.to_string())
@@ -493,24 +486,30 @@ pub async fn pipeline_failure(
493486
}
494487

495488
let mut secret_count = 0;
496-
let mut message_to_hash: HashMap<String, (String, String, String, String)> = HashMap::new();
489+
let mut message_to_hash: HashMap<String, (String, String, String, String, String)> =
490+
HashMap::new();
497491

498492
// Collect all secret records and their hashes
499493
for value in secret_results.clone() {
494+
// Append to slack alert message, remove first 2 values after split with "/"
495+
let file_commit = get_commit_of_file(&value["file"]);
496+
let commit_base_link = commit_path.split("/commit").collect::<Vec<&str>>()[0];
497+
let commit_link = format!("{}/commit/{}", commit_base_link, file_commit.unwrap());
500498
let vuln_record = format!(
501-
"\n\nFile: {}\nLine: {}\nRaw: {}\nDetector Name: {}",
502-
value["file"], value["line"], value["raw"], value["detector_name"]
499+
"\n\nFile: {}\nLine: {}\nRaw: {}\nDetector Name: {}\nCommit: {}",
500+
value["file"], value["line"], value["raw"], value["detector_name"], commit_link
503501
);
504502
let hashed_message = common::hash_text(&vuln_record);
505503

506504
// Collect messages and their hashes along with other details
507505
message_to_hash.insert(
508506
hashed_message,
509507
(
510-
value["file"].replace("\"", ""),
508+
value["file"].clone(),
511509
value["line"].clone(),
512-
value["raw"].replace("\"", ""),
513-
value["detector_name"].replace("\"", ""),
510+
value["raw"].clone(),
511+
value["detector_name"].clone(),
512+
commit_link,
514513
),
515514
);
516515
}
@@ -529,10 +528,8 @@ pub async fn pipeline_failure(
529528
};
530529

531530
let mut secret_count = 0;
532-
let mut found_secret_issues = false;
533-
534531
// Process each message to check for existence and add to the table
535-
for (hashed_message, (file, line, raw, detector_name)) in message_to_hash {
532+
for (hashed_message, (file, line, raw, detector_name, commit_link)) in message_to_hash {
536533
if !existing_hashes.contains(&hashed_message) {
537534
found_secret_issues = true;
538535
secret_count += 1;
@@ -545,10 +542,9 @@ pub async fn pipeline_failure(
545542
// Add row to table
546543
table.add_row(row![secret_count, file, line, raw_truncated, detector_name]);
547544

548-
// Append to slack alert message
549545
slack_alert_msg.push_str(&format!(
550-
"\n\nFile: {}\nLine: {}\nRaw: {}\nDetector Name: {}",
551-
file, line, raw, detector_name
546+
"\n\nFile: {}\nLine: {}\nRaw: {}\nDetector Name: {}\nCommit: {}",
547+
file, line, raw, detector_name, commit_link
552548
));
553549

554550
// Register the missing hash
@@ -617,7 +613,6 @@ pub async fn pipeline_failure(
617613
.collect::<Vec<String>>();
618614
pipeline_secret_license_data.insert("licenses", licenses_list);
619615
}
620-
621616
if found_sast_issues == false
622617
&& found_sca_issues == false
623618
&& found_secret_issues == false
@@ -1101,7 +1096,7 @@ pub async fn pipeline_failure(
11011096
println!("\t\t Job ID: {}", job_id);
11021097
if !mongo_uri.is_empty() {
11031098
println!("\t\t Inserting job info into MongoDB");
1104-
insert_job_info(
1099+
let _ = insert_job_info(
11051100
&mongo_uri,
11061101
&job_id,
11071102
&pipeline_failure_reason,
@@ -1130,7 +1125,7 @@ pub async fn pipeline_failure(
11301125
println!("\t\t Job ID: {}", job_id);
11311126
if !mongo_uri.is_empty() {
11321127
println!("\t\t Inserting job info into MongoDB");
1133-
insert_job_info(
1128+
let _ = insert_job_info(
11341129
&mongo_uri,
11351130
&job_id,
11361131
&pipeline_failure_reason,
@@ -1165,7 +1160,7 @@ pub async fn pipeline_failure(
11651160
println!("[+] No issues found in scan results, so slack alert is not sent");
11661161
}
11671162
}
1168-
insert_job_info(
1163+
let _ = insert_job_info(
11691164
&mongo_uri,
11701165
&job_id,
11711166
"No policy file provided, skipping policy check",
@@ -1236,6 +1231,7 @@ pub async fn pipeline_failure(
12361231
println!("[+] Could not upload SARIF report to Defect Dojo because of missing configuration - defectdojo-token, defectdojo-url, product-name, engagement-name");
12371232
}
12381233
}
1234+
12391235
pub async fn get_commit_info(
12401236
start_line: u64,
12411237
end_line: u64,
@@ -1302,6 +1298,7 @@ pub async fn get_commit_info(
13021298
})
13031299
}
13041300
// Function to fetch commit information from GitHub API
1301+
// Function to fetch commit information from GitHub API
13051302
async fn get_commit_info_from_github(path: &str, repo_url_with_pat: &str) -> Option<Value> {
13061303
// Parse the repository URL with PAT
13071304
println!("Fetching commit info from GitHub API for {}", path);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy