-
Notifications
You must be signed in to change notification settings - Fork 17.6k
fix(network): validate target hostname in outbound requests #39301
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
base: master
Are you sure you want to change the base?
Changes from all commits
ec17725
7e886c6
6f9f625
dfb304f
74a0dda
7484965
8d120df
0c20ccf
de45255
5f87da9
273fe1a
976afcf
088c4f9
595dd90
c7b171f
0fd906c
9abe2bd
dd11b33
9dcd493
fdc321e
4624529
45d3662
da0b1d1
04d042e
7308d1b
0223c3b
1cef64d
d1749ad
52c4183
4cc423b
5292ade
1a4d5fb
3404c6a
90ee4f2
d3f0056
1931bde
5cc649f
0276baa
a1acb35
9cd1469
dc432ab
7f7d38e
1588f0b
001bfec
2d71687
27c6c2b
9502e57
2d95767
4028da4
2584416
b34c46b
48fba47
7f0659f
ee3ea54
ced9de7
6d4b079
23c49c5
7e1061b
181c06e
0221ce0
6b8b794
8d4ed5a
966b9e1
b96f599
136c920
3e90541
97af811
3d986ae
377d000
2d431d5
4396139
4e0ac11
83a9f76
fbe4927
313334c
2e7e54d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,7 @@ | |
| ) | ||
| from superset.utils import json | ||
| from superset.utils.decorators import statsd_gauge | ||
| from superset.utils.network import is_safe_host | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
@@ -93,6 +94,31 @@ def _get_files(self) -> list[tuple[str, tuple[str, bytes, str]]]: | |
| ) | ||
| return files | ||
|
|
||
| def _validate_webhook_url(self, url: str) -> None: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Add an inline docstring to this newly introduced method describing what it validates and which exceptions it raises. [custom_rule] Severity Level: Minor Why it matters? 🤔This is a newly introduced Python method and it has no docstring in the final file state. Fix in Cursor | Fix in VSCode Claude (Use Cmd/Ctrl + Click for best experience) Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** superset/reports/notifications/webhook.py
**Line:** 97:97
**Comment:**
*Custom Rule: Add an inline docstring to this newly introduced method describing what it validates and which exceptions it raises.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix |
||
| parsed = urlparse(url) | ||
| if parsed.scheme.lower() not in ("http", "https"): | ||
| raise NotificationParamException( | ||
| "Webhook failed: only HTTP and HTTPS webhook URLs are supported." | ||
| ) | ||
| if ( | ||
| current_app.config["ALERT_REPORTS_WEBHOOK_HTTPS_ONLY"] | ||
| and parsed.scheme.lower() != "https" | ||
| ): | ||
| raise NotificationParamException( | ||
| "Webhook failed: HTTPS is required by config for webhook URLs." | ||
| ) | ||
| if not parsed.hostname: | ||
| raise NotificationParamException( | ||
| "Webhook failed: URL must include a valid hostname." | ||
| ) | ||
| # Operators with internal webhook targets (chatops bridges, internal | ||
| # automation, etc.) can opt out of the private-IP block via | ||
| # ALERT_REPORTS_WEBHOOK_ALLOW_INTERNAL_HOSTS. | ||
| if current_app.config["ALERT_REPORTS_WEBHOOK_ALLOW_INTERNAL_HOSTS"]: | ||
| return | ||
| if not is_safe_host(parsed.hostname): | ||
| raise NotificationParamException("Webhook URL target host is not allowed.") | ||
|
|
||
| @backoff.on_exception( | ||
| backoff.expo, NotificationUnprocessableException, factor=10, base=2, max_tries=5 | ||
| ) | ||
|
|
@@ -104,11 +130,7 @@ def send(self) -> None: | |
| is not enabled." | ||
| ) | ||
| wh_url = self._get_webhook_url() | ||
| if current_app.config["ALERT_REPORTS_WEBHOOK_HTTPS_ONLY"]: | ||
| if urlparse(wh_url).scheme.lower() != "https": | ||
| raise NotificationParamException( | ||
| "Webhook failed: HTTPS is required by config for webhook URLs." | ||
| ) | ||
| self._validate_webhook_url(wh_url) | ||
| payload = self._get_req_payload() | ||
| files = self._get_files() | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.