Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit 112b45f

Browse files
committed
#33 Improved the generation of the cascading scans name
If the scan was previously prefixed by the scanType, this prefix will now be replaced with the cascading Scans scanType
1 parent e87b1ea commit 112b45f

File tree

2 files changed

+126
-48
lines changed

2 files changed

+126
-48
lines changed
Lines changed: 98 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,83 @@
11
const { getCascadingScans } = require("./hook");
22

3-
test("Should create subsequent scans for open HTTPS ports (NMAP findings)", () => {
4-
const findings = [
5-
{
6-
name: "Port 443 is open",
7-
category: "Open Port",
8-
attributes: {
9-
state: "open",
10-
hostname: "foobar.com",
11-
port: 443,
12-
service: "https"
13-
}
14-
}
15-
];
3+
let parentScan = undefined;
164

17-
const cascadingRules = [
18-
{
19-
apiVersion: "cascading.experimental.securecodebox.io/v1",
20-
kind: "CascadingRule",
21-
metadata: {
22-
name: "tls-scans"
23-
},
24-
spec: {
25-
matches: [
5+
beforeEach(() => {
6+
parentScan = {
7+
apiVersion: "execution.experimental.securecodebox.io/v1",
8+
kind: "Scan",
9+
metadata: {
10+
name: "nmap-foobar.com",
11+
},
12+
spec: {
13+
scanType: "nmap",
14+
parameters: "foobar.com",
15+
},
16+
};
17+
});
18+
19+
const sslyzeCascadingRules = [
20+
{
21+
apiVersion: "cascading.experimental.securecodebox.io/v1",
22+
kind: "CascadingRule",
23+
metadata: {
24+
name: "tls-scans",
25+
},
26+
spec: {
27+
matches: {
28+
anyOf: [
2629
{
2730
category: "Open Port",
2831
attributes: {
2932
port: 443,
30-
service: "https"
31-
}
33+
service: "https",
34+
},
3235
},
3336
{
3437
category: "Open Port",
3538
attributes: {
36-
service: "https"
37-
}
38-
}
39+
service: "https",
40+
},
41+
},
3942
],
40-
scanSpec: {
41-
name: "sslyze",
42-
parameters: ["--regular", "{{attributes.hostname}}"]
43-
}
44-
}
45-
}
43+
},
44+
scanSpec: {
45+
scanType: "sslyze",
46+
parameters: ["--regular", "{{attributes.hostname}}"],
47+
},
48+
},
49+
},
50+
];
51+
52+
test("should create subsequent scans for open HTTPS ports (NMAP findings)", () => {
53+
const findings = [
54+
{
55+
name: "Port 443 is open",
56+
category: "Open Port",
57+
attributes: {
58+
state: "open",
59+
hostname: "foobar.com",
60+
port: 443,
61+
service: "https",
62+
},
63+
},
4664
];
4765

48-
const cascadedScans = getCascadingScans(findings, cascadingRules);
66+
const cascadedScans = getCascadingScans(
67+
parentScan,
68+
findings,
69+
sslyzeCascadingRules
70+
);
4971

5072
expect(cascadedScans).toMatchInlineSnapshot(`
5173
Array [
5274
Object {
53-
"name": "sslyze",
75+
"name": "sslyze-foobar.com-tls-scans-",
5476
"parameters": Array [
5577
"--regular",
5678
"foobar.com",
5779
],
80+
"scanType": "sslyze",
5881
},
5982
]
6083
`);
@@ -69,14 +92,50 @@ test("Should create no subsequent scans if there are no rules", () => {
6992
state: "open",
7093
hostname: "foobar.com",
7194
port: 443,
72-
service: "https"
73-
}
74-
}
95+
service: "https",
96+
},
97+
},
7598
];
7699

77100
const cascadingRules = [];
78101

79-
const cascadedScans = getCascadingScans(findings, cascadingRules);
102+
const cascadedScans = getCascadingScans(parentScan, findings, cascadingRules);
80103

