diff --git a/Data_Coupler/Pages/DataCoupler.razor b/Data_Coupler/Pages/DataCoupler.razor
index 0221175..19b8d9e 100644
--- a/Data_Coupler/Pages/DataCoupler.razor
+++ b/Data_Coupler/Pages/DataCoupler.razor
@@ -106,10 +106,20 @@
-
-
- Scrivi una query SELECT personalizzata. La query verrà automaticamente ottimizzata per il trasferimento dati.
-
+
+
+
+
+ Controlli di Sicurezza Attivi:
+
+ • Solo query SELECT sono permesse
+ • Operazioni come INSERT, UPDATE, DELETE, DROP sono bloccate
+ • Query multiple separate da ; non sono consentite
+ • La query verrà automaticamente ottimizzata per il trasferimento dati
+
+
+
+
@@ -2386,6 +2396,12 @@
throw new InvalidOperationException("Query custom non valida. Validare la query prima di procedere.");
}
+ // CONTROLLO DI SICUREZZA AGGIUNTIVO: Verifica che sia ancora una SELECT
+ if (!IsSelectQuery(customQuery))
+ {
+ throw new InvalidOperationException("ERRORE DI SICUREZZA: Tentativo di eseguire una query non SELECT. Operazione bloccata per sicurezza.");
+ }
+
var cleanQuery = CleanQuery(customQuery);
Logger.LogInformation("Esecuzione query custom per trasferimento dati: {Query}", cleanQuery);
@@ -2820,6 +2836,15 @@
return;
}
+ // CONTROLLO DI SICUREZZA: Verifica che sia una SELECT
+ if (!IsSelectQuery(customQuery))
+ {
+ isQueryValid = false;
+ queryValidationMessage = "ERRORE DI SICUREZZA: Sono permesse solo query SELECT. Operazioni come INSERT, UPDATE, DELETE, DROP, CREATE, ALTER, TRUNCATE non sono consentite.";
+ Logger.LogWarning("Tentativo di eseguire query non SELECT bloccato: {Query}", customQuery.Length > 100 ? customQuery.Substring(0, 100) + "..." : customQuery);
+ return;
+ }
+
isValidatingQuery = true;
queryValidationMessage = "";
queryColumns.Clear();
@@ -3031,4 +3056,104 @@
StateHasChanged();
}
+
+ ///
+ /// Verifica che la query sia una SELECT e non contenga operazioni pericolose
+ ///
+ private bool IsSelectQuery(string query)
+ {
+ if (string.IsNullOrWhiteSpace(query))
+ return false;
+
+ // Rimuovi commenti e normalizza la query
+ var cleanQuery = CleanQueryForSecurityCheck(query);
+
+ // Lista delle operazioni pericolose che non sono permesse
+ var dangerousKeywords = new[]
+ {
+ "INSERT", "UPDATE", "DELETE", "DROP", "CREATE", "ALTER",
+ "TRUNCATE", "REPLACE", "MERGE", "EXEC", "EXECUTE",
+ "DECLARE", "SET", "GRANT", "REVOKE", "BACKUP", "RESTORE",
+ "SHUTDOWN", "KILL", "LOAD", "BULK", "OPENROWSET", "OPENDATASOURCE"
+ };
+
+ // Verifica che non contenga operazioni pericolose
+ foreach (var keyword in dangerousKeywords)
+ {
+ if (cleanQuery.Contains($" {keyword} ", StringComparison.OrdinalIgnoreCase) ||
+ cleanQuery.StartsWith($"{keyword} ", StringComparison.OrdinalIgnoreCase) ||
+ cleanQuery.Contains($";{keyword} ", StringComparison.OrdinalIgnoreCase) ||
+ cleanQuery.Contains($"\n{keyword} ", StringComparison.OrdinalIgnoreCase) ||
+ cleanQuery.Contains($"\r{keyword} ", StringComparison.OrdinalIgnoreCase))
+ {
+ Logger.LogWarning("Query bloccata: contiene keyword pericolosa '{Keyword}' in query: {QueryStart}",
+ keyword, query.Length > 50 ? query.Substring(0, 50) + "..." : query);
+ return false;
+ }
+ }
+
+ // Verifica che inizi con SELECT (permettendo spazi e commenti iniziali)
+ var trimmedQuery = cleanQuery.TrimStart();
+ if (!trimmedQuery.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
+ {
+ Logger.LogWarning("Query bloccata: non inizia con SELECT. Query: {QueryStart}",
+ query.Length > 50 ? query.Substring(0, 50) + "..." : query);
+ return false;
+ }
+
+ // Verifica addizionale: non deve contenere punto e virgola seguito da altra query
+ var statements = cleanQuery.Split(';', StringSplitOptions.RemoveEmptyEntries);
+ if (statements.Length > 1)
+ {
+ // Se ci sono multiple statements, tutte devono essere SELECT o commenti vuoti
+ foreach (var statement in statements)
+ {
+ var trimmedStatement = statement.Trim();
+ if (!string.IsNullOrEmpty(trimmedStatement) &&
+ !trimmedStatement.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
+ {
+ Logger.LogWarning("Query bloccata: contiene multiple statements non SELECT. Query: {QueryStart}",
+ query.Length > 50 ? query.Substring(0, 50) + "..." : query);
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// Pulisce la query per il controllo di sicurezza rimuovendo commenti
+ ///
+ private string CleanQueryForSecurityCheck(string query)
+ {
+ if (string.IsNullOrEmpty(query))
+ return "";
+
+ var lines = query.Split('\n');
+ var cleanedLines = new List();
+
+ foreach (var line in lines)
+ {
+ var cleanedLine = line.Trim();
+
+ // Rimuovi commenti SQL (-- e /* */)
+ var dashCommentIndex = cleanedLine.IndexOf("--");
+ if (dashCommentIndex >= 0)
+ {
+ cleanedLine = cleanedLine.Substring(0, dashCommentIndex).Trim();
+ }
+
+ // Gestione commenti multiline /* */ - implementazione base
+ cleanedLine = System.Text.RegularExpressions.Regex.Replace(cleanedLine, @"/\*.*?\*/", " ",
+ System.Text.RegularExpressions.RegexOptions.IgnoreCase);
+
+ if (!string.IsNullOrWhiteSpace(cleanedLine))
+ {
+ cleanedLines.Add(cleanedLine);
+ }
+ }
+
+ return string.Join(" ", cleanedLines);
+ }
}
diff --git a/Data_Coupler/wwwroot/data/credentials.db-shm b/Data_Coupler/wwwroot/data/credentials.db-shm
index 6262d13..c6bea81 100644
Binary files a/Data_Coupler/wwwroot/data/credentials.db-shm and b/Data_Coupler/wwwroot/data/credentials.db-shm differ