Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions hooks/teams-webhook/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a newline to make GH happy

1 change: 1 addition & 0 deletions hooks/teams-webhook/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a newline to make GH happy

30 changes: 30 additions & 0 deletions hooks/teams-webhook/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
# Node.js files
node_modules/*
package.json
package-lock.json
src/*
config/*
Dockerfile
.dockerignore
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a newline to make GH happy

3 changes: 3 additions & 0 deletions hooks/teams-webhook/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies: []
digest: sha256:643d5437104296e21d906ecb15b2c96ad278f20cfc4af53b12bb6069bd853726
generated: "2020-05-26T16:56:03.119255+02:00"
11 changes: 11 additions & 0 deletions hooks/teams-webhook/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v2
name: teams-webhook
description: Lets you send a findings result summary as webhook to MS Teams, after a scan is completed.

type: application

version: 0.1.0

appVersion: latest

dependencies: []
11 changes: 11 additions & 0 deletions hooks/teams-webhook/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ARG baseImageTag
FROM node:12-alpine as build
RUN mkdir -p /home/app
WORKDIR /home/app
COPY package.json package-lock.json ./
RUN npm ci --production

FROM scbexperimental/hook-sdk-nodejs:${baseImageTag:-latest}
WORKDIR /home/app/hook-wrapper/hook/
COPY --from=build --chown=app:app /home/app/node_modules/ ./node_modules/
COPY --chown=app:app ./hook.js ./hook.js
6 changes: 6 additions & 0 deletions hooks/teams-webhook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ usecase: "Publishes Scan Summary to MS Teams."
Installing the Teams WebHook hook will add a ReadOnly Hook to your namespace.

> 🔧 The implementation is currently work-in-progress and still undergoing major changes. It'll be released here once it has stabilized.


```bash
helm upgrade --install twh ./hooks/teams-webhook/ --set webhookUrl="http://example.com/my/webhook/target"
```
> ✍ This documentation is currently work-in-progress.
1 change: 1 addition & 0 deletions hooks/teams-webhook/__mocks__/axios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports.post = jest.fn();
89 changes: 89 additions & 0 deletions hooks/teams-webhook/__snapshots__/hook.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should send a post request to the url when fired 1`] = `
[MockFunction] {
"calls": Array [
Array [
"http://example.com/foo/bar",
Object {
"findings": Array [],
"paylod": Object {
"@context": "https://schema.org/extensions",
"@type": "MessageCard",
"potentialAction": Array [
Object {
"@type": "OpenUri",
"name": "Open Dashboard",
"targets": Array [
Object {
"os": "default",
"uri": "https://your-dashboard.url/",
},
],
},
Object {
"@type": "OpenUri",
"name": "Show Results in Dashboard",
"targets": Array [
Object {
"os": "default",
"uri": "https://your-dashboard.url/",
},
],
},
],
"sections": Array [
Object {
"activityImage": "https://raw.githubusercontent.com/secureCodeBox/securecodebox.github.io/gh-source/static/Favicon.png",
"activitySubtitle": "Finished at 2020-05-25T02:38:13Z",
"activityTitle": "Scheduled scan: **'demo-scan-1601086432'**",
"facts": Array [
Object {
"name": "High:",
"value": "10",
},
Object {
"name": "Medium:",
"value": "5",
},
Object {
"name": "Low:",
"value": "2",
},
Object {
"name": "Informational",
"value": "1",
},
],
"startGroup": true,
"text": "__Findings Severity Overview:__",
},
Object {
"facts": Array [
Object {
"name": "Open Ports:",
"value": "3",
},
Object {
"name": "Hosts:",
"value": "8",
},
],
"text": "__Findings Category Overview:__",
},
],
"summary": "Scan 09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc",
"themeColor": "0078D7",
"title": "New security scan Nmap results are available!",
},
},
],
],
"results": Array [
Object {
"type": "return",
"value": undefined,
},
],
}
`;
69 changes: 69 additions & 0 deletions hooks/teams-webhook/__testfiles__/messageCard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"summary": "Issue 176715375",
"themeColor": "0078D7",
"title": "New security scan results are available",
"sections": [
{
"activityTitle": "Scheduled scan: **'nmap-hamburg-2345678'**",
"activitySubtitle": "Startet at 15.06.2020 20:10",
"activityImage": "https://raw.githubusercontent.com/secureCodeBox/securecodebox.github.io/gh-source/static/Favicon.png",
"startGroup": true,
"facts": [
{
"name": "High:",
"value": "11"
},
{
"name": "Medium:",
"value": "20"
},
{
"name": "Low:",
"value": "10"
},
{
"name": "Informational",
"value": "10"
}
],
"text": "__Findings Severity Overview:__"
},
{
"facts": [
{
"name": "Open Ports:",
"value": "3"
},
{
"name": "Hosts:",
"value": "8"
}
],
"text": "__Findings Category Overview:__"
}
],
"potentialAction": [
{
"@type": "OpenUri",
"name": "Open Dashboard",
"targets": [
{
"os": "default",
"uri": "https://my-secureCodeBoc-dashboard.url/"
}
]
},
{
"@type": "OpenUri",
"name": "Show Results in Dashboard",
"targets": [
{
"os": "default",
"uri": "https://my-secureCodeBoc-dashboard.url/"
}
]
}
]
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a newline to make GH happy

97 changes: 97 additions & 0 deletions hooks/teams-webhook/hook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
const axios = require("axios");

async function handle({
getFindings,
scan,
webhookUrl = process.env["WEBHOOK_URL"],
}) {
const findings = await getFindings();

console.log(`Sending ${findings.length} findings to ${webhookUrl}`);
console.log(scan);
console.log(findings);

const paylod = getMessageCard(scan);

await axios.post(webhookUrl, {paylod, findings });
}

/**
* Returns a MS Teams WebHook Payload in the classic "MessageCard" style.
* @param {*} scan
*/
function getMessageCard(scan) {
var result = {
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"summary": "Scan " + scan.metadata.uid,
"themeColor": "0078D7",
"title": "New security scan "+ scan.spec.scanType +" results are available!",
"sections": [
{
"activityTitle": "Scheduled scan: **'"+ scan.metadata.name +"'**",
"activitySubtitle": "Finished at "+ scan.status.finishedAt,
"activityImage": "https://raw.githubusercontent.com/secureCodeBox/securecodebox.github.io/gh-source/static/Favicon.png",
"startGroup": true,
"facts": [
{
"name": "High:",
"value": ""+ scan.status.findings.severities.high +""
},
{
"name": "Medium:",
"value": ""+ scan.status.findings.severities.medium +""
},
{
"name": "Low:",
"value": ""+ scan.status.findings.severities.low +""
},
{
"name": "Informational",
"value": ""+ scan.status.findings.severities.informational +""
}
],
"text": "__Findings Severity Overview:__"
},
{
"facts": [
{
"name": "Open Ports:",
"value": "3"
},
{
"name": "Hosts:",
"value": "8"
}
],
"text": "__Findings Category Overview:__"
}
],
"potentialAction": [
{
"@type": "OpenUri",
"name": "Open Dashboard",
"targets": [
{
"os": "default",
"uri": "https://your-dashboard.url/"
}
]
},
{
"@type": "OpenUri",
"name": "Show Results in Dashboard",
"targets": [
{
"os": "default",
"uri": "https://your-dashboard.url/"
}
]
}
]
}
return result;
}

module.exports.handle = handle;
module.exports.axios = axios;
55 changes: 55 additions & 0 deletions hooks/teams-webhook/hook.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const { handle, axios } = require("./hook");

beforeEach(() => {
axios.post.mockClear();
});

test("should send a post request to the url when fired", async () => {
const findings = [];

const getFindings = async () => findings;

const scan = {
metadata: {
uid: "09988cdf-1fc7-4f85-95ee-1b1d65dbc7cc",
name: "demo-scan-1601086432",
namespace: "my-scans",
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: "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 webhookUrl = "http://example.com/foo/bar";

await handle({ getFindings, scan, webhookUrl });

expect(axios.post).toMatchSnapshot();
});
Loading