Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak mogę zabezpieczyć nazwę użytkownika i hasło MySQL przed dekompilacją?

Nigdy nie wpisuj haseł na stałe do swojego kodu. Zostało to ostatnio poruszone w 25 najbardziej niebezpiecznych błędów programistycznych :

Zakodowanie na stałe tajnego konta i hasła w oprogramowaniu jest niezwykle wygodne — dla wykwalifikowanych inżynierów odwrotnych. Jeśli hasło jest takie samo w całym oprogramowaniu, każdy klient staje się podatny na ataki, gdy hasło nieuchronnie staje się znane. A ponieważ jest zakodowany, naprawienie tego jest bardzo trudne.

Informacje konfiguracyjne, w tym hasła, należy przechowywać w osobnym pliku, który aplikacja odczytuje podczas uruchamiania. To jedyny prawdziwy sposób, aby zapobiec wyciekowi hasła w wyniku dekompilacji (na początku nigdy nie kompiluj go do pliku binarnego).

Aby uzyskać więcej informacji na temat tego powszechnego błędu, przeczytaj artykuł CWE-259 . Artykuł zawiera dokładniejszą definicję, przykłady i wiele innych informacji na temat problemu.

W Javie jednym z najłatwiejszych sposobów na to jest użycie klasy Preferences. Jest przeznaczony do przechowywania wszelkiego rodzaju ustawień programu, z których niektóre mogą zawierać nazwę użytkownika i hasło.

import java.util.prefs.Preferences;

public class DemoApplication {
  Preferences preferences = 
      Preferences.userNodeForPackage(DemoApplication.class);

  public void setCredentials(String username, String password) {
    preferences.put("db_username", username);
    preferences.put("db_password", password);
  }

  public String getUsername() {
    return preferences.get("db_username", null);
  }

  public String getPassword() {
    return preferences.get("db_password", null);
  }

  // your code here
}

W powyższym kodzie możesz wywołać setCredentials metoda po wyświetleniu okna dialogowego z pytaniem o nazwę użytkownika i hasło. Kiedy musisz połączyć się z bazą danych, możesz po prostu użyć getUsername i getPassword metody pobierania przechowywanych wartości. Dane logowania nie zostaną zapisane na stałe w plikach binarnych, więc dekompilacja nie będzie stanowić zagrożenia dla bezpieczeństwa.

Ważna uwaga: Pliki preferencji to zwykłe pliki tekstowe XML. Upewnij się, że podejmujesz odpowiednie kroki, aby uniemożliwić nieautoryzowanym użytkownikom przeglądanie plików raw (uprawnienia UNIX, uprawnienia Windows itp.). Przynajmniej w Linuksie nie stanowi to problemu, ponieważ wywołanie Preferences.userNodeForPackage utworzy plik XML w katalogu domowym bieżącego użytkownika, którego i tak nie mogą odczytać inni użytkownicy. W systemie Windows sytuacja może być inna.

Więcej ważnych uwag: W komentarzach do tej i innych odpowiedzi było wiele dyskusji na temat tego, jaka jest właściwa architektura w tej sytuacji. Pierwotne pytanie tak naprawdę nie wspomina o kontekście, w którym aplikacja jest używana, więc opowiem o dwóch sytuacjach, które przychodzą mi do głowy. Pierwszy to przypadek, w którym osoba korzystająca z programu zna już (i jest upoważniona do poznania) poświadczenia bazy danych. Drugi to przypadek, w którym Ty, programista, próbujesz zachować poświadczenia bazy danych w tajemnicy przed osobą korzystającą z programu.

Pierwszy przypadek:użytkownik jest upoważniony do poznania danych logowania do bazy danych

W takim przypadku zadziała rozwiązanie, o którym wspomniałem powyżej. Preference Java class przechowuje nazwę użytkownika i hasło w postaci zwykłego tekstu, ale plik preferencji będzie odczytywany tylko przez autoryzowanego użytkownika. Użytkownik może po prostu otworzyć plik XML preferencji i odczytać poświadczenia logowania, ale nie stanowi to zagrożenia bezpieczeństwa, ponieważ użytkownik znał poświadczenia od samego początku.

