Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions src/lib/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export interface Incident {
incident_url: string;
total_occurrences: number;
secret_vaulted: boolean;
vault_type: string;
vault_name: string;
vault_path: string;
vault_path_count: number;
}

export interface EntityWithIncidents {
Expand Down
24 changes: 22 additions & 2 deletions src/lib/ggshield-results-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ function filterUriOccurrences(occurrences: Occurrence[]): Occurrence[] {
* @param results ggshield scan results
* @returns incidents diagnostics
*/

const pluralize = (num: number, word: string, plural = word + "s") =>
[1, -1].includes(Number(num)) ? word : plural;

export function parseGGShieldResults(
results: GGShieldScanResults,
): Diagnostic[] {
Expand All @@ -63,6 +67,22 @@ export function parseGGShieldResults(
new Position(occurrence.line_start - 1, occurrence.index_start),
new Position(occurrence.line_end - 1, occurrence.index_end),
);

let vaultInfo = "";

if (incident.secret_vaulted) {
if (incident.vault_path_count !== null) {
vaultInfo += `Secret found in vault: YES (${incident.vault_path_count} ${pluralize(incident.vault_path_count, "location")})
├─ Vault Type: ${incident.vault_type}
├─ Vault Name: ${incident.vault_name}
└─ Secret Path: ${incident.vault_path}`;
} else {
vaultInfo += "Secret found in vault: YES";
}
} else {
vaultInfo += "Secret found in vault: NO";
}

let diagnostic = new Diagnostic(
range,
`ggshield: ${occurrence.type}
Expand All @@ -73,11 +93,11 @@ Known by GitGuardian dashboard: ${incident.known_secret ? "YES" : "NO"}
Total occurrences: ${incident.total_occurrences}
Incident URL: ${incident.incident_url || "N/A"}
Secret SHA: ${incident.ignore_sha}
Secret in Secrets Manager: ${incident.secret_vaulted ? "YES" : "NO"}`,
${vaultInfo}`,
DiagnosticSeverity.Warning,
);

diagnostic.source = "gitguardian";
diagnostic.source = "\ngitguardian";
diagnostics.push(diagnostic);
},
);
Expand Down
45 changes: 45 additions & 0 deletions src/test/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,48 @@ export const scanResultsWithUriIncident = `{
"total_occurrences": 1,
"secrets_engine_version": "2.126.0"
}`;

export const scanResultsVaulted = `{
"id":"test.py",
"type":"path_scan",
"entities_with_incidents":[
{
"mode":"FILE",
"filename":"test.py",
"incidents":[
{
"policy":"Secrets detection",
"occurrences":[
{
"match":"DDACC73DdB04********************************************057c78317C39",
"type":"apikey",
"line_start":4,
"line_end":4,
"index_start":11,
"index_end":79,
"pre_line_start":4,
"pre_line_end":4
}
],
"type":"Generic High Entropy Secret",
"validity":"no_checker",
"ignore_sha":"38353eb1a2aac5b24f39ed67912234d4b4a2e23976d504a88b28137ed2b9185e",
"total_occurrences":2,
"incident_url":"",
"known_secret":false,
"secret_vaulted": true,
"vault_type": "AWS Secrets Manager",
"vault_name": "463175827647/us-west-2",
"vault_path": "arn:aws:secretsmanager:us-west-2:463175827647:secret:xav-test-svef2q:pwd",
"vault_path_count": 2

}
],
"total_incidents":1,
"total_occurrences":1
}
],
"total_incidents":1,
"total_occurrences":1,
"secrets_engine_version":"2.96.0"
}`;
14 changes: 13 additions & 1 deletion src/test/suite/results-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { parseGGShieldResults } from "../../lib/ggshield-results-parser";
import { DiagnosticSeverity } from "vscode";
import {
scanResultsNoIncident,
scanResultsVaulted,
scanResultsWithIncident,
scanResultsWithUriIncident,
} from "../constants";
Expand All @@ -17,14 +18,25 @@ suite("parseGGShieldResults", () => {
const diagnostic = diagnostics[0];
assert.ok(diagnostic.message.includes("apikey"));
assert.ok(diagnostic.message.includes("Generic High Entropy Secret"));
assert.ok(diagnostic.message.includes("Secret in Secrets Manager: NO"));
assert.ok(diagnostic.message.includes("Secret found in vault: NO"));
assert.strictEqual(diagnostic.range.start.line, 3);
assert.strictEqual(diagnostic.range.start.character, 11);
assert.strictEqual(diagnostic.range.end.line, 3);
assert.strictEqual(diagnostic.range.end.character, 79);
assert.strictEqual(diagnostic.severity, DiagnosticSeverity.Warning);
});

test("Should parse vault information", () => {
const diagnostics = parseGGShieldResults(
JSON.parse(scanResultsVaulted),
);
const diagnostic = diagnostics[0];
assert.ok(diagnostic.message.includes("Secret found in vault: YES"));
assert.ok(diagnostic.message.includes("├─ Vault Type: AWS Secrets Manager"));
assert.ok(diagnostic.message.includes("├─ Vault Name: 463175827647/us-west-2"));
assert.ok(diagnostic.message.includes("└─ Secret Path: arn:aws:secretsmanager:us-west-2:463175827647:secret:xav-test-svef2q:pwd"));
});

test("Should return an empty array if there are no incidents", () => {
const diagnostics = parseGGShieldResults(JSON.parse(scanResultsNoIncident));
assert.strictEqual(diagnostics.length, 0);
Expand Down
Loading