mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 23:31:31 +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
324 lines
7.2 KiB
Python
324 lines
7.2 KiB
Python
import shared.models._tztypes # patch datetime->timestamptz first
|
|
from shared.models.activity_log import ActivityLog, ActivityLogRead
|
|
from shared.models.ai import AiNarrative
|
|
from shared.models.api_key import (
|
|
APIKey,
|
|
APIKeyCreate,
|
|
APIKeyRead,
|
|
APIKeyUpdate,
|
|
ProviderInfo,
|
|
)
|
|
from shared.models.dns import (
|
|
DnsLookup,
|
|
DnsLookupRead,
|
|
DnsLookupSummary,
|
|
DnsRecord,
|
|
DnsRecordRead,
|
|
)
|
|
from shared.models.endpoint import (
|
|
Endpoint,
|
|
EndpointCoverage,
|
|
EndpointDetail,
|
|
EndpointFacets,
|
|
EndpointFilter,
|
|
EndpointPage,
|
|
EndpointRead,
|
|
EndpointSummary,
|
|
EndpointTree,
|
|
TreeNode,
|
|
)
|
|
from shared.models.http_asset import (
|
|
HttpAsset,
|
|
HttpAssetRead,
|
|
HttpAssetSummary,
|
|
)
|
|
from shared.models.instance_settings import (
|
|
InstanceSettings,
|
|
InstanceSettingsRead,
|
|
InstanceSettingsUpdate,
|
|
)
|
|
from shared.models.ip_address import (
|
|
IpAddress,
|
|
IpAddressRead,
|
|
IpAddressSummary,
|
|
TargetIpAddressRead,
|
|
)
|
|
from shared.models.ip_asn_range import IpAsnRange, IpCountryRange
|
|
from shared.models.notification import (
|
|
Notification,
|
|
NotificationCreate,
|
|
NotificationRead,
|
|
)
|
|
from shared.models.notification_channel import (
|
|
NotificationChannel,
|
|
NotificationChannelCreate,
|
|
NotificationChannelRead,
|
|
NotificationChannelTestResult,
|
|
NotificationChannelUpdate,
|
|
NotificationPreference,
|
|
)
|
|
from shared.models.organization import (
|
|
Organization,
|
|
OrganizationCreate,
|
|
OrganizationRead,
|
|
OrganizationSummary,
|
|
OrganizationUpdate,
|
|
)
|
|
from shared.models.port import Port, PortRead, PortSummary
|
|
from shared.models.project import Project, ProjectBase, ProjectCreate, ProjectRead
|
|
from shared.models.proxy import (
|
|
Proxy,
|
|
ProxyCreate,
|
|
ProxyEndpoint,
|
|
ProxyEndpointRead,
|
|
ProxyRead,
|
|
ProxyTestResult,
|
|
ProxyUpdate,
|
|
)
|
|
from shared.models.report import Report, ReportFont, ReportTemplate, ReportTheme
|
|
from shared.models.ripestat import (
|
|
RIPEStatAbuseContact,
|
|
RIPEStatAnnouncedPrefix,
|
|
RIPEStatASNNeighbour,
|
|
RIPEStatASOverview,
|
|
RIPEStatNetworkInfo,
|
|
RIPEStatPrefixOverview,
|
|
RIPEStatRelatedPrefix,
|
|
)
|
|
from shared.models.scan import (
|
|
Scan,
|
|
ScanCreate,
|
|
ScanRead,
|
|
)
|
|
from shared.models.scan_activity import ScanActivity, ScanActivityRead
|
|
from shared.models.scan_command import (
|
|
ScanCommand,
|
|
ScanCommandDetail,
|
|
ScanCommandRead,
|
|
)
|
|
from shared.models.scan_context import (
|
|
AuthConfig,
|
|
AuthHeader,
|
|
ScanContext,
|
|
ScanContextCreate,
|
|
ScanContextRead,
|
|
ScanContextUpdate,
|
|
)
|
|
from shared.models.scan_engine import (
|
|
EngineCatalog,
|
|
ScanEngine,
|
|
ScanEngineCreate,
|
|
ScanEngineRead,
|
|
ScanEngineUpdate,
|
|
)
|
|
from shared.models.scan_schedule import (
|
|
ScanSchedule,
|
|
ScanScheduleCreate,
|
|
ScanScheduleRead,
|
|
ScanScheduleUpdate,
|
|
ScheduleTargetRef,
|
|
)
|
|
from shared.models.subdomain import (
|
|
Subdomain,
|
|
SubdomainRead,
|
|
SubdomainSummary,
|
|
TargetSubdomainRead,
|
|
)
|
|
from shared.models.tag import Tag, TagBase, TagCreate, TagRead, TagSummary, TagUpdate
|
|
from shared.models.target import (
|
|
Target,
|
|
TargetBulkCreate,
|
|
TargetBulkCreateResponse,
|
|
TargetCreate,
|
|
TargetImportItem,
|
|
TargetImportRequest,
|
|
TargetImportResult,
|
|
TargetRead,
|
|
TargetType,
|
|
TargetUpdate,
|
|
TargetValidationRequest,
|
|
TargetValidationResponse,
|
|
)
|
|
from shared.models.user import User, UserBase, UserCreate, UserRead
|
|
from shared.models.viewdns import ViewDNSCache
|
|
from shared.models.vuln_template import (
|
|
TemplateFilter,
|
|
TemplateLibraryStats,
|
|
TemplatePage,
|
|
TemplateSelection,
|
|
VulnTemplate,
|
|
VulnTemplateRead,
|
|
VulnTemplateUpdate,
|
|
VulnTemplateUploadRequest,
|
|
)
|
|
from shared.models.vulnerability import (
|
|
ScanVulnerabilities,
|
|
Vulnerability,
|
|
VulnerabilityCoverage,
|
|
VulnerabilityFacets,
|
|
VulnerabilityFilter,
|
|
VulnerabilityPage,
|
|
VulnerabilityRead,
|
|
VulnerabilityTriage,
|
|
)
|
|
from shared.models.wordlist import (
|
|
Wordlist,
|
|
WordlistFile,
|
|
WordlistRead,
|
|
WordlistUpdate,
|
|
WordlistUploadRequest,
|
|
WordlistUploadResult,
|
|
)
|
|
|
|
TargetRead.model_rebuild()
|
|
|
|
__all__ = [
|
|
"APIKey",
|
|
"APIKeyCreate",
|
|
"APIKeyRead",
|
|
"APIKeyUpdate",
|
|
"ActivityLog",
|
|
"ActivityLogRead",
|
|
"AiNarrative",
|
|
"AuthConfig",
|
|
"AuthHeader",
|
|
"DnsLookup",
|
|
"DnsLookupRead",
|
|
"DnsLookupSummary",
|
|
"DnsRecord",
|
|
"DnsRecordRead",
|
|
"Endpoint",
|
|
"EndpointCoverage",
|
|
"EndpointDetail",
|
|
"EndpointFacets",
|
|
"EndpointFilter",
|
|
"EndpointPage",
|
|
"EndpointRead",
|
|
"EndpointSummary",
|
|
"EndpointTree",
|
|
"EngineCatalog",
|
|
"HttpAsset",
|
|
"HttpAssetRead",
|
|
"HttpAssetSummary",
|
|
"InstanceSettings",
|
|
"InstanceSettingsRead",
|
|
"InstanceSettingsUpdate",
|
|
"IpAddress",
|
|
"IpAddressRead",
|
|
"IpAddressSummary",
|
|
"IpAsnRange",
|
|
"IpCountryRange",
|
|
"Notification",
|
|
"NotificationChannel",
|
|
"NotificationChannelCreate",
|
|
"NotificationChannelRead",
|
|
"NotificationChannelTestResult",
|
|
"NotificationChannelUpdate",
|
|
"NotificationCreate",
|
|
"NotificationPreference",
|
|
"NotificationRead",
|
|
"Organization",
|
|
"OrganizationCreate",
|
|
"OrganizationRead",
|
|
"OrganizationSummary",
|
|
"OrganizationUpdate",
|
|
"Port",
|
|
"PortRead",
|
|
"PortSummary",
|
|
"Project",
|
|
"ProjectBase",
|
|
"ProjectCreate",
|
|
"ProjectRead",
|
|
"ProviderInfo",
|
|
"Proxy",
|
|
"ProxyCreate",
|
|
"ProxyEndpoint",
|
|
"ProxyEndpointRead",
|
|
"ProxyRead",
|
|
"ProxyTestResult",
|
|
"ProxyUpdate",
|
|
"RIPEStatASNNeighbour",
|
|
"RIPEStatASOverview",
|
|
"RIPEStatAbuseContact",
|
|
"RIPEStatAnnouncedPrefix",
|
|
"RIPEStatNetworkInfo",
|
|
"RIPEStatPrefixOverview",
|
|
"RIPEStatRelatedPrefix",
|
|
"Report",
|
|
"ReportFont",
|
|
"ReportTemplate",
|
|
"ReportTheme",
|
|
"Scan",
|
|
"ScanActivity",
|
|
"ScanActivityRead",
|
|
"ScanCommand",
|
|
"ScanCommandDetail",
|
|
"ScanCommandRead",
|
|
"ScanContext",
|
|
"ScanContextCreate",
|
|
"ScanContextRead",
|
|
"ScanContextUpdate",
|
|
"ScanCreate",
|
|
"ScanEngine",
|
|
"ScanEngineCreate",
|
|
"ScanEngineRead",
|
|
"ScanEngineUpdate",
|
|
"ScanRead",
|
|
"ScanSchedule",
|
|
"ScanScheduleCreate",
|
|
"ScanScheduleRead",
|
|
"ScanScheduleUpdate",
|
|
"ScanVulnerabilities",
|
|
"ScheduleTargetRef",
|
|
"Subdomain",
|
|
"SubdomainRead",
|
|
"SubdomainSummary",
|
|
"Tag",
|
|
"TagBase",
|
|
"TagCreate",
|
|
"TagRead",
|
|
"TagSummary",
|
|
"TagUpdate",
|
|
"Target",
|
|
"TargetBulkCreate",
|
|
"TargetBulkCreateResponse",
|
|
"TargetCreate",
|
|
"TargetImportItem",
|
|
"TargetImportRequest",
|
|
"TargetImportResult",
|
|
"TargetIpAddressRead",
|
|
"TargetRead",
|
|
"TargetSubdomainRead",
|
|
"TargetType",
|
|
"TargetUpdate",
|
|
"TargetValidationRequest",
|
|
"TargetValidationResponse",
|
|
"TemplateFilter",
|
|
"TemplateLibraryStats",
|
|
"TemplatePage",
|
|
"TemplateSelection",
|
|
"TreeNode",
|
|
"User",
|
|
"UserBase",
|
|
"UserCreate",
|
|
"UserRead",
|
|
"ViewDNSCache",
|
|
"VulnTemplate",
|
|
"VulnTemplateRead",
|
|
"VulnTemplateUpdate",
|
|
"VulnTemplateUploadRequest",
|
|
"Vulnerability",
|
|
"VulnerabilityCoverage",
|
|
"VulnerabilityFacets",
|
|
"VulnerabilityFilter",
|
|
"VulnerabilityPage",
|
|
"VulnerabilityRead",
|
|
"VulnerabilityTriage",
|
|
"Wordlist",
|
|
"WordlistFile",
|
|
"WordlistRead",
|
|
"WordlistUpdate",
|
|
"WordlistUploadRequest",
|
|
"WordlistUploadResult",
|
|
]
|