Skip to main content

Notification WebHook

License Apache-2.0GitHub release (latest SemVer)OWASP Lab ProjectArtifact HUBGitHub Repo starsMastodon Follower

What is "Notification" Hook about?

Installing the Notification WebHook hook will add a ReadOnly Hook to your namespace which is capable of sending scan results containing findings as messages to different tools like messangers or even email.

You can customise the message templates on your behalf or use the already provided one.

Deployment

The notification chart can be deployed via helm:

# Install HelmChart (use -n to configure another namespace)
helm upgrade --install notification oci://ghcr.io/securecodebox/helm/notification

Requirements

Kubernetes: >=v1.11.0-0

Additional Chart Configurations

Installing the Notification hook will add a ReadOnly Hook to your namespace.

helm upgrade --install notification ./hooks/notification/ --values /path/to/your/values"

The values.yaml you need depends on the notification type you want to use. Please take a look at the documentation for each type (e.g. for slack see Configuration of a Slack Notification)

Available Notifier

Configuration of a Notification

The general configuration of a notification looks something like this

notificationChannels:
- name: slack
type: slack
template: slack-messageCard
skipNotificationOnZeroFinding: true
rules:
- matches:
anyOf:
- category: "Open Port"
endPoint: "SOME_ENV"

env:
- name: SOME_ENV
valueFrom:
secretKeyRef:
name: some-secret
key: some-key

The Notification Hook enables you to define multiple so called notificationChannels. A notificationChannel defines the Notification to a specific platform (e.g. Slack or Teams).

The name is used to for debugging failing notifications. it can be a string of you choice.

The type specifies the type of the notification (in this example slack). See Available Notifier.

The template field defines the name of a Nunjucks template to send to your notification channel. These templates are usually tied to their notification channel (slack templates will not work for teams). The template slack-messageCard is provided by default. Notice that for the name of the template we chose to omit the file type. The template slack-messageCard will point to slack-messageCard.njk in the filesystem of the hook.

The skipNotificationOnZeroFindings if set to true will cause the notifier when there were no findings. This can happen when the scan did not identify any or if all findings were filtered out using rules. Defaults to false if not set. You can use skipNotificationOnZeroFindings to only send out notification for non duplicate findings, e.g. by combining the DefectDojo hook with this one and filtering out the duplicate attribute in the rules.

The endPoint specifies where the notification has to go to. To protect the actual endPoint (e.g. a webhook url) this should point to an env name defined under env For slack this would be your webhook URL to slack.

To define conditions when a notification should be created you can use rules. If no rules are specified, this hook will assume that you always want to be notified.

Under env you have to define additional information needed for your templates such as the actual endpoint. env will be mapped to the env implementation of Kubernetes. This means that you can define key-value pairs as well as providing envs via secrets (See Define Environment Variables for a Container | Kubernetes).

Rule Configuration

The rules can be defined in the values of the Chart. The syntax and semantic for these rules are quite similar to CascadingRules (See: secureCodeBox | CascadingRules) To define Rules you will have to provide the rules field with one or more matches elements. Each matches defines one Rule. For example:

rules:
- matches:
anyOf:
- category: "Open Port"
attributes:
port: 23
state: open

This Rule will match all Findings with an open port on 23.

matches

Within the matches you will have to provide anyOf anyOf contains one or more conditions to be met by the finding to match the rule. Notice that only one of these elements needs to match the finding for the rule to match.

Configuration of a Slack Notification (WebHook)

To configure a Slack notification set the type to slack and the endPoint to point to your env containing your Webhook URL to slack. You can use one of the following default templates:

  • slack-messageCard: Sends a message with a summary listing the number of findings per category and severity.
  • slack-individual-findings-with-defectdojo: Sends a message with a list of all findings with a link to the finding in DefectDojo. Will only work correctly if the DefectDojo hook is installed in the same namespace.
Example Config

The below example shows how to create a helm values chart and load secrets for access. You must have endPoint point to a defined environment variable, not a string.

# cat myvalues.yaml

notificationChannels:
- name: nmapopenports
type: slack
template: slack-messageCard
skipNotificationOnZeroFinding: true
rules:
- matches:
anyOf:
- category: "Open Port"
endPoint: POINTER_TO_ENV
env:
- name: POINTER_TO_ENV
valueFrom:
secretKeyRef:
name: myslacksecret
key: SLACK_WEB_HOOK

# cat values_slack_secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: myslacksecret
type: Opaque
data:
SLACK_WEB_HOOK: NOIDONTHINKSOBASE64STUFF

kubectl apply -f values_slack_secrets.yaml
helm upgrade --install nwh oci://ghcr.io/securecodebox/helm/notification-hook --values myvalues.yaml

Configuration of a Slack App Notification

