Skip to content

Commit

Permalink
Increase max webhook length and add backend length check
Browse files Browse the repository at this point in the history
  • Loading branch information
gjcthinkst committed Feb 5, 2024
1 parent 9c1478b commit 0b9a20f
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 3 deletions.
2 changes: 2 additions & 0 deletions canarytokens/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@
MAILGUN_IGNORE_ERRORS = [
"to parameter is not a valid address. please check documentation"
]

MAX_WEBHOOK_URL_LENGTH = 1024
9 changes: 8 additions & 1 deletion canarytokens/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from twisted.logger import Logger

from canarytokens import canarydrop as cand
from canarytokens import models, tokens
from canarytokens import models, tokens, constants
from canarytokens.exceptions import CanarydropAuthFailure, NoCanarydropFound
from canarytokens.redismanager import ( # KEY_BITCOIN_ACCOUNT,; KEY_BITCOIN_ACCOUNTS,; KEY_CANARY_NXDOMAINS,; KEY_CANARYTOKEN_ALERT_COUNT,; KEY_CLONEDSITE_TOKEN,; KEY_CLONEDSITE_TOKENS,; KEY_IMGUR_TOKEN,; KEY_IMGUR_TOKENS,; KEY_KUBECONFIG_CERTS,; KEY_KUBECONFIG_HITS,; KEY_KUBECONFIG_SERVEREP,; KEY_LINKEDIN_ACCOUNT,; KEY_LINKEDIN_ACCOUNTS,; KEY_USER_ACCOUNT,
DB,
Expand Down Expand Up @@ -797,11 +797,18 @@ def add_canary_google_api_key(key: str) -> int:
# return key


class WebhookTooLongError(Exception):
pass


def validate_webhook(url, token_type: models.TokenTypes):
"""Tests if a webhook is valid by sending a test payload
Arguments:
url -- Webhook url
"""
if len(url) > constants.MAX_WEBHOOK_URL_LENGTH:
raise WebhookTooLongError()

slack = "https://hooks.slack.com"
googlechat_hook_base_url = "https://chat.googleapis.com"
discord = "https://discord.com/api/webhooks"
Expand Down
3 changes: 3 additions & 0 deletions frontend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
remove_canary_domain,
save_canarydrop,
validate_webhook,
WebhookTooLongError,
)
from canarytokens.redismanager import DB
from canarytokens.settings import FrontendSettings, SwitchboardSettings
Expand Down Expand Up @@ -347,6 +348,8 @@ async def generate(request: Request) -> AnyTokenResponse: # noqa: C901 # gen i
validate_webhook(
token_request_details.webhook_url, token_request_details.token_type
)
except WebhookTooLongError:
return response_error(3, "Webhook URL too long. Use a shorter webhook URL.")
except requests.exceptions.HTTPError:
return response_error(
3, "Invalid webhook supplied. Confirm you can POST to this URL."
Expand Down
2 changes: 1 addition & 1 deletion templates/generate_new.html
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,7 @@ <h3>Your log4shell token is active!</h3>
if (endpoints.val().length == 0) {
return endpoints.addClass('error-outline').removeClass('success-outline');
}
if (endpoints.val().length > 255) {
if (endpoints.val().length > 1024) {
return endpoints.addClass('error-outline').removeClass('success-outline');
}
endpoints_components = endpoints.val().split(' ');
Expand Down
14 changes: 13 additions & 1 deletion tests/units/test_frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from fastapi.testclient import TestClient
from pydantic import HttpUrl

from canarytokens import canarydrop, models, queries
from canarytokens import canarydrop, models, queries, constants
from canarytokens.models import (
AnyDownloadRequest,
AnyTokenRequest,
Expand Down Expand Up @@ -91,6 +91,18 @@ def test_generate_dns_token(test_client: TestClient) -> None:
assert resp.status_code == 200


def test_reject_webhook_too_long(test_client: TestClient) -> None:
url_suffix = "a" * constants.MAX_WEBHOOK_URL_LENGTH
dns_request_token = models.DNSTokenRequest(
token_type=TokenTypes.DNS,
email="test@test.com",
webhook_url=f"https://slack.com/api/{url_suffix}",
memo="test stuff break stuff fix stuff test stuff",
)
resp = test_client.post("/generate", json=json.loads(dns_request_token.json()))
assert resp.status_code == 400


def test_generate_log4shell_token(test_client: TestClient) -> None:
log4shell_request_token = models.Log4ShellTokenRequest(
email="test@test.com",
Expand Down

0 comments on commit 0b9a20f

Please sign in to comment.