sql >> Database >  >> RDS >> Mysql

Moeten primaire sleutels van MySQL-tabellen worden weergegeven?

Het blootleggen van uw primaire sleutels (vooral als ze voorspelbaar zijn) is een kwetsbaarheid die Insecure Direct Object Reference wordt genoemd.

Door een URL (of een andere door de klant opgegeven parameter) als volgt te gebruiken:

http://www.domain.com/myaccount?userid=12

U geeft uw eindgebruikers de mogelijkheid om met die variabelen te knoeien en alle gegevens door te geven die ze willen. De tegenmaatregel om dit beveiligingslek te verminderen, is om in plaats daarvan verwijzingen naar indirecte objecten te maken. Dit klinkt misschien als een grote verandering, maar dat hoeft het niet per se te zijn. U hoeft niet al uw tabellen of iets anders te gaan sleutelen, u kunt dit doen door slim om te gaan met uw gegevens door middel van een indirecte referentiekaart.

Overweeg dit:u heeft een gebruiker die een aankoop doet op uw site. En wanneer het tijd is om te betalen, krijgen ze een vervolgkeuzelijst te zien met de creditcardnummers van hen die u "in ons bestand" hebt. Als u naar de code voor de vervolgkeuzelijst kijkt, ziet u dat de creditcardnummers zijn gekoppeld aan de toetsen 8055, 9044 en 10099.

De gebruiker kan hiernaar kijken en denken dat ze veel lijken op automatisch oplopende primaire sleutels (de gebruiker zou waarschijnlijk gelijk hebben). Dus begint hij andere sleutels te proberen om te zien of hij met de kaart van iemand anders kan betalen.

Technisch gezien zou u aan de serverzijde een code moeten hebben die ervoor zorgt dat de geselecteerde kaart deel uitmaakt van het account van de gebruiker en dat deze deze kan gebruiken. Dit is een verzonnen voorbeeld. Voor nu gaan we ervan uit dat dit niet het geval is of dat dit een ander type formulier is dat misschien niet zo'n server-side controle heeft.

Dus hoe voorkomen we dat de eindgebruiker een sleutel kiest die niet voor hen beschikbaar zou moeten zijn?

In plaats van ze een directe verwijzing naar het record in de DB te laten zien, geef je ze een indirecte verwijzing.

In plaats van de DB-sleutels in de vervolgkeuzelijst te plaatsen, zullen we een array op de server maken en deze in de gebruikerssessie stoppen.

Array cards = new Array(3);
cards[0] = 8055;
cards[1] = 9044;
cards[2] = 10099;

In de vervolgkeuzelijst geven we nu de verwijzing naar de index van de array waar de kaart is opgeslagen. Dus in plaats van de daadwerkelijke sleutels te zien, ziet de eindgebruiker de waarden 0, 1 en 2 als ze de bron bekijken.

Bij het indienen van het formulier wordt een van die waarden doorgegeven. Vervolgens halen we de array uit de sessie van de gebruiker en gebruiken we de index om de waarde te krijgen. De eigenlijke sleutel heeft de server nooit verlaten.

En de gebruiker kan de hele dag door verschillende waarden doorgeven als hij dat wil, maar hij zal nooit een ander resultaat krijgen dan zijn eigen kaarten, ongeacht de server-side toegangscontrole die er is.

Houd er echter rekening mee dat wanneer u de doorgegeven index gebruikt om de waarde eruit te halen, u enkele uitzonderingen kunt krijgen (ArrayOutOfBounds, InvalidIndex, wat dan ook) als de gebruiker ermee knoeit. Dus stop dat spul in een try/catch, zodat je die fouten kunt onderdrukken en de mislukkingen kunt loggen om te zoeken naar kraakpogingen.

Ik hoop dat dit helpt.

Om meer te lezen over onveilige directe objectreferenties, bekijk de OWASP Top 10. Het is risiconummer A4. https://www.owasp.org/index.php/Top_10_2010-A4 -Insecure_Direct_Object_Referenties



  1. hoe de functie string left te gebruiken in hql

  2. Hoe kan ik een tabel in Oracle beschrijven zonder de opdracht DESCRIBE te gebruiken?

  3. XML importeren met inhoud gespecificeerd als attributen in een MySQL-tabel?

  4. hoe selecteer je alleen een rij met een maximale reeks zonder een subquery te gebruiken?