Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CRC validation to Zoom module #35604

Merged
merged 7 commits into from
Jun 1, 2023
Merged
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 .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ CHANGELOG*
/x-pack/filebeat/module/zookeeper @elastic/integrations
/x-pack/filebeat/module/zoom @elastic/security-external-integrations
/x-pack/filebeat/module/zscaler @elastic/security-external-integrations
/x-pack/filebeat/modules.d/zoom.yml.disabled @elastic/security-external-integrations
/x-pack/filebeat/processors/decode_cef/ @elastic/security-external-integrations
/x-pack/heartbeat/ @elastic/uptime
/x-pack/metricbeat/ @elastic/elastic-agent-data-plane
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ automatic splitting at root level, if root level element is an array. {pull}3415
- Add oracle authentication messages parsing {pull}35127[35127]
- Add sanitization capabilities to azure-eventhub input {pull}34874[34874]
- Add support for CRC validation in Filebeat's HTTP endpoint input. {pull}35204[35204]
- Add support for CRC validation in Zoom module. {pull}35604[35604]
- Add execution budget to CEL input. {pull}35409[35409]
- Add XML decoding support to HTTPJSON. {issue}34438[34438] {pull}35235[35235]
- Add delegated account support when using Google ADC in `httpjson` input. {pull}35507[35507]
Expand Down
10 changes: 7 additions & 3 deletions filebeat/docs/modules/zoom.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ include::../include/config-option-intro.asciidoc[]
[float]
==== `webhook` fileset settings

When a webhook integration is created on Zoom, it will show a special token used to ensure that filebeat only handles HTTP requests from the correct source.
When a webhook integration is created on Zoom, you can create a custom header to verify webhook events. See https://developers.zoom.us/docs/api/rest/webhook-reference/#custom-header[Custom Header] for more information about this process.
This is configured with the `secret.header` and `secret.value` settings as shown below.

On the other hand, Zoom also requires webhook validation for created or modified webhooks after October, 2022. This follows a challenge-response check (CRC) algorithm which is configured with the `crc.enabled` and `crc.secret` settings. Learn more about it at https://developers.zoom.us/docs/api/rest/webhook-reference/#validate-your-webhook-endpoint[Validate your webhook endpoint].

Example config:

[source,yaml]
Expand All @@ -42,8 +44,10 @@ Example config:
var.input: http_endpoint
var.listen_address: 0.0.0.0
var.listen_port: 8080
var.secret.header: Authorization
var.secret.value: ZOOMTOKEN
var.secret.header: x-my-custom-key
var.secret.value: my-custom-value
var.crc.enabled: true
var.crc.secret: ZOOMSECRETTOKEN
----

include::../include/var-paths.asciidoc[]
Expand Down
6 changes: 6 additions & 0 deletions x-pack/filebeat/docs/inputs/input-http-endpoint.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Validate webhook endpoint for a specific provider using CRC
secret.header: someheadername
secret.value: secretheadertoken
crc.provider: webhookProvider
crc.secret: secretToken
----

Validate a HMAC signature from a specific header
Expand Down Expand Up @@ -273,6 +274,11 @@ This option copies the raw unmodified body of the incoming request to the event.

This option defines the provider of the webhook that uses CRC (Challenge-Response Check) for validating the endpoint. The HTTP endpoint input is responsible for ensuring the authenticity of incoming webhook requests by generating and verifying a unique token. By specifying the `crc.provider`, you ensure that the system correctly handles the specific CRC validation process required by the chosen provider.

[float]
==== `crc.secret`

The secret token provided by the webhook owner for the CRC validation.
chemamartinez marked this conversation as resolved.
Show resolved Hide resolved

[id="{beatname_lc}-input-{type}-common-options"]
include::../../../../filebeat/docs/inputs/input-common-options.asciidoc[]

Expand Down
10 changes: 8 additions & 2 deletions x-pack/filebeat/filebeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2558,8 +2558,14 @@ filebeat.modules:
# The header Zoom uses to send its secret token, defaults to "Authorization"
#secret.header: Authorization

# The secret token value created by Zoom
#secret.value: ZOOMTOKEN
# The custom secret token value created when configuring the Zoom webhook
#secret.value: my-custom-value

# Enable the CRC webhook validation
#crc.enabled: false

# The secret token value provided by Zoom for CRC validation
#crc.secret: ZOOMSECRETTOKEN

#----------------------------- Zscaler NSS Module -----------------------------
- module: zscaler
Expand Down
8 changes: 6 additions & 2 deletions x-pack/filebeat/input/http_endpoint/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type config struct {
HMACType string `config:"hmac.type"`
HMACPrefix string `config:"hmac.prefix"`
CRCProvider string `config:"crc.provider"`
CRCSecret string `config:"crc.secret"`
IncludeHeaders []string `config:"include_headers"`
PreserveOriginalEvent bool `config:"preserve_original_event"`
}
Expand All @@ -63,6 +64,7 @@ func defaultConfig() config {
HMACType: "",
HMACPrefix: "",
CRCProvider: "",
CRCSecret: "",
}
}

Expand Down Expand Up @@ -92,9 +94,11 @@ func (c *config) Validate() error {
if c.CRCProvider != "" {
if !isValidCRCProvider(c.CRCProvider) {
return fmt.Errorf("not a valid CRC provider: %q", c.CRCProvider)
} else if c.SecretValue == "" {
return errors.New("secret.value is required when crc.provider is defined")
} else if c.CRCSecret == "" {
return errors.New("crc.secret is required when crc.provider is defined")
}
} else if c.CRCSecret != "" {
return errors.New("crc.provider is required when crc.secret is defined")
}

return nil
Expand Down
18 changes: 6 additions & 12 deletions x-pack/filebeat/input/http_endpoint/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,8 @@ func Test_apiResponse(t *testing.T) {
{
name: "validate CRC request",
conf: config{
SecretHeader: "secretHeaderTest",
SecretValue: "secretValueTest",
CRCProvider: "Zoom",
CRCProvider: "Zoom",
CRCSecret: "secretValueTest",
},
request: func() *http.Request {
buf := bytes.NewBufferString(
Expand All @@ -261,7 +260,6 @@ func Test_apiResponse(t *testing.T) {
)
req := httptest.NewRequest(http.MethodPost, "/", buf)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("secretHeaderTest", "secretValueTest")
return req
}(),
events: nil,
Expand All @@ -271,9 +269,8 @@ func Test_apiResponse(t *testing.T) {
{
name: "malformed CRC request",
conf: config{
SecretHeader: "secretHeaderTest",
SecretValue: "secretValueTest",
CRCProvider: "Zoom",
CRCProvider: "Zoom",
CRCSecret: "secretValueTest",
},
request: func() *http.Request {
buf := bytes.NewBufferString(
Expand All @@ -287,7 +284,6 @@ func Test_apiResponse(t *testing.T) {
)
req := httptest.NewRequest(http.MethodPost, "/", buf)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("secretHeaderTest", "secretValueTest")
return req
}(),
events: nil,
Expand All @@ -297,9 +293,8 @@ func Test_apiResponse(t *testing.T) {
{
name: "empty CRC challenge",
conf: config{
SecretHeader: "secretHeaderTest",
SecretValue: "secretValueTest",
CRCProvider: "Zoom",
CRCProvider: "Zoom",
CRCSecret: "secretValueTest",
},
request: func() *http.Request {
buf := bytes.NewBufferString(
Expand All @@ -313,7 +308,6 @@ func Test_apiResponse(t *testing.T) {
)
req := httptest.NewRequest(http.MethodPost, "/", buf)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("secretHeaderTest", "secretValueTest")
return req
}(),
events: nil,
Expand Down
2 changes: 1 addition & 1 deletion x-pack/filebeat/input/http_endpoint/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func newHandler(c config, pub stateless.Publisher, log *logp.Logger) http.Handle
responseBody: c.ResponseBody,
includeHeaders: canonicalizeHeaders(c.IncludeHeaders),
preserveOriginalEvent: c.PreserveOriginalEvent,
crc: newCRC(c.CRCProvider, c.SecretValue),
crc: newCRC(c.CRCProvider, c.CRCSecret),
}

return newAPIValidationHandler(http.HandlerFunc(handler.apiResponse), validator, log)
Expand Down
10 changes: 8 additions & 2 deletions x-pack/filebeat/module/zoom/_meta/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,11 @@
# The header Zoom uses to send its secret token, defaults to "Authorization"
#secret.header: Authorization

# The secret token value created by Zoom
#secret.value: ZOOMTOKEN
# The custom secret token value created when configuring the Zoom webhook
#secret.value: my-custom-value

# Enable the CRC webhook validation
#crc.enabled: false

# The secret token value provided by Zoom for CRC validation
#crc.secret: ZOOMSECRETTOKEN
10 changes: 7 additions & 3 deletions x-pack/filebeat/module/zoom/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ include::../include/config-option-intro.asciidoc[]
[float]
==== `webhook` fileset settings

When a webhook integration is created on Zoom, it will show a special token used to ensure that filebeat only handles HTTP requests from the correct source.
When a webhook integration is created on Zoom, you can create a custom header to verify webhook events. See https://developers.zoom.us/docs/api/rest/webhook-reference/#custom-header[Custom Header] for more information about this process.
This is configured with the `secret.header` and `secret.value` settings as shown below.

On the other hand, Zoom also requires webhook validation for created or modified webhooks after October, 2022. This follows a challenge-response check (CRC) algorithm which is configured with the `crc.enabled` and `crc.secret` settings. Learn more about it at https://developers.zoom.us/docs/api/rest/webhook-reference/#validate-your-webhook-endpoint[Validate your webhook endpoint].

Example config:

[source,yaml]
Expand All @@ -35,8 +37,10 @@ Example config:
var.input: http_endpoint
var.listen_address: 0.0.0.0
var.listen_port: 8080
var.secret.header: Authorization
var.secret.value: ZOOMTOKEN
var.secret.header: x-my-custom-key
var.secret.value: my-custom-value
var.crc.enabled: true
var.crc.secret: ZOOMSECRETTOKEN
----

include::../include/var-paths.asciidoc[]
Expand Down
5 changes: 5 additions & 0 deletions x-pack/filebeat/module/zoom/webhook/config/webhook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ content_type: "{{ .content_type }}"
secret: {{ .secret | tojson }}
ssl: {{ .ssl | tojson }}

{{ if .crc.enabled }}
crc.provider: zoom
crc.secret: {{ .crc.secret }}
{{ end }}

{{ else if eq .input "file" }}

type: log
Expand Down
4 changes: 4 additions & 0 deletions x-pack/filebeat/module/zoom/webhook/manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ var:
default:
header: Authorization
value: ""
- name: crc
default:
enabled: false
secret: ""

- name: tags
default: [zoom-webhook, forwarded]
Expand Down
10 changes: 8 additions & 2 deletions x-pack/filebeat/modules.d/zoom.yml.disabled
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,11 @@
# The header Zoom uses to send its secret token, defaults to "Authorization"
#secret.header: Authorization

# The secret token value created by Zoom
#secret.value: ZOOMTOKEN
# The custom secret token value created when configuring the Zoom webhook
#secret.value: my-custom-value

# Enable the CRC webhook validation
#crc.enabled: false

# The secret token value provided by Zoom for CRC validation
#crc.secret: ZOOMSECRETTOKEN