sql >> Databasteknik >  >> RDS >> Mysql

Bör primärnycklar för MySQL-tabeller exponeras?

Att exponera dina primärnycklar (särskilt om de är förutsägbara) är en sårbarhet som kallas Insecure Direct Object Reference.

Genom att ha en URL (eller någon annan klient tillhandahållen param) så här:

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

Du ger dina slutanvändare möjlighet att bråka med dessa variabler och skicka all data som de vill. Motåtgärden för att mildra denna sårbarhet är att skapa indirekta objektreferenser istället. Det kan låta som en stor förändring, men det behöver det inte nödvändigtvis vara. Du behöver inte gå och nycklara alla dina tabeller eller något, du kan göra det bara genom att vara smart med dina data genom att använda en indirekt referenskarta.

Tänk på detta:Du har en användare som gör ett köp på din webbplats. Och när det är dags att betala får de en rullgardinsmeny med deras kreditkortsnummer som du har "registrerat". Om du tittar på koden för rullgardinsmenyn ser du att kreditkortsnumren är kopplade till nycklarna 8055, 9044 och 10099.

Användaren kanske tittar på detta och tror att de ser mycket ut som auto-inkrementerande primärnycklar (användaren skulle förmodligen ha rätt). Så han börjar prova andra nycklar för att se om han kan betala med någon annans kort.

Nu tekniskt sett bör du ha kod på serversidan som säkerställer att det valda kortet är en del av användarens konto och att de kan använda det. Detta är ett konstruerat exempel. För närvarande kommer vi att anta att så inte är fallet eller att det här är en annan typ av form som kanske inte har den typen av kontroll på serversidan.

Så hur förhindrar vi slutanvändaren från att välja en nyckel som inte borde vara tillgänglig för dem?

Istället för att visa dem en direkt referens till posten i DB, ge dem en indirekt referens.

Istället för att lägga in DB-nycklarna i rullgardinsmenyn skapar vi en array på servern och stoppar in den i användarens session.

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

I rullgardinsmenyn ger vi nu referensen till indexet för arrayen där kortet är lagrat. Så istället för att se de faktiska nycklarna, kommer slutanvändaren att se värdena 0, 1 och 2, om de ser källan.

När formuläret skickas in kommer ett av dessa värden att skickas vidare. Sedan tar vi ut arrayen från användarens session och använder indexet för att få värdet. Den faktiska nyckeln har aldrig lämnat servern.

Och användaren kan skicka in olika värden hela dagen om han vill, men han kommer aldrig, aldrig, att få något annat resultat än sina egna kort, oavsett vilken åtkomstkontroll på serversidan som finns på plats.

Tänk dock på att när du använder det passerade indexet för att få ut värdet att om användaren bråkar med det kan du få några undantag (ArrayOutOfBounds, InvalidIndex, vad som helst). Så slå in det där i ett försök/fångst så att du kan undertrycka dessa fel och logga misslyckanden för att leta efter sprickförsök.

Hoppas detta hjälper.

För att läsa mer om Insecure Direct Object References, kolla in OWASP Top 10. Det är risknummer A4. https://www.owasp.org/index.php/Top_10_2010-A4 -Insecure_Direct_Object_References



  1. Snabbare sätt att ta bort matchande rader?

  2. Fråga två tabeller från olika scheman

  3. Problem med att binda en imploderad array till en mysql-förberedd sats

  4. Är det vettigt att använda ett index som kommer att ha en låg kardinalitet?