The slack-app notifier is an alternate way to send notifications to slack using the slack api directly rather then using webhooks. Use slack-app over the normal slack if you want to send notifications into different slack channels on a per scan basis.

Slack App Configuration

To set it up, you'll need to create a new slack app at https://api.slack.com/apps/ and add the chat:write "Bot Token Scope" to it on the "OAuth & Permissions" tab. Then add the bot to your workspace, this will give you the access token (should begin with a xoxb-).

To configure a Slack notification set the type to slack-app and reference the secret via the SLACK_APP_TOKEN env var.

Example Config
notificationChannels:
- name: slack
type: slack-app
template: slack-messageCard
rules: []

env:
# you can create the secret via: kubectl create secret generic slack-app-token --from-literal="token=xoxb-..."
- name: SLACK_APP_TOKEN
valueFrom:
secretKeyRef:
name: slack-app-token
key: token
# configures which channel the messages are send to if the scan doesn't specify a channel
- name: SLACK_DEFAULT_CHANNEL
value: "#example-channel"
Supported Notification Channels

The slack-app notifier supports the same message templates as the slack notifier. See slack for the supported message types.

Scan / Channel Config

You can configure to which channel the message is sent to by setting the notification.securecodebox.io/slack-channel to the channel the message should be sent to, the following example will send its notifications to the #juice-shop-dev channel in the slack workspace of the configured token.

Note: The channel needs to have the app you've create invited to it. Otherwise the app will not be permitted to write to it.

apiVersion: "execution.securecodebox.io/v1"
kind: Scan
metadata:
name: "nmap-juice-shop"
annotations:
notification.securecodebox.io/slack-channel: "#juice-shop-dev"
spec:
scanType: "nmap"
parameters:
- juice-shop.default.svc

Configuration Of An Email Notification

To configure an email notification set the type to email and the endPoint to point to your env containing your target email address. You can use one of the following default templates:

  • email: Sends a email with a summary listing the number of findings per category and severity.

Additional to this configuration you will have to provide a special smtp configuration URL. This config reflects the transporter configuration of nodemailer (See nodemailer | SMTP Transport). 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:

notificationChannels:
- name: email
type: email
template: email
rules: []
endPoint: "someone@example.com"
env:
- name: SMTP_CONFIG
# you can create the secret via: kubectl create secret generic email-credentials --from-literal="smtp-config=smtp://user:pass@smtp.domain.tld/"
valueFrom:
secretKeyRef:
name: email-credentials
key: smtp-config

To provide a custom from field for your email you can specify EMAIL_FROM under env. For example:

env:
- name: SMTP_CONFIG
valueFrom:
secretKeyRef:
name: email-credentials
key: smtp-config
- name: EMAIL_FROM
value: secureCodeBox

You can overwrite the default email recipient of the notification mail for every scan by setting a notification.securecodebox.io/email-recipient annotation on the scan to another email address:

apiVersion: "execution.securecodebox.io/v1"
kind: Scan
metadata:
name: "nmap-juice-shop"
annotations:
notification.securecodebox.io/email-recipient: "foo@example.com"
spec:
scanType: "nmap"
parameters:
- juice-shop.default.svc

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:

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

Configuration of a Trello Notification

A Trello notification is used to create Trello cards for each finding that matches the defined rules. This allows integrating SecureCodeBox into your development workflow. Each finding will be created as a card with the following information:

Card Name: <severity>: <name>
Card Body: <location> <category> <description> <attributes>
Requirements
Configuration

