security: faza 2 - safeUnlink() i escaping XSS w szablonach artykulow

- ProductRepository: dodano safeUnlink() z walidacja realpath() - zapobiega path traversal
- ArticleRepository: to samo, 4 metody usuwania plikow zaktualizowane
- templates/articles/article-full.php: htmlspecialchars() na tytule, SERVER_NAME i $url
- templates/articles/article-entry.php: htmlspecialchars() na tytule i $url (3 miejsca)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jacek
2026-03-12 09:22:32 +01:00
parent 564b4eab40
commit 394d09d3e1
4 changed files with 51 additions and 30 deletions

View File

@@ -318,9 +318,7 @@ class ArticleRepository
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
@@ -337,9 +335,7 @@ class ArticleRepository
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
@@ -819,9 +815,7 @@ class ArticleRepository
$results = $this->db->select('pp_articles_files', '*', ['article_id' => null]);
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
@@ -836,15 +830,29 @@ class ArticleRepository
$results = $this->db->select('pp_articles_images', '*', ['article_id' => null]);
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
$this->db->delete('pp_articles_images', ['article_id' => null]);
}
/**
* Usuwa plik z dysku tylko jeśli ścieżka pozostaje wewnątrz katalogu upload/.
* Zapobiega path traversal przy danych z bazy.
*/
private function safeUnlink(string $src): void
{
$base = realpath('../upload');
if (!$base) {
return;
}
$full = realpath('../' . ltrim($src, '/'));
if ($full && strpos($full, $base . DIRECTORY_SEPARATOR) === 0 && is_file($full)) {
unlink($full);
}
}
/**
* Pobiera artykuly opublikowane w podanym zakresie dat.
*/