Drugi przypadek:próba ukrycia danych logowania przed użytkownikiem

To jest bardziej skomplikowany przypadek:użytkownik nie powinien znać danych logowania, ale nadal potrzebuje dostępu do bazy danych. W takim przypadku użytkownik uruchamiający aplikację ma bezpośredni dostęp do bazy danych, co oznacza, że ​​program musi wcześniej znać dane logowania. Rozwiązanie, o którym wspomniałem powyżej, nie jest odpowiednie w tym przypadku. Poświadczenia logowania do bazy danych można przechowywać w pliku preferencji, ale użytkownik będzie mógł odczytać ten plik, ponieważ będzie on właścicielem. W rzeczywistości nie ma dobrego sposobu na bezpieczne korzystanie z tego przypadku.

Właściwy przypadek:korzystanie z architektury wielowarstwowej

Prawidłowym sposobem na to jest utworzenie warstwy środkowej pomiędzy serwerem bazy danych a aplikacją kliencką, która uwierzytelnia poszczególnych użytkowników i umożliwia wykonanie ograniczonego zestawu operacji. Każdy użytkownik miałby własne poświadczenia logowania, ale nie serwer bazy danych. Poświadczenia umożliwiłyby dostęp do warstwy środkowej (warstwy logiki biznesowej) i byłyby różne dla każdego użytkownika.

Każdy użytkownik miałby własną nazwę użytkownika i hasło, które mogłyby być przechowywane lokalnie w pliku preferencji bez żadnego zagrożenia bezpieczeństwa. Nazywa się to architekturą trójwarstwową (warstwy to serwer bazy danych, serwer logiki biznesowej i aplikacja kliencka). Jest to bardziej złożone, ale naprawdę jest to najbezpieczniejszy sposób robienia tego typu rzeczy.

Podstawowa kolejność operacji to:

  1. Klient uwierzytelnia się w warstwie logiki biznesowej przy użyciu osobistej nazwy użytkownika/hasła użytkownika. Nazwa użytkownika i hasło są znane użytkownikowi i nie są w żaden sposób powiązane z danymi logowania do bazy danych.
  2. Jeśli uwierzytelnianie się powiedzie, klient wysyła żądanie do warstwy logiki biznesowej, prosząc o pewne informacje z bazy danych. Na przykład spis produktów. Zauważ, że żądanie klienta nie jest zapytaniem SQL; jest to zdalne wywołanie procedury, takie jak getInventoryList .
  3. Warstwa logiki biznesowej łączy się z bazą danych i pobiera żądane informacje. Warstwa logiki biznesowej odpowiada za tworzenie bezpiecznego zapytania SQL na podstawie żądania użytkownika. Wszelkie parametry zapytania SQL powinny zostać oczyszczone, aby zapobiec atakom typu SQL injection.
  4. Warstwa logiki biznesowej wysyła listę inwentarza z powrotem do aplikacji klienckiej.
  5. Klient wyświetla użytkownikowi listę inwentarzową.

Pamiętaj, że w całym procesie aplikacja kliencka nigdy nie łączy się bezpośrednio z bazą danych . Warstwa logiki biznesowej odbiera żądanie od uwierzytelnionego użytkownika, przetwarza żądanie klienta dotyczące listy inwentarzowej, a dopiero potem wykonuje zapytanie SQL.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy mogę wykonać wiele zapytań oddzielonych średnikami za pomocą MySQL Connector/J?

  2. Jak uzyskać identyfikator po wstawieniu do bazy danych MySQL za pomocą Pythona?

  3. Jak najlepiej wykorzystać funkcję komentowania w MySQL?

  4. mySQL ::wstawić do tabeli, dane z innej tabeli?

  5. Jak przechowywać GUID w tabelach MySQL?