To configure a Trello notification set the type to trello and the endPoint to point to your env containing the Trello cards API endpoint. You also need to define the following env vars (if an env var is not defined it will take the default value, if required and not set the notification won't be sent):

  • TRELLO_CARDS_ENDPOINT: The Trello cards API endpoint. Default: https://api.trello.com/1/cards.
  • TRELLO_KEY: Your Trello API key. Read the requirements above. Required.
  • TRELLO_TOKEN: Your Trello API token. Read the requirements above. Required.
  • TRELLO_LIST: Trello unique Id of the list where the cards will be placed. Required.
  • TRELLO_LABELS: Comma separated list of Trello label IDs to apply to the card. If empty no labels will be applied. Default: ""
  • TRELLO_POS: The position of the card in the list as defined by the Trello cards API. Options: top, bottom, or a positive float. Default: top.
  • TRELLO_TITLE_PREFIX: An optional arbitrary text to add to the title of the card. Default "".
Example Config

The below example shows how to create a helm values chart and load secrets for access. You must have endPoint point to a defined environment variable, not a string.

# cat trello_values.yaml
notificationChannels:
- name: nmapopenports
type: trello
skipNotificationOnZeroFinding: true
rules:
- matches:
anyOf:
- category: "Open Port"
endPoint: TRELLO_CARDS_ENDPOINT
env:
- name: TRELLO_CARDS_ENDPOINT
value: https://api.trello.com/1/cards
- name: TRELLO_KEY
valueFrom:
secretKeyRef:
name: trello
key: key
- name: TRELLO_TOKEN
valueFrom:
secretKeyRef:
name: trello
key: token
- name: TRELLO_LIST
value: 123a456b789c013d
- name: TRELLO_LABELS
value: "111a111b222c333f,555a666b777c888d"
- name: TRELLO_POS
value: top
- name: TRELLO_TITLE_PREFIX
value: "Alert! "
---
# cat trello_secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: trello
type: Opaque
stringData:
key: YOURSECRETTRELLOAPIKEY
token: YOURSECRETTRELLOAPITOKEN
kubectl apply -f trello_secrets.yaml
helm upgrade --install nwh oci://ghcr.io/securecodebox/helm/notification-hook --values trello_values.yaml

Configuration Of A rocket.chat Notification

To configure a rocket.chat notification you need to set the type to rocket-chat. In endPoint you need to specify url to your rocket.chat instances post.message endpoint. E.g. https://rocketchat.example.com/api/v1/chat.postMessage To use the template provided by the secureCodeBox set template to rocket-chat. The rocket.chat notifier requires a rocket chat api token to work correctly, see example below on how this is configured.

You can configure the channel the hook sends the message to by setting the notification.securecodebox.io/rocket-chat-channel=#my-channel on the scan. If the channel is not set the hook wil send the notification to the default channel configured, see config example below.

A basic configuration could look like this:

notificationChannels:
- name: rocket-chat
type: rocket-chat
template: rocket-chat
rules: []
endPoint: "https://rocketchat.example.com/api/v1/chat.postMessage"
env:
- name: ROCKET_CHAT_AUTH_TOKEN
# you can create the secret via: kubectl create secret generic rocket-chat --from-literal="token=token-goes-here"
valueFrom:
secretKeyRef:
name: rocket-chat
key: token
- name: ROCKET_CHAT_USER_ID
value: "XcNTAqEhyBD14aqcZ"
- name: ROCKET_CHAT_DEFAULT_CHANNEL
# channel used to send in notifications if no channel is set for the individual scan.
value: "#securecodebox"

Custom Message Templates

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

The Notification Hook enables you to write your own message templates if the templates provided by default are not sufficient. Templates for this hook are written using the Nunjucks templating engine.

To fill your template with data we provide the following objects.

objectDetails
findingsAn array of the findings matching your rules (See Finding secureCodeBox API Specification
scanAn Object containing information about the scan that triggered the notification (See Scan secureCodeBox API Specification
argscontains process.env (See: process.env nodejs) you can use this to access data defined in env of the values.yaml

Values

KeyTypeDefaultDescription
customTemplateMap.existsboolfalse
customTemplateMap.namestring"config-map-name"
env[0].namestring"SOME_ENV_KEY"
env[0].valueFrom.secretKeyRef.keystring"some-key"
env[0].valueFrom.secretKeyRef.namestring"some-secret"
env[1].namestring"SMTP_CONFIG"
env[1].valueFrom.secretKeyRef.keystring"smtp-config-key"
env[1].valueFrom.secretKeyRef.namestring"some-secret"
hook.affinityobject{}Optional affinity settings that control how the hook job is scheduled (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)
hook.envlist[]Optional environment variables mapped into the hook (see: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/)
hook.extraVolumeMountslist[]Optional VolumeMounts mapped into the hook (see: https://kubernetes.io/docs/concepts/storage/volumes/)
hook.extraVolumeslist[]Optional Volumes mapped into the hook (see: https://kubernetes.io/docs/concepts/storage/volumes/)
hook.image.pullPolicystring"IfNotPresent"Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
hook.image.repositorystring"docker.io/securecodebox/hook-notification"Hook image repository
hook.image.tagstringdefaults to the charts versionImage tag
hook.labelsobject{}Add Kubernetes Labels to the hook definition
hook.priorityint0Hook priority. Higher priority Hooks are guaranteed to execute before low priority Hooks.
hook.resourcesobject{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }Optional resources lets you control resource limits and requests for the hook container. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
hook.tolerationslist[]Optional tolerations settings that control how the hook job is scheduled (see: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
hook.ttlSecondsAfterFinishedstringnilseconds after which the Kubernetes job for the hook will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/
imagePullSecretslist[]Define imagePullSecrets when a private registry is used (see: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)
notificationChannels[0].endPointstring"SOME_ENV_KEY"
notificationChannels[0].namestring"slack"
notificationChannels[0].rules[0].matches.anyOf[0].categorystring"Open Port"
notificationChannels[0].templatestring"slack-messageCard"
notificationChannels[0].typestring"slack"

License

License

Code of secureCodeBox is licensed under the Apache License 2.0.