sql >> Database teknologi >  >> RDS >> Mysql

Hvordan kan jeg beskytte MySQL brugernavn og adgangskode mod dekompilering?

Indtast aldrig adgangskoder hårdt i din kode. Dette blev bragt for nylig i Top 25 mest farlige programmeringsfejl :

Hard-kodning af en hemmelig konto og adgangskode i din software er ekstremt praktisk - for dygtige, omhyggelige ingeniører. Hvis adgangskoden er den samme på tværs af al din software, så bliver enhver kunde sårbar, når adgangskoden uundgåeligt bliver kendt. Og fordi det er hårdkodet, er det en kæmpe smerte at ordne.

Du bør gemme konfigurationsoplysninger, herunder adgangskoder, i en separat fil, som programmet læser, når det starter. Det er den eneste rigtige måde at forhindre adgangskoden i at lække som følge af dekompilering (kompiler den aldrig til binær til at begynde med).

For mere information om denne almindelige fejl, kan du læse CWE-259-artiklen . Artiklen indeholder en mere grundig definition, eksempler og mange andre oplysninger om problemet.

I Java er en af ​​de nemmeste måder at gøre dette på at bruge klassen Præferencer. Den er designet til at gemme alle mulige programindstillinger, hvoraf nogle kunne indeholde et brugernavn og en adgangskode.

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
}

I ovenstående kode kan du kalde setCredentials metode efter at have vist en dialogboks, spørg efter brugernavn og adgangskode. Når du skal oprette forbindelse til databasen, kan du bare bruge getUsername og getPassword metoder til at hente de lagrede værdier. Loginoplysningerne bliver ikke hårdkodet i dine binære filer, så dekompilering vil ikke udgøre en sikkerhedsrisiko.

Vigtig bemærkning: Præferencefilerne er blot almindelig tekst XML-filer. Sørg for at tage passende skridt for at forhindre uautoriserede brugere i at se råfilerne (UNIX-tilladelser, Windows-tilladelser osv.). I Linux er dette i hvert fald ikke et problem, fordi kald Preferences.userNodeForPackage vil oprette XML-filen i den aktuelle brugers hjemmemappe, som alligevel ikke kan læses af andre brugere. I Windows kan situationen være anderledes.

Flere vigtige bemærkninger: Der har været megen diskussion i kommentarerne til dette svar og andre om, hvad den korrekte arkitektur er for denne situation. Det oprindelige spørgsmål nævner ikke rigtig den kontekst, som applikationen bruges i, så jeg vil tale om de to situationer, jeg kan komme i tanke om. Det første er det tilfælde, hvor den person, der bruger programmet, allerede kender (og er autoriseret til at kende) databasens legitimationsoplysninger. Det andet er tilfældet, hvor du, udvikleren, forsøger at holde databasens legitimationsoplysninger hemmelige for den person, der bruger programmet.

Første tilfælde:Brugeren er autoriseret til at kende databasens loginoplysninger

I dette tilfælde vil den løsning, jeg nævnte ovenfor, fungere. Java Preference klasse gemmer brugernavnet og adgangskoden i almindelig tekst, men præferencefilen vil kun kunne læses af den autoriserede bruger. Brugeren kan blot åbne præference-XML-filen og læse loginoplysningerne, men det er ikke en sikkerhedsrisiko, fordi brugeren kendte legitimationsoplysningerne til at begynde med.

Andet tilfælde:Forsøger at skjule loginoplysninger for brugeren

Dette er det mere komplicerede tilfælde:Brugeren skal ikke kende loginoplysningerne, men skal stadig have adgang til databasen. I dette tilfælde har brugeren, der kører applikationen, direkte adgang til databasen, hvilket betyder, at programmet skal kende loginoplysningerne på forhånd. Den løsning, jeg nævnte ovenfor, er ikke passende i denne sag. Du kan gemme databasens loginoplysninger i en præferencefil, men brugeren vil være i stand til at læse den fil, da de vil være ejeren. Faktisk er der virkelig ingen god måde at bruge denne sag på en sikker måde.

Korrekt sag:Brug af en flerlagsarkitektur

Den korrekte måde at gøre det på er at have et mellemlag, mellem din databaseserver og din klientapplikation, som autentificerer individuelle brugere og tillader, at et begrænset sæt operationer udføres. Hver bruger ville have deres egne login-legitimationsoplysninger, men ikke for databaseserveren. Legitimationsoplysningerne ville give adgang til mellemlaget (forretningslogikniveauet) og ville være forskelligt for hver bruger.

Hver bruger ville have deres eget brugernavn og adgangskode, som kunne gemmes lokalt i en præferencefil uden nogen sikkerhedsrisiko. Dette kaldes en tre-tiers arkitektur (niveauerne er din databaseserver, forretningslogikserver og klientapplikation). Det er mere komplekst, men det er virkelig den mest sikre måde at gøre denne slags ting på.

Den grundlæggende rækkefølge af operationer er:

  1. Klient autentificerer med business logic tier ved hjælp af brugerens personlige brugernavn/adgangskode. Brugernavnet og adgangskoden er kendt af brugeren og er ikke relateret til databasens loginoplysninger på nogen måde.
  2. Hvis godkendelse lykkes, sender klienten en anmodning til forretningslogikniveauet og beder om nogle oplysninger fra databasen. For eksempel en opgørelse af produkter. Bemærk, at klientens anmodning ikke er en SQL-forespørgsel; det er et fjernprocedurekald såsom getInventoryList .
  3. Forretningslogikniveauet forbinder til databasen og henter de anmodede oplysninger. Forretningslogikniveauet er ansvarlig for at danne en sikker SQL-forespørgsel baseret på brugerens anmodning. Alle parametre til SQL-forespørgslen skal renses for at forhindre SQL-injektionsangreb.
  4. Forretningslogikniveauet sender inventarlisten tilbage til klientapplikationen.
  5. Klienten viser inventarlisten for brugeren.

Bemærk, at klientapplikationen aldrig forbinder direkte til databasen i hele processen . Forretningslogikniveauet modtager en anmodning fra en godkendt bruger, behandler klientens anmodning om en beholdningsliste og udfører først derefter en SQL-forespørgsel.



  1. Sådan får du den aktuelle tid (uden tidszone) i PostgreSQL

  2. UNIX_TIMESTAMP i SQL Server

  3. Fordele vs. ulemper ved at implementere et hybridt cloudmiljø

  4. Er det muligt at angive parametre for tabel- eller kolonnenavn i Prepared Statements eller QueryRunner.update()?