⚙️ 3.3.3 – Weryfikacja konfiguracji aplikacji i serwera
🎯 Cel sekcji
Zidentyfikować słabe punkty w konfiguracji aplikacji i serwera, które umożliwiają lub zwiększają ryzyko wystąpienia podatności typu Injection.
🔍 Obszary do weryfikacji
🔸 1. Obsługa danych wejściowych
- Czy dane wejściowe są walidowane po stronie serwera?
- Czy stosowane są białe listy dozwolonych wartości?
- Czy aplikacja odrzuca nieoczekiwane znaki (
'
,"
,;
,--
,|
,$
,<
,>
itd.)?
🔸 2. Sposób wykonywania zapytań
- Czy w backendzie stosowane są prepared statements (np.
?
lub named parameters)? - Czy unika się składania zapytań SQL/LDAP/XML za pomocą
+
,concat
,eval
,exec
,system()
?
🔸 3. Uprawnienia bazy danych
- Czy aplikacja korzysta z konta DB z minimalnymi uprawnieniami (
SELECT
tylko jeśli nie ma potrzebyINSERT
/UPDATE
)? - Czy konto nie ma dostępu do poleceń
DROP
,DELETE
,ALTER
?
🔸 4. Logowanie i obsługa błędów
- Czy aplikacja NIE wyświetla błędów SQL/LDAP/command w odpowiedzi HTTP?
- Czy błędy są logowane bez ujawniania stosu lub szczegółów użytkownikowi?
🔸 5. Middleware i serwer
Bezpieczna konfiguracja środowiska uruchomieniowego i middleware aplikacji .NET ma kluczowe znaczenie dla ochrony przed atakami typu injection.
✅ Przykłady zabezpieczeń w ASP.NET Core (Kestrel / IIS)
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxRequestBodySize = 1048576; // 1 MB
serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(10);
serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);
});
✅ Ograniczenie rozmiaru żądania i czasu na nagłówki chroni przed atakami typu Slowloris i próbą przesłania złośliwego payloadu o dużej objętości.
✅ Ochrona przed Remote Code Execution (RCE)
Unikaj niekontrolowanego użycia:
Process.Start(input); // ❌ podatne
Zamiast tego:
- Nigdy nie wykonuj komend bazujących na danych użytkownika.
- Weryfikuj dopuszczalne wartości (np. tylko
ping
,nslookup
z whitelisty). - Używaj
switch
/enum
i tylko z góry określonych wartości.
❌ Przykład niebezpieczny
string cmd = Request.Query["cmd"];
Process.Start("cmd.exe", $"/C {cmd}");
➡️ http://app.local/?cmd=del C:\Users
może skutkować RCE!
✅ Przykład bezpieczny (whitelistowane komendy)
var allowedCommands = new Dictionary<string, string>
{
{ "status", "systemctl status app" },
{ "uptime", "uptime" }
};
if (allowedCommands.ContainsKey(input))
{
Process.Start("/bin/bash", $"-c "{allowedCommands[input]}"");
}
🧠 Dodatkowe środki bezpieczeństwa
- Używaj
UseAuthorization()
iUseAuthentication()
we właściwej kolejności. - Filtruj wejście nawet jeśli middleware uprzednio je przetworzył (defense in depth).
- Upewnij się, że
app.UseDeveloperExceptionPage()
NIE jest włączony w środowisku produkcyjnym.
💻 Przykłady dla aplikacji .NET (C# / ASP.NET Core)
✅ Poprawne podejście: parametryzowane zapytania
using (var command = new SqlCommand("SELECT * FROM Users WHERE Username = @username", connection))
{
command.Parameters.AddWithValue("@username", username);
var reader = command.ExecuteReader();
}
❌ Złe podejście: dynamiczne zapytania SQL
var query = "SELECT * FROM Users WHERE Username = '" + username + "'";
➡️ Wstrzyknięcie admin' --
pozwoli zalogować się bez hasła.
✅ Bezpieczne użycie Entity Framework (LINQ)
var user = dbContext.Users.FirstOrDefault(u => u.Username == inputUsername);
✅ LINQ automatycznie chroni przed injection.
❌ Niebezpieczne użycie FromSqlRaw
var sql = $"SELECT * FROM Users WHERE Username = '{inputUsername}'";
var users = dbContext.Users.FromSqlRaw(sql).ToList();
➡️ Zawsze używaj FromSqlInterpolated
:
var users = dbContext.Users
.FromSqlInterpolated($"SELECT * FROM Users WHERE Username = {inputUsername}")
.ToList();
⚙️ Przykład konfiguracji ASP.NET Core
app.UseExceptionHandler("/Error"); // Ukrywanie stack trace'ów
app.UseHsts(); // Wymuszanie HTTPS
services.AddControllersWithViews()
.AddDataAnnotationsLocalization(); // Walidacja wejścia
📋 Przykład poprawnej konfiguracji – Node.js + PostgreSQL
const result = await db.query("SELECT * FROM users WHERE id = $1", [req.params.id]);
✅ Użycie parametryzacji zamiast string interpolation
.
❌ Przykład złej praktyki
const result = await db.query("SELECT * FROM users WHERE id = " + req.params.id);
❗ Ryzyko SQL Injection, jeśli req.params.id
pochodzi od użytkownika.
🧠 Wskazówki
- Przejrzyj kod aplikacji pod kątem dynamicznych zapytań.
- Sprawdź konfigurację bazy i serwera dla każdego środowiska (dev/test/prod).
- Automatyzuj skanowanie kodu i konfiguracji przy pomocy linters / SAST.
W kolejnym kroku: 3.3.4 – Narzędzia do testowania Injection