mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 15:21:30 +02:00
Uploaded typefaces and instance-wide branding defaults, which together make a report genuinely white-labellable: a client's own font, a logo set once, and a theme that names both. The security half came first, because the logo field was a live SSRF. It was a free-text string rendered into an <img src>, and WeasyPrint would have fetched whatever it pointed at from inside the worker. Nothing fetches now, at four layers. The load-bearing one is a WeasyPrint url_fetcher that allows data: URIs and files under three known roots and refuses everything else; it was checked against cloud metadata, internal https, loopback, /etc/passwd, a UNC host, ftp and protocol-relative references. Above it sit three input guards: a logo must be embedded data of a known image type, an uploaded theme may not use @import or a url() that is not data:, and authored markdown loses any image that is not embedded. A new feature that lets a report name a resource goes through the fetcher, not around it. A typeface is bytes, never a link. The family row records files named by us, so a hostile filename never reaches disk, and the family directory refuses anything resolving outside itself. A face is accepted only when the bytes agree: the signature is sniffed and then fontTools opens it and requires outlines, which is why fonttools is now an api dependency rather than only a WeasyPrint one. A 5-byte file with a valid TTF header and a 4 KB file of padding are both refused. The family name is banned from carrying quotes or braces because it is written into a quoted CSS font-family string. The standalone HTML export now embeds only the families the theme actually names, which halves it, and no longer carries file:// references that would have been dead outside the container. Instance defaults fill only what a template leaves blank, so setting a logo once never overrides a per-client deliverable that set its own. Verified: a real TTF family uploaded and embedded in a 53-page PDF under an uploaded theme with an uploaded logo, and every probe above refused. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f2Mf2HGwFaTRnui4UxpRd
33 lines
789 B
TOML
33 lines
789 B
TOML
[project]
|
|
name = "rengine-api"
|
|
version = "3.0.0"
|
|
description = "reNgine: FastAPI backend"
|
|
requires-python = ">=3.13"
|
|
dependencies = [
|
|
"alembic>=1.18.3",
|
|
"anthropic>=0.69.0",
|
|
"apprise>=1.9.0",
|
|
"argon2-cffi>=25.1.0",
|
|
"asyncpg>=0.31.0",
|
|
"brotli>=1.1.0",
|
|
"fonttools>=4.59.2",
|
|
"celery>=5.6.2",
|
|
"cryptography>=42",
|
|
"fastapi>=0.128.0",
|
|
"fastapi-pagination>=0.15.8",
|
|
"passlib[bcrypt]>=1.7.4",
|
|
"pydantic-settings>=2.12.0",
|
|
"pyotp>=2.9.0",
|
|
"python-jose>=3.5.0",
|
|
"python-multipart>=0.0.22",
|
|
"qrcode[pil]>=7.4.2",
|
|
"redis>=7.1.0",
|
|
"sqlmodel>=0.0.31",
|
|
"uvicorn>=0.40.0",
|
|
"validators>=0.35.0",
|
|
"pyyaml>=6.0",
|
|
"zxcvbn>=4.5.0",
|
|
"rengine-shared @ file:///app/shared",
|
|
"rengine-tools @ file:///app/tools",
|
|
]
|