Session 2026-04-23: Security, Content-Schutz, Wiki-Temperament-Migration

Security (9 Fixes):
- JWT_SECRET Pflicht-Check beim Start (Production)
- Rate-Limit: Login (10/5min), Register (5/h), KI-Training (10/h), Giftköder (3/h)
- KI-Training-Endpoint: Auth-Pflicht hinzugefügt
- Private Profile aus Freunde-Suche gefiltert
- OG-Tags XSS mit html.escape() gesichert
- Globales File-Upload-Limit 20 MB (Middleware)
- E-Mail-Maskierung für Moderatoren im Admin-Panel
- IP-Blocklist in ratelimit.py

Content-Schutz (4 Schichten):
- robots.txt: /api/ komplett Disallow, SSR-Seiten Allow
- Rate-Limit auf /api/wiki/rassen (60/min) + Detail (30/min)
- Honeypot /api/wiki/trap + unsichtbarer Link in index.html
- Wasserzeichen in KI-Enricher-Prompt

Wiki Temperament-Migration:
- 60-Wort Übersetzungsmap EN→DE
- Datenmüll-Filter (hunderasse, dog breed etc.)
- translate_existing_temperaments() + Admin-Button
- SW by-v318, APP_VER 306
This commit is contained in:
rene 2026-04-23 18:34:05 +02:00
parent 0f5f1c4c30
commit 15f854d96c
15 changed files with 284 additions and 53 deletions

View file

@ -200,6 +200,10 @@
<span data-page="impressum" style="cursor:pointer;text-decoration:underline">Impressum</span>
<span data-page="datenschutz" style="cursor:pointer;text-decoration:underline">Datenschutz</span>
</div>
<!-- bot-trap: kein echter Nutzer klickt hier -->
<a href="/api/wiki/trap" aria-hidden="true" tabindex="-1"
style="position:absolute;width:1px;height:1px;opacity:0;pointer-events:none"
rel="nofollow noindex">.</a>
</div>
</nav>

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
const APP_VER = '300'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VER = '306'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const App = (() => {

View file

@ -674,6 +674,18 @@ window.Page_admin = (() => {
</button>
</div>
<div id="adm-sys-cards">Lade</div>
<div class="card" style="margin-top:var(--space-4);padding:var(--space-4)">
<div style="font-size:var(--text-sm);font-weight:var(--weight-semibold);
color:var(--c-text);margin-bottom:var(--space-3)">Wartung</div>
<div style="display:flex;flex-wrap:wrap;gap:var(--space-2)">
<button class="btn btn-secondary btn-sm" id="adm-translate-temper">
${UI.icon('translate')} Temperament Deutsch
</button>
</div>
<div id="adm-maint-result" style="margin-top:var(--space-2);font-size:var(--text-xs);
color:var(--c-text-secondary)"></div>
</div>
<div style="margin-top:var(--space-5)">
<div style="display:flex;align-items:center;gap:var(--space-3);margin-bottom:var(--space-3)">
<span style="font-size:var(--text-sm);font-weight:600">Server-Logs</span>
@ -712,6 +724,21 @@ window.Page_admin = (() => {
});
el.querySelector('#adm-log-refresh').addEventListener('click', loadLogs);
el.querySelector('#adm-log-level').addEventListener('change', loadLogs);
el.querySelector('#adm-translate-temper').addEventListener('click', async (e) => {
const btn = e.currentTarget;
const res = el.querySelector('#adm-maint-result');
btn.disabled = true;
res.textContent = 'Läuft…';
try {
const d = await API.post('/admin/wiki/translate-temperament', {});
res.textContent = `${d.updated} Rassen übersetzt`;
} catch (err) {
res.textContent = '✗ Fehler: ' + (err.message || err);
} finally {
btn.disabled = false;
}
});
await _loadSystemCards(el.querySelector('#adm-sys-cards'));
await loadLogs();
}

View file

@ -1,30 +1,10 @@
User-agent: *
Allow: /
Allow: /info
Allow: /wiki/rassen
Allow: /wiki/rasse/
Allow: /hund/
Allow: /api/wiki/rassen
Allow: /api/wiki/rassen/
Allow: /api/events
Allow: /api/knigge/articles
Allow: /api/movies/list
Allow: /api/forum/
Allow: /api/lost
Allow: /api/poison
Allow: /api/stats
Disallow: /api/auth/
Disallow: /api/admin/
Disallow: /api/dogs/
Disallow: /api/diary/
Disallow: /api/health/
Disallow: /api/chat/
Disallow: /api/friends/
Disallow: /api/push/
Disallow: /api/widget/
Disallow: /api/notifications/
Disallow: /api/alerts/
Disallow: /api/ki/
Disallow: /api/import/
Disallow: /api/sitting-access/
Disallow: /api/
Disallow: /ausweis/
Disallow: /teilen/
Disallow: /media/

View file

@ -3,7 +3,7 @@
Offline-Cache + Push Notifications + Tile-Cache
============================================================ */
const CACHE_VERSION = 'by-v312';
const CACHE_VERSION = 'by-v318';
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten