mirror of
https://github.com/lnbits/lnbits.git
synced 2025-05-30 01:29:30 +02:00
fix: allow ports for domains (#3171)
This commit is contained in:
parent
5345ccaf4e
commit
375b95c004
@ -11,6 +11,7 @@ import jinja2
|
||||
import jwt
|
||||
import shortuuid
|
||||
from fastapi.routing import APIRoute
|
||||
from loguru import logger
|
||||
from packaging import version
|
||||
from pydantic.schema import field_schema
|
||||
|
||||
@ -279,12 +280,21 @@ def is_lnbits_version_ok(
|
||||
|
||||
|
||||
def check_callback_url(url: str):
|
||||
netloc = urlparse(url).netloc
|
||||
if not settings.lnbits_callback_url_rules:
|
||||
# no rules, all urls are allowed
|
||||
return
|
||||
u = urlparse(url)
|
||||
for rule in settings.lnbits_callback_url_rules:
|
||||
if re.match(rule, netloc) is None:
|
||||
raise ValueError(
|
||||
f"Callback not allowed. URL: {url}. Netloc: {netloc}. Rule: {rule}"
|
||||
)
|
||||
try:
|
||||
if re.match(rule, f"{u.scheme}://{u.netloc}") is not None:
|
||||
return
|
||||
except re.error:
|
||||
logger.debug(f"Invalid regex rule: '{rule}'. ")
|
||||
continue
|
||||
raise ValueError(
|
||||
f"Callback not allowed. URL: {url}. Netloc: {u.netloc}. "
|
||||
f"Please check your admin settings."
|
||||
)
|
||||
|
||||
|
||||
def download_url(url, save_path):
|
||||
|
@ -381,7 +381,7 @@ class SecuritySettings(LNbitsSettings):
|
||||
lnbits_allowed_ips: list[str] = Field(default=[])
|
||||
lnbits_blocked_ips: list[str] = Field(default=[])
|
||||
lnbits_callback_url_rules: list[str] = Field(
|
||||
default=["^(?!\\d+\\.\\d+\\.\\d+\\.\\d+$)(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$"]
|
||||
default=["https?://([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})(:\\d+)?"]
|
||||
)
|
||||
|
||||
lnbits_wallet_limit_max_balance: int = Field(default=0, ge=0)
|
||||
|
2
lnbits/static/bundle.min.js
vendored
2
lnbits/static/bundle.min.js
vendored
File diff suppressed because one or more lines are too long
@ -278,7 +278,7 @@ window.localisation.en = {
|
||||
callback_url_rules: 'Callback URL Rules',
|
||||
enter_callback_url_rule: 'Enter URL rule as regex and hit enter',
|
||||
callback_url_rule_hint:
|
||||
'Callback URLs (like LNURL one) will be validated against all of these rules. No rule means all URLs are allowed.',
|
||||
'Callback URLs (like LNURL one) will be validated against these rules. At leat one rule must match. No rule means all URLs are allowed.',
|
||||
wallet_limiter: 'Wallet Limiter',
|
||||
wallet_config: 'Wallet Config',
|
||||
wallet_charts: 'Wallet Charts',
|
||||
|
84
tests/unit/test_helpers.py
Normal file
84
tests/unit/test_helpers.py
Normal file
@ -0,0 +1,84 @@
|
||||
import pytest
|
||||
|
||||
from lnbits.helpers import check_callback_url
|
||||
from lnbits.settings import Settings
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
def test_check_callback_url_not_allowed(settings: Settings):
|
||||
settings.lnbits_callback_url_rules = [
|
||||
"https?://([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})(:\\d+)?"
|
||||
]
|
||||
with pytest.raises(ValueError, match="Callback not allowed. URL: xx. Netloc: ."):
|
||||
check_callback_url("xx")
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="Callback not allowed. URL: http://localhost:3000/callback. "
|
||||
"Netloc: localhost:3000. Please check your admin settings.",
|
||||
):
|
||||
check_callback_url("http://localhost:3000/callback")
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="Callback not allowed. URL: https://localhost:3000/callback. "
|
||||
"Netloc: localhost:3000. Please check your admin settings.",
|
||||
):
|
||||
check_callback_url("https://localhost:3000/callback")
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="Callback not allowed. URL: http://192.168.2.2:3000/callback. "
|
||||
"Netloc: 192.168.2.2:3000. Please check your admin settings.",
|
||||
):
|
||||
check_callback_url("http://192.168.2.2:3000/callback")
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
def test_check_callback_url_no_rules(settings: Settings):
|
||||
settings.lnbits_callback_url_rules = [
|
||||
"https?://([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})(:\\d+)?"
|
||||
]
|
||||
settings.lnbits_callback_url_rules.append(".*")
|
||||
check_callback_url("xyz")
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
def test_check_callback_url_allow_all(settings: Settings):
|
||||
settings.lnbits_callback_url_rules = []
|
||||
check_callback_url("xyz")
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
def test_check_callback_url_allowed(settings: Settings):
|
||||
settings.lnbits_callback_url_rules = [
|
||||
"https?://([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})(:\\d+)?"
|
||||
]
|
||||
check_callback_url("http://google.com/callback")
|
||||
check_callback_url("http://google.com:80/callback")
|
||||
check_callback_url("http://google.com:8080/callback")
|
||||
check_callback_url("https://google.com/callback")
|
||||
check_callback_url("https://google.com:443/callback")
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
def test_check_callback_url_multiple_rules(settings: Settings):
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="Callback not allowed. URL: http://localhost:3000/callback. "
|
||||
"Netloc: localhost:3000. Please check your admin settings.",
|
||||
):
|
||||
check_callback_url("http://localhost:3000/callback")
|
||||
|
||||
settings.lnbits_callback_url_rules.append("http://localhost:3000")
|
||||
check_callback_url("http://localhost:3000/callback") # should not raise
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="Callback not allowed. URL: https://localhost:3000/callback. "
|
||||
"Netloc: localhost:3000. Please check your admin settings.",
|
||||
):
|
||||
check_callback_url("https://localhost:3000/callback")
|
||||
|
||||
settings.lnbits_callback_url_rules.append("https://localhost:3000")
|
||||
check_callback_url("https://localhost:3000/callback") # should not raise
|
Loading…
x
Reference in New Issue
Block a user