fix(security): resolve F-01 — parameterize SQL queries in RainfallController index()

This commit is contained in:
root
2026-05-28 16:26:01 +08:00
parent b63cb6a3e8
commit e9fa6a2912

View File

@@ -30,21 +30,31 @@ class RainfallController extends Controller
->where('rainfall',1) ->where('rainfall',1)
->orderBy('stationid')->get(); ->orderBy('stationid')->get();
$bindings = [];
$stationCondition = ''; $stationCondition = '';
if ($stationFilter) if ($stationFilter) {
{ $stationCondition = " AND s.stationid = ?";
$stationCondition = " AND s.stationid = '{$stationFilter}'"; $bindings[] = $stationFilter;
} }
$bindings[] = $displayDate;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$bindings[] = $dateFilter;
$rainfallData = collect(DB::select(" $rainfallData = collect(DB::select("
SELECT SELECT
s.stationid, s.stationid,
s.name, s.name,
s.district, s.district,
-- selected datetime filter CAST(? AS timestamp) AS selected_timestamp,
CAST('$displayDate' AS timestamp) AS selected_timestamp,
-- Latest hourly value
( (
SELECT l2.hourly SELECT l2.hourly
FROM rainfall l2 FROM rainfall l2
@@ -53,7 +63,6 @@ class RainfallController extends Controller
LIMIT 1 LIMIT 1
) AS hourly, ) AS hourly,
-- Latest daily rainfall
( (
SELECT l3.daily SELECT l3.daily
FROM rainfall l3 FROM rainfall l3
@@ -66,27 +75,27 @@ class RainfallController extends Controller
SELECT l4.timestamp SELECT l4.timestamp
FROM rainfall l4 FROM rainfall l4
WHERE l4.stationid = s.stationid WHERE l4.stationid = s.stationid
AND DATE(l4.timestamp) <= CAST('$dateFilter' AS date) AND DATE(l4.timestamp) <= CAST(? AS date)
ORDER BY l4.timestamp DESC ORDER BY l4.timestamp DESC
LIMIT 1 LIMIT 1
) AS last_updated, ) AS last_updated,
-- Historical daily values for the past 7 days MAX(CASE WHEN DATE(l.timestamp) = CAST(? as date) - INTERVAL '6 days' THEN l.daily END) AS day1,
MAX(CASE WHEN DATE(l.timestamp) = CAST('$dateFilter' as date) - INTERVAL '6 days' THEN l.daily END) AS day1, MAX(CASE WHEN DATE(l.timestamp) = CAST(? as date) - INTERVAL '5 days' THEN l.daily END) AS day2,
MAX(CASE WHEN DATE(l.timestamp) = CAST('$dateFilter' as date) - INTERVAL '5 days' THEN l.daily END) AS day2, MAX(CASE WHEN DATE(l.timestamp) = CAST(? as date) - INTERVAL '4 days' THEN l.daily END) AS day3,
MAX(CASE WHEN DATE(l.timestamp) = CAST('$dateFilter' as date) - INTERVAL '4 days' THEN l.daily END) AS day3, MAX(CASE WHEN DATE(l.timestamp) = CAST(? as date) - INTERVAL '3 days' THEN l.daily END) AS day4,
MAX(CASE WHEN DATE(l.timestamp) = CAST('$dateFilter' as date) - INTERVAL '3 days' THEN l.daily END) AS day4, MAX(CASE WHEN DATE(l.timestamp) = CAST(? as date) - INTERVAL '2 days' THEN l.daily END) AS day5,
MAX(CASE WHEN DATE(l.timestamp) = CAST('$dateFilter' as date) - INTERVAL '2 days' THEN l.daily END) AS day5, MAX(CASE WHEN DATE(l.timestamp) = CAST(? as date) - INTERVAL '1 day' THEN l.daily END) AS day6,
MAX(CASE WHEN DATE(l.timestamp) = CAST('$dateFilter' as date) - INTERVAL '1 day' THEN l.daily END) AS day6, MAX(CASE WHEN DATE(l.timestamp) = CAST(? as date) THEN l.daily END) AS day7
MAX(CASE WHEN DATE(l.timestamp) = CAST('$dateFilter' as date) THEN l.daily END) AS day7
FROM station s FROM station s
INNER JOIN rainfall l ON s.stationid = l.stationid INNER JOIN rainfall l ON s.stationid = l.stationid
WHERE TO_CHAR(l.timestamp, 'HH24:MI:SS') != '00:00:00' WHERE TO_CHAR(l.timestamp, 'HH24:MI:SS') != '00:00:00'
AND l.timestamp >= CAST('$dateFilter' as date) - INTERVAL '6 days' AND l.timestamp >= CAST(? as date) - INTERVAL '6 days'
$stationCondition $stationCondition
GROUP BY s.stationid, s.name, s.district GROUP BY s.stationid, s.name, s.district
" ",
$bindings
)); ));