Sicherheitscheck: Schwachstellen behoben
- Pfad-Traversal: safeFilename/containedPath-Helper, storeAnhang sanitizes filename, alle Download/Delete/Mail-Send-Routen pruefen Containment - Stored XSS: serveInline entscheidet Viewable-Typ nur nach Extension, nicht nach client/seitigem MIME; nicht viewbare Typen werden als Download erzwungen. Upload fileFilter (Basis/Interne) + Extension-Validierung (Signatur/Foto leiten Ext aus MIME, blockieren .html) - URL-Scheme-Allowlist (safeUrl) fuer quelle_url-hrefs gegen javascript:-XSS - E-Mail-Iframe: Sandbox auf allow-same-only (kein allow-popups-to-escape) - Sicherheits-Header: CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, COOP; x-powered-by aus; jsPDF self-hosted unter /vendor - Session: Secure-Flag bei TLS, serverseitige absoluteexpiry, Scrypt async + Dummy-Verify gegen Timing/Enumerate + Login-Rate-Limit - Open Redirect: /email/fetch nur same-origin Redirects - SSRF: Validierung von OLLAMA_HOST/CALDAV_URL/MAIL_HOST gegen Metadata/Link-Local-BLock (localhost/LAN bleibt erlaubt) - Globaler Error-Handler ohne Interna-Leak, env=production Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+5
-4
@@ -415,7 +415,7 @@
|
||||
</summary>
|
||||
<div class="px-4 pb-4">
|
||||
<% if (application.quelle_url) { %>
|
||||
<a href="<%= application.quelle_url %>" target="_blank" rel="noopener"
|
||||
<a href="<%= safeUrl(application.quelle_url) %>" target="_blank" rel="noopener"
|
||||
class="inline-block mb-3 text-sm text-blue-600 dark:text-blue-400 hover:underline break-all"><%= application.quelle_url %></a>
|
||||
<% } %>
|
||||
<p class="whitespace-pre-wrap break-words text-sm leading-relaxed text-gray-700 dark:text-gray-300"><%= application.stellenbeschreibung %></p>
|
||||
@@ -471,7 +471,7 @@
|
||||
<p class="text-sm font-medium text-gray-800 dark:text-gray-100 mb-1"><%= e.subject || '(kein Betreff)' %></p>
|
||||
<% if (e.display_srcdoc) { %>
|
||||
<iframe class="email-html-frame w-full border border-gray-200 dark:border-gray-600 rounded bg-white" style="height:6rem"
|
||||
sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox" referrerpolicy="no-referrer"
|
||||
sandbox="allow-same-origin" referrerpolicy="no-referrer"
|
||||
srcdoc="<%= e.display_srcdoc %>"></iframe>
|
||||
<% } else { %>
|
||||
<p class="whitespace-pre-wrap break-words text-sm leading-relaxed text-gray-700 dark:text-gray-300"><%= e.body_text || '' %></p>
|
||||
@@ -828,8 +828,9 @@
|
||||
});
|
||||
|
||||
// Size a sandboxed e-mail iframe to its content height. The sandbox
|
||||
// enables allow-same-origin (but not allow-scripts), so scripts in the
|
||||
// mail never run, yet we can still measure the rendered document.
|
||||
// keeps allow-same-origin (so we can read contentDocument to measure)
|
||||
// but enables no scripts, no forms and no popups, so mail content can
|
||||
// neither execute nor escape the frame.
|
||||
function fitFrame(f) {
|
||||
try {
|
||||
const doc = f.contentDocument || (f.contentWindow && f.contentWindow.document);
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% if (j.quelle_url) { %>
|
||||
<a href="<%= j.quelle_url %>" target="_blank" rel="noopener noreferrer"
|
||||
<a href="<%= safeUrl(j.quelle_url) %>" target="_blank" rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400 hover:underline mt-2 break-all">
|
||||
<svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path></svg>
|
||||
<span class="truncate"><%= j.quelle_url %></span>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
</p>
|
||||
<% } %>
|
||||
<% if (j.quelle_url) { %>
|
||||
<a href="<%= j.quelle_url %>" target="_blank" rel="noopener noreferrer"
|
||||
<a href="<%= safeUrl(j.quelle_url) %>" target="_blank" rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400 hover:underline mt-2 break-all">
|
||||
<svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path></svg>
|
||||
<span class="truncate"><%= j.quelle_url %></span>
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@
|
||||
<p class="text-sm font-medium text-gray-800 dark:text-gray-100 mb-1"><%= e.subject || '(kein Betreff)' %></p>
|
||||
<% if (e.display_srcdoc) { %>
|
||||
<iframe class="email-html-frame w-full border border-gray-200 dark:border-gray-600 rounded bg-white" style="height:6rem"
|
||||
sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox" referrerpolicy="no-referrer"
|
||||
sandbox="allow-same-origin" referrerpolicy="no-referrer"
|
||||
srcdoc="<%= e.display_srcdoc %>"></iframe>
|
||||
<% } else { %>
|
||||
<p class="email-body whitespace-pre-wrap break-words text-sm leading-relaxed text-gray-700 dark:text-gray-300 max-h-40 overflow-hidden"><%= e.body_text || '' %></p>
|
||||
|
||||
Reference in New Issue
Block a user