r3gm commited on
Commit
f769a93
·
verified ·
1 Parent(s): 2f6da1c

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +13 -15
utils.py CHANGED
@@ -30,7 +30,7 @@ from urllib3.util import Retry
30
  import shutil
31
  import subprocess
32
  import json
33
- import html as _html
34
 
35
  IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
36
  USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
@@ -42,32 +42,32 @@ MODEL_ARCH = {
42
 
43
 
44
  def validate_url(url: str) -> str:
45
- """Validate URL protocol and block SSRF (localhost, private & cloud metadata IPs)."""
46
  url = url.strip()
47
  if not url:
48
  raise ValueError("URL cannot be empty.")
49
 
50
  parsed = urllib.parse.urlparse(url)
51
- if parsed.scheme not in ("http", "https"):
52
- raise ValueError(f"Invalid protocol '{parsed.scheme}'. Only HTTP/HTTPS are allowed.")
53
 
54
  hostname = (parsed.hostname or "").lower()
55
  if not hostname:
56
  raise ValueError("Invalid URL: missing hostname.")
57
 
58
- # SSRF Protection: Block loopback and local hosts
59
  if hostname in ("localhost", "0.0.0.0", "127.0.0.1", "::1"):
60
- raise ValueError("Access to local/loopback address is blocked.")
61
 
62
- # SSRF Protection: Block private and link-local / cloud metadata IPs (e.g. 169.254.169.254)
63
  try:
64
  ip = ipaddress.ip_address(hostname)
65
  if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
66
- raise ValueError(f"Access to internal IP ({hostname}) is blocked.")
67
  except ValueError:
68
  pass # Standard domain name
69
 
70
- # Normalize Civitai domain alias
71
  if hostname == "civitai.red" or hostname.endswith(".civitai.red"):
72
  url = url.replace("civitai.red", "civitai.com")
73
 
@@ -180,9 +180,6 @@ class LoraHeaderInformation:
180
  Return a compact HTML snippet (string) showing the parsed info
181
  in a small font. Values are HTML-escaped.
182
  """
183
- # helper to escape
184
- esc = _html.escape
185
-
186
  rows = [
187
  ("Title", esc(str(self.title))),
188
  ("Author", esc(str(self.author))),
@@ -415,7 +412,6 @@ def download_things(directory, url, hf_token="", civitai_api_key="", romanize=Fa
415
  if not url:
416
  return None
417
 
418
- # SSRF & protocol validation
419
  try:
420
  url = validate_url(url)
421
  except Exception as e:
@@ -531,7 +527,7 @@ def get_my_lora(link_url, romanize):
531
  new_lora_model_list = new_lora_model_list + DIFFUSERS_FORMAT_LORAS
532
  msg_lora = "Downloaded"
533
  if l_name:
534
- msg_lora += f": <b>{l_name}</b>"
535
  print(msg_lora)
536
 
537
  try:
@@ -776,4 +772,6 @@ def html_template_message(msg):
776
 
777
  def escape_html(text):
778
  """Escapes HTML special characters in the input text."""
779
- return text.replace("<", "&lt;").replace(">", "&gt;").replace("\n", "<br>")
 
 
 
30
  import shutil
31
  import subprocess
32
  import json
33
+ from html import escape as esc
34
 
35
  IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
36
  USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
 
42
 
43
 
44
  def validate_url(url: str) -> str:
45
+ """Validate URL protocol and host."""
46
  url = url.strip()
47
  if not url:
48
  raise ValueError("URL cannot be empty.")
49
 
50
  parsed = urllib.parse.urlparse(url)
51
+ if parsed.scheme != "https":
52
+ raise ValueError(f"Invalid protocol '{parsed.scheme}'. Only HTTPS is allowed.")
53
 
54
  hostname = (parsed.hostname or "").lower()
55
  if not hostname:
56
  raise ValueError("Invalid URL: missing hostname.")
57
 
58
+ # Restrict local and internal endpoints
59
  if hostname in ("localhost", "0.0.0.0", "127.0.0.1", "::1"):
60
+ raise ValueError("Restricted address.")
61
 
62
+ # Restrict private IP addresses
63
  try:
64
  ip = ipaddress.ip_address(hostname)
65
  if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
66
+ raise ValueError(f"Access to ({hostname}) is blocked.")
67
  except ValueError:
68
  pass # Standard domain name
69
 
70
+ # Normalize domain alias
71
  if hostname == "civitai.red" or hostname.endswith(".civitai.red"):
72
  url = url.replace("civitai.red", "civitai.com")
73
 
 
180
  Return a compact HTML snippet (string) showing the parsed info
181
  in a small font. Values are HTML-escaped.
182
  """
 
 
 
183
  rows = [
184
  ("Title", esc(str(self.title))),
185
  ("Author", esc(str(self.author))),
 
412
  if not url:
413
  return None
414
 
 
415
  try:
416
  url = validate_url(url)
417
  except Exception as e:
 
527
  new_lora_model_list = new_lora_model_list + DIFFUSERS_FORMAT_LORAS
528
  msg_lora = "Downloaded"
529
  if l_name:
530
+ msg_lora += f": <b>{escape_html(os.path.basename(l_name))}</b>"
531
  print(msg_lora)
532
 
533
  try:
 
772
 
773
  def escape_html(text):
774
  """Escapes HTML special characters in the input text."""
775
+ if text is None:
776
+ return ""
777
+ return esc(str(text), quote=True).replace("\n", "<br>")