Vad är en sårbarhet för rastillstånd?

Vad är en sårbarhet för rastillstånd?
Läsare som du hjälper till att stödja MUO. När du gör ett köp med hjälp av länkar på vår webbplats kan vi tjäna en affiliate-provision.

Ett racetillstånd uppstår när två operationer måste ske i en specifik ordning, men de kan köras i motsatt ordning.





Till exempel, i en flertrådad applikation kan två separata trådar komma åt en gemensam variabel. Som ett resultat, om en tråd ändrar värdet på variabeln, kan den andra fortfarande använda den äldre versionen och ignorera det senaste värdet. Detta kommer att orsaka oönskade resultat.





MAKEUSE AV DAGENS VIDEO

För att bättre förstå denna modell skulle det vara bra att undersöka processväxlingsprocessen för processorn noggrant.





Hur en processor växlar processer

Moderna operativsystem kan köra mer än en process samtidigt, så kallad multitasking. När man ser på denna process i termer av CPU:s exekveringscykel , kanske du upptäcker att multitasking egentligen inte existerar.

Istället växlar processorer hela tiden mellan processer för att köra dem samtidigt eller åtminstone agera som om de gör det. CPU:n kan avbryta en process innan den har slutförts och återuppta en annan process. Operativsystemet styr hanteringen av dessa processer.



hur man ser raderade meddelanden på fb

Till exempel fungerar Round Robin-algoritmen, en av de enklaste växlingsalgoritmerna, enligt följande:

  Ett diagram som visar 3 köade, vilande processer en 1 aktiv process som CPU:n kör för närvarande

I allmänhet tillåter denna algoritm att varje process körs under mycket små bitar av tid, som operativsystemet bestämmer. Detta kan till exempel vara en period på två mikrosekunder.





CPU:n tar varje process i tur och ordning och kör kommandon som körs i två mikrosekunder. Den fortsätter sedan till nästa process, oavsett om den nuvarande är klar eller inte. Alltså, ur en slutanvändares synvinkel, verkar mer än en process vara igång samtidigt. Men när du tittar bakom kulisserna gör CPU:n fortfarande saker i ordning.

Förresten, som diagrammet ovan visar, saknar Round Robin-algoritmen några optimerings- eller bearbetningsprioritetsuppfattningar. Som ett resultat är det en ganska rudimentär metod som sällan används i riktiga system.





För att förstå allt detta bättre, föreställ dig att två trådar körs. Om trådarna kommer åt en gemensam variabel kan ett rastillstånd uppstå.

Ett exempel på webbapplikation och tävlingsvillkor

Kolla in den enkla Flask-appen nedan för att reflektera över ett konkret exempel på allt du har läst hittills. Syftet med denna applikation är att hantera pengatransaktioner som kommer att ske på webben. Spara följande i en fil med namnet money.py :

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

class Account(db.Model):
id = db.Column(db.Integer, primary_key = True)
amount = db.Column(db.String(80), unique = True)

def __init__(self, count):
self.amount = amount

def __repr__(self):
return '' % self.amount

@app.route("/")
def hi():
account = Account.query.get(1) # There is only one wallet.
return "Total Money = {}".format(account.amount)

@app.route("/send/")
def send(amount):
account = Account.query.get(1)

if int(account.amount) < amount:
return "Insufficient balance. Reset money with /reset!)"

account.amount = int(account.amount) - amount
db.session.commit()
return "Amount sent = {}".format(amount)

@app.route("/reset")
def reset():
account = Account.query.get(1)
account.amount = 5000
db.session.commit()
return "Money reset."

if __name__ == "__main__":
app.secret_key = 'heLLoTHisIsSeCReTKey!'
app.run()

För att köra den här koden måste du skapa en post i kontotabellen och fortsätta transaktionerna över denna post. Som du kan se i koden är detta en testmiljö, så den gör transaktioner mot den första posten i tabellen.

from money import db 
db.create_all()
from money import Account
account = Account(5000)
db.session.add(account)
db.session.commit()

Du har nu skapat ett konto med ett saldo på 000. Slutligen, kör ovanstående källkod med följande kommando, förutsatt att du har paketen Flask och Flask-SQLAlchemy installerade:

python money.py 

Så du har webbapplikationen Flask som gör en enkel extraktionsprocess. Denna applikation kan utföra följande operationer med GET-förfrågningslänkar. Eftersom Flask körs på 5000-porten som standard är adressen du kommer åt den på 127.0.0.1:5000/ . Appen tillhandahåller följande slutpunkter:

  • 127.0.0.1:5000/ visar aktuellt saldo.
  • 127.0.0.1:5000/send/{amount} drar av beloppet från kontot.
  • 127.0.0.1:5000/återställning återställer kontot till 000.

Nu, i detta skede, kan du undersöka hur sårbarheten för rastillståndet uppstår.

Sannolikhet för en sårbarhet för rastillstånd

Ovanstående webbapplikation innehåller en möjlig sårbarhet för rastillstånd.

Föreställ dig att du har 000 att börja med och skapa två olika HTTP-förfrågningar som skickar . För detta kan du skicka två olika HTTP-förfrågningar till länken 127.0.0.1:5000/skicka/1 . Antag att så snart webbservern behandlar den första begäran, stoppar CPU:n denna process och behandlar den andra begäran. Till exempel kan den första processen stoppas efter att ha kört följande kodrad:

account.amount = int(account.amount) - amount 

Den här koden har beräknat en ny summa men har ännu inte sparat posten i databasen. När den andra begäran börjar kommer den att utföra samma beräkning, subtrahera från värdet i databasen— 000—och lagra resultatet. När den första processen återupptas kommer den att lagra sitt eget värde— 999—som inte kommer att återspegla det senaste kontosaldot.

Så två förfrågningar har slutförts, och var och en borde ha subtraherat från kontosaldot, vilket resulterar i ett nytt saldo på ,998. Men beroende på i vilken ordning webbservern bearbetar dem, kan det slutliga kontosaldot vara 999.

Föreställ dig att du skickar 128 förfrågningar om att göra en -överföring till målsystemet inom en tidsram på fem sekunder. Som ett resultat av denna transaktion kommer det förväntade kontoutdraget att vara 000 - 8 = 875. Men på grund av tävlingsförhållandena kan det slutliga saldot variera mellan 875 och 999.

Programmerare är en av de viktigaste komponenterna i säkerhet

I ett mjukvaruprojekt har du som programmerare en hel del ansvar. Exemplet ovan var för en enkel överföringsapplikation. Föreställ dig att arbeta med ett programvaruprojekt som hanterar ett bankkonto eller backend på en stor e-handelswebbplats.

Du måste vara bekant med sådana sårbarheter så att programmet du har skrivit för att skydda dem är fritt från sårbarheter. Detta kräver ett starkt ansvar.

En sårbarhet för rastillstånd är bara en av dem. Oavsett vilken teknik du använder måste du se upp för sårbarheter i koden du skriver. En av de viktigaste färdigheterna du kan förvärva som programmerare är förtrogenhet med mjukvarusäkerhet.