Skip to content

Commit e1aed32

Browse files
committed
güvenlik: Semgrep bulgularına göre XSS, command injection ve unlink güvenliği düzeltildi
- bildirimler.php: Pagination URL'lerinde htmlspecialchars() eklendi (XSS) - denetim-gunlugu.php: Pagination + CSV export URL'lerinde htmlspecialchars() eklendi (XSS) - yedekler.php: mysqldump binary whitelist uygulandı (command injection) - yedekler.php: unlink() öncesi realpath + dizin doğrulaması eklendi (path traversal) - SQL injection bulguları false-positive: WHERE koşulları parameterized query ile oluşturuluyor
1 parent 51c2f49 commit e1aed32

3 files changed

Lines changed: 57 additions & 41 deletions

File tree

bildirimler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,11 @@
194194
?>
195195
<nav class="mt-3">
196196
<ul class="pagination pagination-sm mb-0 justify-content-center">
197-
<li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>"><a class="page-link" href="<?= $pageUrl(max(1, $page - 1)) ?>">«</a></li>
197+
<li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>"><a class="page-link" href="<?= htmlspecialchars($pageUrl(max(1, $page - 1)), ENT_QUOTES, 'UTF-8') ?>">«</a></li>
198198
<?php for ($p = max(1, $page - 3); $p <= min($totalPages, $page + 3); $p++): ?>
199-
<li class="page-item <?= $p === $page ? 'active' : '' ?>"><a class="page-link" href="<?= $pageUrl($p) ?>"><?= $p ?></a></li>
199+
<li class="page-item <?= $p === $page ? 'active' : '' ?>"><a class="page-link" href="<?= htmlspecialchars($pageUrl($p), ENT_QUOTES, 'UTF-8') ?>"><?= $p ?></a></li>
200200
<?php endfor; ?>
201-
<li class="page-item <?= $page >= $totalPages ? 'disabled' : '' ?>"><a class="page-link" href="<?= $pageUrl(min($totalPages, $page + 1)) ?>">»</a></li>
201+
<li class="page-item <?= $page >= $totalPages ? 'disabled' : '' ?>"><a class="page-link" href="<?= htmlspecialchars($pageUrl(min($totalPages, $page + 1)), ENT_QUOTES, 'UTF-8') ?>">»</a></li>
202202
</ul>
203203
</nav>
204204
<?php endif; ?>

