Initiales CMS: Deutschsprachiges Blog-System mit Admin-Bereich

Vollständiges, schlankes PHP/SQLite-CMS für IT-, KI- und Gaming-Inhalte:

- Core: DB-Singleton, Auth mit Passwort-Hashing, Session-Cookies,
  CSRF-Schutz, Login-Rate-Limit, Bild-Upload mit serverseitiger Validierung
- Admin: Dashboard, Artikel/Seiten-Verwaltung mit Quill WYSIWYG-Editor,
  Kategorien, Navigation (Drag & Drop), Medienbibliothek, Profil
- Frontend: Responsive Dark-Theme, Artikel-Grid, Kategorie-Filter,
  Archiv, Paginierung, SEO-Meta-Tags
- Sicherheit: Prepared Statements, HTML-Sanitizer, .htaccess-Schutz
  für sensible Verzeichnisse, PHP-Ausführungsschutz im Upload-Ordner
- Installation: install.php erstellt DB-Schema und Admin-Account

https://claude.ai/code/session_01Xsg4j2t4S9goMuWVpF3ezG
This commit is contained in:
Claude
2026-04-05 20:59:52 +00:00
commit 3c97192386
45 changed files with 2839 additions and 0 deletions

55
core/upload.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
/**
* Bild-Upload mit Validierung
*/
require_once __DIR__ . '/../config/config.php';
function handle_upload(array $file): string|false
{
if ($file['error'] !== UPLOAD_ERR_OK) {
return false;
}
if ($file['size'] > UPLOAD_MAX_SIZE) {
return false;
}
// MIME-Typ serverseitig prüfen
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file['tmp_name']);
if (!in_array($mime, ALLOWED_MIME_TYPES, true)) {
return false;
}
// Prüfen ob es ein echtes Bild ist
$imageInfo = getimagesize($file['tmp_name']);
if ($imageInfo === false) {
return false;
}
// Dateiendung aus MIME ableiten
$extensions = [
'image/jpeg' => '.jpg',
'image/png' => '.png',
'image/gif' => '.gif',
'image/webp' => '.webp',
];
$ext = $extensions[$mime] ?? '.jpg';
// Eindeutigen Dateinamen generieren
$subdir = date('Y/m');
$dir = rtrim(UPLOAD_DIR, '/') . '/' . $subdir;
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
$filename = bin2hex(random_bytes(16)) . $ext;
$filepath = $dir . '/' . $filename;
if (!move_uploaded_file($file['tmp_name'], $filepath)) {
return false;
}
return UPLOAD_URL . $subdir . '/' . $filename;
}