Webhooks 2 hide secrets (#2104)

Replace password and authorization header fields with placeholders when
returning data to the UI. Mask the authorization header field when
editing and in the status logs.
This commit is contained in:
Michael Derynck 2023-06-06 01:59:12 -06:00 committed by GitHub
parent 889c0afab9
commit bc535ac5df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 6 deletions

View file

@ -4,6 +4,7 @@ from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator
from apps.webhooks.models import Webhook, WebhookResponse
from apps.webhooks.models.webhook import WEBHOOK_FIELD_PLACEHOLDER
from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField
from common.api_helpers.utils import CurrentOrganizationDefault, CurrentTeamDefault, CurrentUserDefault
from common.jinja_templater import apply_jinja_template
@ -66,6 +67,21 @@ class WebhookSerializer(serializers.ModelSerializer):
validators = [UniqueTogetherValidator(queryset=Webhook.objects.all(), fields=["name", "organization"])]
def to_representation(self, instance):
result = super().to_representation(instance)
if instance.password:
result["password"] = WEBHOOK_FIELD_PLACEHOLDER
if instance.authorization_header:
result["authorization_header"] = WEBHOOK_FIELD_PLACEHOLDER
return result
def to_internal_value(self, data):
if data.get("password") == WEBHOOK_FIELD_PLACEHOLDER:
data["password"] = self.instance.password
if data.get("authorization_header") == WEBHOOK_FIELD_PLACEHOLDER:
data["authorization_header"] = self.instance.authorization_header
return super().to_internal_value(data)
def _validate_template_field(self, template):
try:
apply_jinja_template(template, alert_payload=defaultdict(str), alert_group_id="alert_group_1")

View file

@ -10,6 +10,7 @@ from rest_framework.test import APIClient
from apps.api.permissions import LegacyAccessControlRole
from apps.webhooks.models import Webhook
from apps.webhooks.models.webhook import WEBHOOK_FIELD_PLACEHOLDER
TEST_URL = "https://some-url"
@ -44,8 +45,8 @@ def test_get_list_webhooks(webhook_internal_api_setup, make_user_auth_headers):
"url": "https://github.com/",
"data": '{"name": "{{ alert_payload }}"}',
"username": "Chris Vanstras",
"password": "qwerty",
"authorization_header": "auth_token",
"password": WEBHOOK_FIELD_PLACEHOLDER,
"authorization_header": WEBHOOK_FIELD_PLACEHOLDER,
"forward_all": False,
"headers": None,
"http_method": "POST",
@ -85,8 +86,8 @@ def test_get_detail_webhook(webhook_internal_api_setup, make_user_auth_headers):
"url": "https://github.com/",
"data": '{"name": "{{ alert_payload }}"}',
"username": "Chris Vanstras",
"password": "qwerty",
"authorization_header": "auth_token",
"password": WEBHOOK_FIELD_PLACEHOLDER,
"authorization_header": WEBHOOK_FIELD_PLACEHOLDER,
"forward_all": False,
"headers": None,
"http_method": "POST",

View file

@ -23,6 +23,8 @@ from common.jinja_templater import apply_jinja_template
from common.jinja_templater.apply_jinja_template import JinjaTemplateError, JinjaTemplateWarning
from common.public_primary_keys import generate_public_primary_key, increase_public_primary_key_length
WEBHOOK_FIELD_PLACEHOLDER = "****************"
def generate_public_primary_key_for_webhook():
prefix = "WH"

View file

@ -11,6 +11,7 @@ from apps.alerts.models import AlertGroup, AlertGroupLogRecord, EscalationPolicy
from apps.base.models import UserNotificationPolicyLogRecord
from apps.user_management.models import User
from apps.webhooks.models import Webhook, WebhookResponse
from apps.webhooks.models.webhook import WEBHOOK_FIELD_PLACEHOLDER
from apps.webhooks.utils import (
InvalidWebhookData,
InvalidWebhookHeaders,
@ -94,6 +95,12 @@ def _build_payload(webhook, alert_group, user):
return data
def mask_authorization_header(headers):
if "Authorization" in headers:
headers["Authorization"] = WEBHOOK_FIELD_PLACEHOLDER
return headers
def make_request(webhook, alert_group, data):
status = {
"url": None,
@ -115,7 +122,8 @@ def make_request(webhook, alert_group, data):
if triggered:
status["url"] = webhook.build_url(data)
request_kwargs = webhook.build_request_kwargs(data, raise_data_errors=True)
status["request_headers"] = json.dumps(request_kwargs.get("headers", {}))
headers = mask_authorization_header(request_kwargs.get("headers", {}))
status["request_headers"] = json.dumps(headers)
if "json" in request_kwargs:
status["request_data"] = json.dumps(request_kwargs["json"])
else:

View file

@ -161,7 +161,7 @@ export const form: { name: string; fields: FormItem[] } = {
},
{
name: 'authorization_header',
type: FormItemType.Input,
type: FormItemType.Password,
},
{
name: 'trigger_template',