sql >> Database >  >> RDS >> Mysql

Hoe kan ik de MySQL-gebruikersnaam en -wachtwoord beschermen tegen decompilatie?

Versleutel nooit wachtwoorden in uw code. Dit werd onlangs naar voren gebracht in de Top 25 meest gevaarlijke programmeerfouten :

Het hard coderen van een geheim account en wachtwoord in uw software is buitengewoon handig - voor ervaren reverse engineers. Als het wachtwoord voor al uw software hetzelfde is, wordt elke klant kwetsbaar wanneer dat wachtwoord onvermijdelijk bekend wordt. En omdat het hard gecodeerd is, is het enorm lastig om het op te lossen.

U moet configuratie-informatie, inclusief wachtwoorden, opslaan in een apart bestand dat de toepassing leest wanneer deze wordt gestart. Dat is de enige echte manier om te voorkomen dat het wachtwoord lekt als gevolg van decompilatie (compileer het om te beginnen nooit in het binaire bestand).

Voor meer informatie over deze veelgemaakte fout kunt u het CWE-259-artikel . Het artikel bevat een uitgebreidere definitie, voorbeelden en tal van andere informatie over het probleem.

In Java is een van de gemakkelijkste manieren om dit te doen, de klasse Preferences te gebruiken. Het is ontworpen om allerlei programma-instellingen op te slaan, waarvan sommige een gebruikersnaam en wachtwoord kunnen bevatten.

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
}

In de bovenstaande code zou je de setCredentials . kunnen aanroepen methode na het tonen van een dialoog om de gebruikersnaam en het wachtwoord te vragen. Wanneer u verbinding moet maken met de database, kunt u gewoon de getUsername . gebruiken en getPassword methoden om de opgeslagen waarden op te halen. De inloggegevens worden niet hard gecodeerd in uw binaire bestanden, dus decompilatie vormt geen veiligheidsrisico.

Belangrijke opmerking: De voorkeursbestanden zijn gewoon XML-tekstbestanden. Zorg ervoor dat u de juiste stappen onderneemt om te voorkomen dat onbevoegde gebruikers de onbewerkte bestanden bekijken (UNIX-machtigingen, Windows-machtigingen, enzovoort). In Linux is dit in ieder geval geen probleem, omdat het aanroepen van Preferences.userNodeForPackage maakt het XML-bestand aan in de thuismap van de huidige gebruiker, die sowieso niet kan worden gelezen door andere gebruikers. In Windows kan de situatie anders zijn.

Meer belangrijke opmerkingen: Er is veel discussie geweest in de opmerkingen van dit antwoord en anderen over wat de juiste architectuur is voor deze situatie. De oorspronkelijke vraag vermeldt niet echt de context waarin de applicatie wordt gebruikt, dus ik zal het hebben over de twee situaties die ik kan bedenken. Het eerste is het geval waarin de persoon die het programma gebruikt de databasereferenties al kent (en bevoegd is om deze te kennen). Het tweede is het geval waarin u, de ontwikkelaar, probeert de databasegegevens geheim te houden voor de persoon die het programma gebruikt.

Eerste geval:gebruiker is geautoriseerd om de inloggegevens van de database te kennen

In dit geval zal de oplossing die ik hierboven noemde werken. De Java Preference class zal de gebruikersnaam en het wachtwoord in platte tekst opslaan, maar het voorkeurenbestand is alleen leesbaar voor de geautoriseerde gebruiker. De gebruiker kan eenvoudig het XML-bestand met voorkeuren openen en de inloggegevens lezen, maar dat is geen veiligheidsrisico omdat de gebruiker de inloggegevens al kende.

Tweede geval:proberen inloggegevens voor de gebruiker te verbergen

Dit is het meer gecompliceerde geval:de gebruiker zou de inloggegevens niet moeten kennen, maar heeft nog steeds toegang tot de database nodig. In dit geval heeft de gebruiker die de applicatie uitvoert directe toegang tot de database, wat betekent dat het programma de inloggegevens van tevoren moet weten. De oplossing die ik hierboven noemde is niet geschikt voor dit geval. U kunt de inloggegevens van de database opslaan in een voorkeurenbestand, maar de gebruiker kan dat bestand lezen, aangezien zij de eigenaar zijn. Er is eigenlijk geen goede manier om deze case op een veilige manier te gebruiken.

Juiste casus:een architectuur met meerdere lagen gebruiken

De juiste manier om dit te doen is om een ​​middelste laag te hebben, tussen uw databaseserver en uw clienttoepassing, die individuele gebruikers verifieert en een beperkte reeks bewerkingen mogelijk maakt. Elke gebruiker zou zijn eigen inloggegevens hebben, maar niet voor de databaseserver. De inloggegevens zouden toegang geven tot de middelste laag (de bedrijfslogicalaag) en zouden voor elke gebruiker anders zijn.

Elke gebruiker zou zijn eigen gebruikersnaam en wachtwoord hebben, die zonder enig veiligheidsrisico lokaal kunnen worden opgeslagen in een voorkeurenbestand. Dit heet een drie-tier architectuur (de lagen zijn uw databaseserver, bedrijfslogicaserver en clienttoepassing). Het is ingewikkelder, maar het is echt de veiligste manier om dit soort dingen te doen.

De basisvolgorde van bewerkingen is:

  1. Cliënt authenticeert met bedrijfslogica-laag met behulp van de persoonlijke gebruikersnaam/wachtwoord van de gebruiker. De gebruikersnaam en het wachtwoord zijn bekend bij de gebruiker en zijn op geen enkele manier gerelateerd aan de inloggegevens van de database.
  2. Als de authenticatie slaagt, dient de client een verzoek in bij de Business Logic-laag om wat informatie uit de database te vragen. Bijvoorbeeld een inventarisatie van producten. Merk op dat het verzoek van de klant geen SQL-query is; het is een externe procedureaanroep zoals getInventoryList .
  3. De business logic-laag maakt verbinding met de database en haalt de gevraagde informatie op. De business logic-laag is verantwoordelijk voor het vormen van een veilige SQL-query op basis van het verzoek van de gebruiker. Alle parameters voor de SQL-query moeten worden opgeschoond om SQL-injectie-aanvallen te voorkomen.
  4. De bedrijfslogica-laag stuurt de inventarislijst terug naar de clienttoepassing.
  5. De klant toont de inventarislijst aan de gebruiker.

Merk op dat tijdens het hele proces de clienttoepassing nooit rechtstreeks verbinding maakt met de database . De bedrijfslogicalaag ontvangt een verzoek van een geverifieerde gebruiker, verwerkt het verzoek van de klant om een ​​inventarislijst en voert pas daarna een SQL-query uit.



  1. Bevat MS SQL Server tussen de bereikgrenzen?

  2. PHP:Waarschuwing:sort() verwacht dat parameter 1 array is, resource gegeven

  3. Hoe een aangepast type array door te geven aan de Postgres-functie

  4. SqlDataSourceEnumerator.Instance.GetDataSources() kan lokale SQL Server 2008-instantie niet vinden