Files
timemaster/backend/tests/test_report_security.py
patrickandClaude Sonnet 5.5 a3470a135c
Security Audit / Python Dependency Audit (push) Canceled after 0s
Security Audit / Node.js Dependency Audit (push) Canceled after 0s
Security Audit / Frontend Build (tsc + vite) (push) Canceled after 0s
fix(security): PDF-Export ohne Ressourcenzugriff, HTML-Escaping, CSV/XLSX Formula-Injection
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 23:02:39 +01:00

41 lines
1.3 KiB
Python

"""Härtung der Report-Exporte: PDF-Ressourcenzugriff, HTML-Escaping, Formula-Injection."""
import io
import pytest
from app.services.report_service import _csv_safe, report_service
def test_pdf_blocks_file_attachment(tmp_path):
secret = tmp_path / "secret.txt"
secret.write_text("TOPSECRET-MARKER")
html = f'<html><body><a rel="attachment" href="file://{secret}">x</a></body></html>'
pdf = report_service.to_pdf(html)
assert b"TOPSECRET-MARKER" not in pdf
def test_pdf_blocks_remote_image():
html = '<html><body><img src="http://127.0.0.1:9/x.png"></body></html>'
assert report_service.to_pdf(html).startswith(b"%PDF")
def test_csv_safe_prefixes_formulas_only_for_strings():
assert _csv_safe('=HYPERLINK("http://x")').startswith("'=")
assert _csv_safe("@SUM(A1)").startswith("'@")
assert _csv_safe("+1").startswith("'+")
assert _csv_safe(-2.5) == "-2.5"
assert _csv_safe(None) == ""
assert _csv_safe("Normal") == "Normal"
def test_csv_and_xlsx_neutralize_formulas():
rows = [{"note": "=1+1", "hours": -1.5}]
csv_out = report_service.to_csv(rows)
assert "'=1+1" in csv_out and "-1.5" in csv_out
from openpyxl import load_workbook
wb = load_workbook(io.BytesIO(report_service.to_xlsx(rows)))
cell = wb.active["A2"]
assert cell.data_type != "f"
assert str(cell.value).startswith("'=")