Skip to content
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,29 @@
*.iml
*.ipr
out/

Created by https://www.toptal.com/developers/gitignore/api/vim
# Edit at https://www.toptal.com/developers/gitignore?templates=vim

### Vim ###
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]

# Session
Session.vim
Sessionx.vim

# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~

# End of https://www.toptal.com/developers/gitignore/api/vim
36 changes: 34 additions & 2 deletions hooks/notification/.helm-docs.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Please take a look at the documentation for each type (e.g. for slack see [Confi
- [Slack](#configuration-of-a-slack-notification)
- [Slack App](#configuration-of-a-slack-app-notification)
- [Email](#configuration-of-an-email-notification)
- [MS Teams](#configuration-of-a-ms-teams-notification)

### Configuration of a Notification

Expand Down Expand Up @@ -204,7 +205,7 @@ This configuration needs to be specified under `env` in the values yaml.
The identifier for this config has to be `SMTP_CONFIG`.
A basic configuration could look like this:

```
```yaml
notificationChannels:
- name: email
type: email
Expand All @@ -227,6 +228,37 @@ env:
value: secureCodeBox
```

### Configuration Of A MS Teams Notification

To configure a MS Teams notification you need to set the type to `ms-teams`.
In `endPoint` you need to specify the MS Teams webhook.
To use the template provided by the secureCodeBox set template to `msteams-messageCard`.

The default template allows you to specify an additional set of information.
If you use an external web based vulnerability management system with some kind of dashboard, you can set the variable `VULNMANAG_ENABLED` to true and point the `VULNMANAG_DASHBOARD_URL` to the URL of your vulnerability management.
This will add a button in the notification that links directly to your dashboard.
You can also add a button that opens your findings directly in your dashboard.
To do this you need to specify `dashboardFingingsUrl`.
You will have to replace the id of the scan in this url with `{{ `{{ uid }}` }}` so that nunjucks can parse these urls.

A basic configuration could look like this:

```yaml
notificationChannels:
- name: ms-teams
type: ms-teams
template: msteams-messageCard
rules: []
endPoint: "https://somewhere.xyz/sadf12"
env:
- name: VULNMANAG_ENABLED
value: true
- name: VULNMANAG_DASHBOARD_URL
value: "somedashboard.url"
- name: VULNMANAG_DASHBOARD_FINDINGS_URL
value: "somedashboard.url/findings/{{ `{{ uid }}` }}"
```

### Custom Message Templates

CAUTION: Nunjucks templates allow code to be injected! Use templates from trusted sources only!
Expand All @@ -244,4 +276,4 @@ To fill your template with data we provide the following objects.
{{- end }}

{{- define "extra.scannerLinksSection" -}}
{{- end }}
{{- end }}
7 changes: 3 additions & 4 deletions hooks/notification/NotifierFactory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { NotificationChannel } from "./model/NotificationChannel";
import { Scan } from "./model/Scan";
import { NotifierFactory } from "./NotifierFactory"
import { SlackNotifier } from "./Notifiers/SlackNotifier";
import { MSTeamsNotifier } from "./Notifiers/MSTeamsNotifier";
import { NotifierType } from "./NotifierType";

const finding: Finding = {
Expand Down Expand Up @@ -85,9 +86,7 @@ test("Should Create MS Teams Notifier", async () => {
const findings: Finding[] = []
findings.push(finding)

const t = () => {
NotifierFactory.create(chan, scan, findings, []);
}
const s = NotifierFactory.create(chan, scan, findings, []);

expect(t).toThrow("This Type is not Implemented :(");
expect(s instanceof MSTeamsNotifier).toBe(true);
})
3 changes: 3 additions & 0 deletions hooks/notification/NotifierFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { NotifierType } from "./NotifierType";
import { SlackNotifier } from "./Notifiers/SlackNotifier";
import { SlackAppNotifier } from "./Notifiers/SlackAppNotifier";
import { EMailNotifier } from "./Notifiers/EMailNotifier";
import { MSTeamsNotifier } from "./Notifiers/MSTeamsNotifier";
import { NotificationChannel } from "./model/NotificationChannel";
import { Scan } from "./model/Scan";
import { Finding } from "./model/Finding";
Expand All @@ -25,6 +26,8 @@ export class NotifierFactory {
return new EMailNotifier(channel, scan, findings, args);
case NotifierType.SLACK_APP:
return new SlackAppNotifier(channel, scan, findings, args);
case NotifierType.MS_TEAMS:
return new MSTeamsNotifier(channel, scan, findings, args);
default:
throw new Error("This Type is not Implemented :(");
}
Expand Down
1 change: 1 addition & 0 deletions hooks/notification/Notifiers/AbstractNotifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export abstract class AbstractNotifier implements Notifier {
findings: this.findings,
scan: this.scan,
args: this.args,
renderString: nunjucks.renderString,
}
);
try {
Expand Down
32 changes: 32 additions & 0 deletions hooks/notification/Notifiers/AbstractWebHookNotifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: 2020 iteratec GmbH
//
// SPDX-License-Identifier: Apache-2.0

import { NotifierType } from "../NotifierType"
import { AbstractNotifier } from "./AbstractNotifier"
import { Finding } from "../model/Finding"
import axios from 'axios';
import { NotificationChannel } from "../model/NotificationChannel";
import { Scan } from "../model/Scan";

export abstract class AbstractWebHookNotifier extends AbstractNotifier {

protected abstract type: NotifierType;

constructor(channel: NotificationChannel, scan: Scan, findings: Finding[], args: Object) {
super(channel, scan, findings, args);
}

public async sendMessage(): Promise<void> {
await this.sendPostRequest(this.renderMessage());
}

protected async sendPostRequest(message: string) {
try {
await axios.post(this.channel.endPoint, message)
} catch (e) {
console.log(`There was an Error sending the Message for the "${this.type}": "${this.channel.name}"`);
console.log(e);
}
}
}
105 changes: 105 additions & 0 deletions hooks/notification/Notifiers/MSTeamsNotifier.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-FileCopyrightText: 2020 iteratec GmbH
//
// SPDX-License-Identifier: Apache-2.0

import { MSTeamsNotifier } from "./MSTeamsNotifier";
import axios from 'axios'
import { NotificationChannel } from "../model/NotificationChannel";
import { NotifierType } from "../NotifierType";
import { Scan } from "../model/Scan";

jest.mock('axios');

beforeEach(() => {
jest.clearAllMocks();
})

const channel: NotificationChannel = {
name: "Channel Name",
type: NotifierType.MS_TEAMS,
template: "msteams-messageCard",
rules: [],
endPoint: "https://iteratec.webhook.office.com/webhookb2/f2a7b22a-6558-4db5-8d4b-860f8d4c6848@e96afb08-eeaf-49be-90d6-526571a42d8a/IncomingWebhook/cd8d3c70bb504eb8b44385a8e0ebe6f5/812e82db-e6d9-4651-b0c8-3becfca82658"
};

test("Should Send Message With Findings And Severities", async () => {

const scan: Scan = {
metadata: {
uid: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc",
name: "demo-scan-1601086432",
namespace: "my-scans",
creationTimestamp: new Date("2021-01-01T14:29:25Z"),
labels: {
company: "iteratec",
"attack-surface": "external",
},
},
spec: {
scanType: "Nmap",
parameters: ["-Pn", "localhost"],
},
status: {
findingDownloadLink:
"https://my-secureCodeBox-instance.com/scan-b9as-sdweref--sadf-asdfsdf-dasdgf-asdffdsfa7/findings.json",
findings: {
categories: {
"A Client Error response code was returned by the server": 1,
"Information Disclosure - Sensitive Information in URL": 1,
"Strict-Transport-Security Header Not Set": 1,
},
count: 3,
severities: {
high: 10,
medium: 5,
low: 2,
informational: 1,
},
},
finishedAt: new Date("2020-05-25T02:38:13Z"),
rawResultDownloadLink:
"https://my-secureCodeBox-instance.com/scan-blkfsdg-sdgfsfgd-sfg-sdfg-dfsg-gfs98-e8af2172caa7/zap-results.json?Expires=1601691232",
rawResultFile: "zap-results.json",
rawResultType: "zap-json",
state: "Done",
},
};

const teamsNotifier = new MSTeamsNotifier(channel, scan, [], []);
teamsNotifier.sendMessage();
expect(axios.post).toBeCalled();
});

test("Should Send Minimal Template For Empty Findings", async () => {
const scan: Scan = {
metadata: {
uid: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc",
name: "demo-scan-1601086432",
namespace: "my-scans",
creationTimestamp: new Date("2021-01-01T14:29:25Z"),
labels: {
company: "iteratec",
"attack-surface": "external",
},
},
spec: {
scanType: "Nmap",
parameters: ["-Pn", "localhost"],
},
status: {
findingDownloadLink:
"https://my-secureCodeBox-instance.com/scan-b9as-sdweref--sadf-asdfsdf-dasdgf-asdffdsfa7/findings.json",
findings: {},
finishedAt: new Date("2020-05-25T02:38:13Z"),
rawResultDownloadLink:
"https://my-secureCodeBox-instance.com/scan-blkfsdg-sdgfsfgd-sfg-sdfg-dfsg-gfs98-e8af2172caa7/zap-results.json?Expires=1601691232",
rawResultFile: "zap-results.json",
rawResultType: "zap-json",
state: "Done",
},
};

const n = new MSTeamsNotifier(channel, scan, [], []);
n.sendMessage();
expect(axios.post).toBeCalled();
})
19 changes: 19 additions & 0 deletions hooks/notification/Notifiers/MSTeamsNotifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2020 iteratec GmbH
//
// SPDX-License-Identifier: Apache-2.0

import { NotifierType } from "../NotifierType"
import { AbstractWebHookNotifier } from "./AbstractWebHookNotifier"
import { Finding } from "../model/Finding"
import axios from 'axios';
import { NotificationChannel } from "../model/NotificationChannel";
import { Scan } from "../model/Scan";

export class MSTeamsNotifier extends AbstractWebHookNotifier {

protected type: NotifierType = NotifierType.MS_TEAMS

constructor(channel: NotificationChannel, scan: Scan, findings: Finding[], args: Object) {
super(channel, scan, findings, args);
}
}
17 changes: 2 additions & 15 deletions hooks/notification/Notifiers/SlackNotifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,17 @@
// SPDX-License-Identifier: Apache-2.0

import { NotifierType } from "../NotifierType"
import { AbstractNotifier } from "./AbstractNotifier"
import { AbstractWebHookNotifier } from "./AbstractWebHookNotifier"
import { Finding } from "../model/Finding"
import axios from 'axios';
import { NotificationChannel } from "../model/NotificationChannel";
import { Scan } from "../model/Scan";

export class SlackNotifier extends AbstractNotifier {
export class SlackNotifier extends AbstractWebHookNotifier {

protected type: NotifierType = NotifierType.SLACK

constructor(channel: NotificationChannel, scan: Scan, findings: Finding[], args: Object) {
super(channel, scan, findings, args);
}

public async sendMessage(): Promise<void> {
await this.sendPostRequest(this.renderMessage());
}

protected async sendPostRequest(message: string) {
try {
await axios.post(this.channel.endPoint, message)
} catch (e) {
console.log(`There was an Error sending the Message for the Slack Notifier "${this.channel.name}"`);
console.log(e);
}
}
}
34 changes: 33 additions & 1 deletion hooks/notification/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Please take a look at the documentation for each type (e.g. for slack see [Confi
- [Slack](#configuration-of-a-slack-notification)
- [Slack App](#configuration-of-a-slack-app-notification)
- [Email](#configuration-of-an-email-notification)
- [MS Teams](#configuration-of-a-ms-teams-notification)

### Configuration of a Notification

Expand Down Expand Up @@ -223,7 +224,7 @@ This configuration needs to be specified under `env` in the values yaml.
The identifier for this config has to be `SMTP_CONFIG`.
A basic configuration could look like this:

```
```yaml
notificationChannels:
- name: email
type: email
Expand All @@ -246,6 +247,37 @@ env:
value: secureCodeBox
```

### Configuration Of A MS Teams Notification

To configure a MS Teams notification you need to set the type to `ms-teams`.
In `endPoint` you need to specify the MS Teams webhook.
To use the template provided by the secureCodeBox set template to `msteams-messageCard`.

The default template allows you to specify an additional set of information.
If you use an external web based vulnerability management system with some kind of dashboard, you can set the variable `VULNMANAG_ENABLED` to true and point the `VULNMANAG_DASHBOARD_URL` to the URL of your vulnerability management.
This will add a button in the notification that links directly to your dashboard.
You can also add a button that opens your findings directly in your dashboard.
To do this you need to specify `dashboardFingingsUrl`.
You will have to replace the id of the scan in this url with `{{ uid }}` so that nunjucks can parse these urls.

A basic configuration could look like this:

```yaml
notificationChannels:
- name: ms-teams
type: ms-teams
template: msteams-messageCard
rules: []
endPoint: "https://somewhere.xyz/sadf12"
env:
- name: VULNMANAG_ENABLED
value: true
- name: VULNMANAG_DASHBOARD_URL
value: "somedashboard.url"
- name: VULNMANAG_DASHBOARD_FINDINGS_URL
value: "somedashboard.url/findings/{{ uid }}"
```

### Custom Message Templates

CAUTION: Nunjucks templates allow code to be injected! Use templates from trusted sources only!
Expand Down
Loading