yonetim/denetim-gunlugu.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,11 @@ function audit_summary(array $row, array $old, array $new, array $entityLabels,
356356
<div class="d-flex justify-content-between align-items-center mb-3">
357357
<div>
358358
<h5 class="fw-bold mb-0"><i class="bi bi-shield-check me-2 text-primary"></i>Denetim Günlüğü</h5>
359-
<small class="text-muted">Sistem işlemleri, kullanıcı hareketleri ve güvenlik kayıtları · Toplam <?= number_format($totalRows, 0, ',', '.') ?> kayıt · Sayfa <?= $page ?>/<?= $totalPages ?></small>
359+
<small class="text-muted">Sistem işlemleri, kullanıcı hareketleri ve güvenlik kayıtları · Toplam <?= number_format($totalRows, 0, ',', '.') ?> kayıt · Sayfa <?= (int)$page ?>/<?= (int)$totalPages ?></small>
360360
</div>
361361
<div class="d-flex gap-2">
362362
<a class="btn btn-outline-success btn-sm"
363-
href="?<?= http_build_query(array_merge($_GET, ['export' => 'csv'])) ?>">
363+
href="?<?= htmlspecialchars(http_build_query(array_merge($_GET, ['export' => 'csv'])), ENT_QUOTES, 'UTF-8') ?>">
364364
<i class="bi bi-download me-1"></i>CSV Olarak İndir
365365
</a>
366366
</div>
@@ -572,26 +572,26 @@ function audit_summary(array $row, array $old, array $new, array $entityLabels,
572572
<nav class="mt-3">
573573
<ul class="pagination pagination-sm mb-0 justify-content-center">
574574
<li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>">
575-
<a class="page-link" href="<?= $pageUrl(max(1, $page - 1)) ?>">«</a>
575+
<a class="page-link" href="<?= htmlspecialchars($pageUrl(max(1, $page - 1)), ENT_QUOTES, 'UTF-8') ?>">«</a>
576576
</li>
577577
<?php
578578
$start = max(1, $page - 3);
579579
$end = min($totalPages, $page + 3);
580580
if ($start > 1): ?>
581-
<li class="page-item"><a class="page-link" href="<?= $pageUrl(1) ?>">1</a></li>
581+
<li class="page-item"><a class="page-link" href="<?= htmlspecialchars($pageUrl(1), ENT_QUOTES, 'UTF-8') ?>">1</a></li>
582582
<?php if ($start > 2): ?><li class="page-item disabled"><span class="page-link">…</span></li><?php endif; ?>
583583
<?php endif; ?>
584584
<?php for ($p = $start; $p <= $end; $p++): ?>
585585
<li class="page-item <?= $p === $page ? 'active' : '' ?>">
586-
<a class="page-link" href="<?= $pageUrl($p) ?>"><?= $p ?></a>
586+
<a class="page-link" href="<?= htmlspecialchars($pageUrl($p), ENT_QUOTES, 'UTF-8') ?>"><?= $p ?></a>
587587
</li>
588588
<?php endfor; ?>
589589
<?php if ($end < $totalPages): ?>
590590
<?php if ($end < $totalPages - 1): ?><li class="page-item disabled"><span class="page-link">…</span></li><?php endif; ?>
591-
<li class="page-item"><a class="page-link" href="<?= $pageUrl($totalPages) ?>"><?= $totalPages ?></a></li>
591+
<li class="page-item"><a class="page-link" href="<?= htmlspecialchars($pageUrl($totalPages), ENT_QUOTES, 'UTF-8') ?>"><?= (int)$totalPages ?></a></li>
592592
<?php endif; ?>
593593
<li class="page-item <?= $page >= $totalPages ? 'disabled' : '' ?>">
594-
<a class="page-link" href="<?= $pageUrl(min($totalPages, $page + 1)) ?>">»</a>
594+
<a class="page-link" href="<?= htmlspecialchars($pageUrl(min($totalPages, $page + 1)), ENT_QUOTES, 'UTF-8') ?>">»</a>
595595
</li>
596596
</ul>
597597
</nav>

yonetim/yedekler.php

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,20 @@
99
$pageTitle = 'Sistem Yedekleri';
1010
$activeNav = 'backups';
1111

12-
function secap_dump_binary(): string
12+
function secap_dump_binary(): ?string
1313
{
14-
$xampp = '/Applications/XAMPP/xamppfiles/bin/mysqldump';
15-
if (is_executable($xampp)) {
16-
return $xampp;
14+
$allowedPaths = [
15+
'/Applications/XAMPP/xamppfiles/bin/mysqldump',
16+
'/usr/bin/mysqldump',
17+
'/usr/local/bin/mysqldump',
18+
'C:\\xampp\\mysql\\bin\\mysqldump.exe',
19+
];
20+
foreach ($allowedPaths as $path) {
21+
if (is_executable($path)) {
22+
return $path;
23+
}
1724
}
18-
return 'mysqldump';
25+
return null;
1926
}
2027

2128
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
@@ -47,35 +54,44 @@ function secap_dump_binary(): string
4754
$message = 'PHP exec fonksiyonu kapalı olduğu için mysqldump çalıştırılamadı.';
4855
} else {
4956
$binary = secap_dump_binary();
50-
$cmd = escapeshellcmd($binary)
51-
. ' --host=' . escapeshellarg($host)
52-
. ' --port=' . escapeshellarg($port)
53-
. ' --user=' . escapeshellarg($user)
54-
. ' --single-transaction --skip-lock-tables --triggers --default-character-set=utf8mb4'
55-
. ' --result-file=' . escapeshellarg($target)
56-
. ' ' . escapeshellarg($db);
57-
58-
if ($pass !== '') {
59-
if (stripos(PHP_OS_FAMILY, 'Windows') === 0) {
60-
$cmd = 'set MYSQL_PWD=' . escapeshellarg($pass) . ' && ' . $cmd;
61-
} else {
62-
$cmd = 'MYSQL_PWD=' . escapeshellarg($pass) . ' ' . $cmd;
57+
if ($binary === null) {
58+
$message = 'mysqldump bulunamadı. İzin verilen yollar kontrol edildi.';
59+
} else {
60+
$cmd = escapeshellcmd($binary)
61+
. ' --host=' . escapeshellarg($host)
62+
. ' --port=' . escapeshellarg($port)
63+
. ' --user=' . escapeshellarg($user)
64+
. ' --single-transaction --skip-lock-tables --triggers --default-character-set=utf8mb4'
65+
. ' --result-file=' . escapeshellarg($target)
66+
. ' ' . escapeshellarg($db);
67+
68+
if ($pass !== '') {
69+
if (stripos(PHP_OS_FAMILY, 'Windows') === 0) {
70+
$cmd = 'set MYSQL_PWD=' . escapeshellarg($pass) . ' && ' . $cmd;
71+
} else {
72+
$cmd = 'MYSQL_PWD=' . escapeshellarg($pass) . ' ' . $cmd;
73+
}
6374
}
64-
}
6575

66-
$output = [];
67-
$exitCode = 1;
68-
exec($cmd . ' 2>&1', $output, $exitCode);
69-
$message = trim(implode("\n", $output));
70-
if ($exitCode === 0 && is_file($target) && filesize($target) > 0) {
71-
chmod($target, 0664);
72-
$status = 'success';
73-
$message = $message ?: 'Yedek başarıyla oluşturuldu.';
74-
} else {
75-
if (is_file($target) && filesize($target) === 0) {
76-
unlink($target);
76+
$output = [];
77+
$exitCode = 1;
78+
exec($cmd . ' 2>&1', $output, $exitCode);
79+
$message = trim(implode("\n", $output));
80+
if ($exitCode === 0 && is_file($target) && filesize($target) > 0) {
81+
chmod($target, 0664);
82+
$status = 'success';
83+
$message = $message ?: 'Yedek başarıyla oluşturuldu.';
84+
} else {
85+
if (is_file($target) && filesize($target) === 0) {
86+
$realTarget = realpath($target);
87+
$realBackupDir = realpath($backupDir);
88+
if ($realTarget !== false && $realBackupDir !== false
89+
&& strpos($realTarget, $realBackupDir . DIRECTORY_SEPARATOR) === 0) {
90+
unlink($realTarget);
91+
}
92+
}
93+
$message = $message ?: 'mysqldump başarısız oldu.';
7794
}
78-
$message = $message ?: 'mysqldump başarısız oldu.';
7995
}
8096
}
8197

0 commit comments

Comments
 (0)