security: fix #6 — escape source via build_source_html in InfoPanel
Replaces the inline f-string concatenation of post.source into the RichText document with a call through build_source_html(), which escapes both the href value and the visible display text. Also escapes the filetype field for defense-in-depth — the value comes from a parsed URL suffix (effectively booru-controlled) and the previous code interpolated it raw. Removes the dead duplicate setText() call that wrote a plain-text version before being overwritten by the RichText version on the next line. Audit-Ref: SECURITY_AUDIT.md finding #6 Severity: Medium
This commit is contained in:
parent
fa4f2cb270
commit
b8cb47badb
@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from html import escape
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtCore import Qt, Property, Signal
|
||||
@ -12,6 +13,7 @@ from PySide6.QtWidgets import (
|
||||
)
|
||||
|
||||
from ..core.api.base import Post
|
||||
from ._source_html import build_source_html
|
||||
|
||||
log = logging.getLogger("booru")
|
||||
|
||||
@ -115,28 +117,12 @@ class InfoPanel(QWidget):
|
||||
log.debug(f"InfoPanel: tag_categories={list(post.tag_categories.keys()) if post.tag_categories else 'empty'}")
|
||||
self._title.setText(f"Post #{post.id}")
|
||||
filetype = Path(post.file_url.split("?")[0]).suffix.lstrip(".").upper() if post.file_url else "unknown"
|
||||
source = post.source or "none"
|
||||
# Truncate display text but keep full URL for the link
|
||||
source_full = source
|
||||
if len(source) > 60:
|
||||
source_display = source[:57] + "..."
|
||||
else:
|
||||
source_display = source
|
||||
if source_full.startswith(("http://", "https://")):
|
||||
source_html = f'<a href="{source_full}" style="color: #4fc3f7;">{source_display}</a>'
|
||||
else:
|
||||
source_html = source_display
|
||||
from html import escape
|
||||
self._details.setText(
|
||||
f"Score: {post.score}\n"
|
||||
f"Rating: {post.rating or 'unknown'}\n"
|
||||
f"Filetype: {filetype}"
|
||||
)
|
||||
source_html = build_source_html(post.source)
|
||||
self._details.setTextFormat(Qt.TextFormat.RichText)
|
||||
self._details.setText(
|
||||
f"Score: {post.score}<br>"
|
||||
f"Rating: {escape(post.rating or 'unknown')}<br>"
|
||||
f"Filetype: {filetype}<br>"
|
||||
f"Filetype: {escape(filetype)}<br>"
|
||||
f"Source: {source_html}"
|
||||
)
|
||||
self._details.setOpenExternalLinks(True)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user