diff --git a/src/Core/Application/Services/TextToSqlService.cs b/src/Core/Application/Services/TextToSqlService.cs index c38d75c..fae8deb 100644 --- a/src/Core/Application/Services/TextToSqlService.cs +++ b/src/Core/Application/Services/TextToSqlService.cs @@ -644,11 +644,8 @@ public class TextToSqlService : ITextToSqlService foreach (var tagName in tagNames) { - // SQL 인젝션 방지를 위해 태그명 이스케이프 - var escapedTagName = tagName.Replace("'", "''"); - - // history_table: tagname (TEXT), recorded_at (TIMESTAMPTZ), value (TEXT) - var sql = $@" + // SQL 인젝션 방지를 위해 parameterized query 사용 + var sql = @" SELECT AVG(value::double precision) AS avg_val, MIN(value::double precision) AS min_val, @@ -658,10 +655,14 @@ public class TextToSqlService : ITextToSqlService last(value::double precision, recorded_at) AS last_val, COUNT(*) AS point_count FROM history_table - WHERE tagname = '{escapedTagName}' - AND recorded_at BETWEEN '{from}' AND '{to}'"; + WHERE tagname = @tagName + AND recorded_at BETWEEN @fromTimestamp AND @toTimestamp"; using var cmd = new NpgsqlCommand(sql, conn); + cmd.Parameters.AddWithValue("@tagName", tagName); + cmd.Parameters.AddWithValue("@fromTimestamp", DateTime.Parse(from)); + cmd.Parameters.AddWithValue("@toTimestamp", DateTime.Parse(to)); + using var reader = await cmd.ExecuteReaderAsync(); if (await reader.ReadAsync())