81104
expect(cascadedScans).toMatchInlineSnapshot(`Array []`);
82105
});
106+
107+
test("should not try to do magic to the scan name if its something random", () => {
108+
parentScan.metadata.name = "foobar.com";
109+
110+
const findings = [
111+
{
112+
name: "Port 443 is open",
113+
category: "Open Port",
114+
attributes: {
115+
state: "open",
116+
hostname: "foobar.com",
117+
port: 443,
118+
service: "https",
119+
},
120+
},
121+
];
122+
123+
const cascadedScans = getCascadingScans(
124+
parentScan,
125+
findings,
126+
sslyzeCascadingRules
127+
);
128+
129+
expect(cascadedScans).toMatchInlineSnapshot(`
130+
Array [
131+
Object {
132+
"name": "foobar.com-tls-scans-",
133+
"parameters": Array [
134+
"--regular",
135+
"foobar.com",
136+
],
137+
"scanType": "sslyze",
138+
},
139+
]
140+
`);
141+
});

hooks/declarative-subsequent-scans/hook.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ interface Finding {
1616
attributes: Map<string, string | number>;
1717
}
1818

19-
interface CascadingRules {
19+
interface CascadingRule {
2020
metadata: k8s.V1ObjectMeta;
2121
spec: CascadingRuleSpec;
2222
}
@@ -41,7 +41,9 @@ interface ScanSpec {
4141
}
4242

4343
interface ExtendedScanSpec extends ScanSpec {
44-
generatedBy: string;
44+
// This is the name of the scan. Its not "really" part of the scan spec
45+
// But this makes the object smaller
46+
name: string;
4547
}
4648

4749
interface HandleArgs {
@@ -53,30 +55,31 @@ export async function handle({ scan, getFindings }: HandleArgs) {
5355
const findings = await getFindings();
5456
const cascadingRules = await getCascadingRules();
5557

56-
const cascadingScans = getCascadingScans(findings, cascadingRules);
58+
const cascadingScans = getCascadingScans(scan, findings, cascadingRules);
5759

58-
for (const { scanType, parameters, generatedBy } of cascadingScans) {
60+
for (const { name, scanType, parameters } of cascadingScans) {
5961
await startSubsequentSecureCodeBoxScan({
60-
name: `${scan.metadata.name}-${generatedBy}`,
62+
name,
6163
parentScan: scan,
6264
scanType,
6365
parameters,
6466
});
6567
}
6668
}
6769

68-
async function getCascadingRules(): Promise<Array<CascadingRules>> {
70+
async function getCascadingRules(): Promise<Array<CascadingRule>> {
6971
// Explicit Cast to the proper Type
70-
return <Array<CascadingRules>>await getCascadingRulesFromCluster();
72+
return <Array<CascadingRule>>await getCascadingRulesFromCluster();
7173
}
7274

7375
/**
7476
* Goes thought the Findings and the CascadingRules
7577
* and returns a List of Scans which should be started based on both.
7678
*/
7779
export function getCascadingScans(
80+
parentScan: Scan,
7881
findings: Array<Finding>,
79-
cascadingRules: Array<CascadingRules>
82+
cascadingRules: Array<CascadingRule>
8083
): Array<ExtendedScanSpec> {
8184
const cascadingScans: Array<ExtendedScanSpec> = [];
8285

@@ -91,7 +94,7 @@ export function getCascadingScans(
9194
const { scanType, parameters } = cascadingRule.spec.scanSpec;
9295

9396
cascadingScans.push({
94-
generatedBy: cascadingRule.metadata.name,
97+
name: generateCascadingScanName(parentScan, cascadingRule),
9598
scanType: Mustache.render(scanType, finding),
9699
parameters: parameters.map((parameter) =>
97100
Mustache.render(parameter, finding)
@@ -103,3 +106,19 @@ export function getCascadingScans(
103106

104107
return cascadingScans;
105108
}
109+
110+
function generateCascadingScanName(
111+
parentScan: Scan,
112+
cascadingRule: CascadingRule
113+
): string {
114+
let namePrefix = parentScan.metadata.name;
115+
116+
// 🧙‍ If the Parent Scan start with its scanType we'll replace it with the ScanType of the CascadingScan
117+
if (namePrefix.startsWith(parentScan.spec.scanType)) {
118+
namePrefix = namePrefix.replace(
119+
parentScan.spec.scanType,
120+
cascadingRule.spec.scanSpec.scanType
121+
);
122+
}
123+
return `${namePrefix}-${cascadingRule.metadata.name}-`;
124+
}

0 commit comments

Comments
 (0)