Læsere som dig hjælper med at støtte MUO. Når du foretager et køb ved hjælp af links på vores websted, kan vi optjene en affiliate-kommission.

En race-tilstand opstår, når to operationer skal forekomme i en bestemt rækkefølge, men de kan køre i den modsatte rækkefølge.

For eksempel kan to separate tråde i en flertrådsapplikation få adgang til en fælles variabel. Som et resultat, hvis en tråd ændrer værdien af ​​variablen, kan den anden stadig bruge den ældre version og ignorere den nyeste værdi. Dette vil forårsage uønskede resultater.

For bedre at forstå denne model, ville det være godt at undersøge processorens processkifteproces nøje.

Hvordan en processor skifter processer

Moderne styresystemer kan køre mere end én proces samtidigt, kaldet multitasking. Når man ser på denne proces i forhold til CPU's udførelsescyklus, kan du opdage, at multitasking ikke rigtig eksisterer.

I stedet skifter processorer konstant mellem processer for at køre dem samtidigt eller i det mindste agere, som om de gør det. CPU'en kan afbryde en proces, før den er afsluttet, og genoptage en anden proces. Operativsystemet styrer styringen af ​​disse processer.

instagram viewer

For eksempel fungerer Round Robin-algoritmen, en af ​​de enkleste switching-algoritmer, som følger:

Generelt tillader denne algoritme, at hver proces kører i meget små bidder af tid, som operativsystemet bestemmer. For eksempel kan dette være en periode på to mikrosekunder.

CPU'en tager hver proces på skift og udfører kommandoer, der vil køre i to mikrosekunder. Derefter fortsætter den til næste proces, uanset om den nuværende er færdig eller ej. Fra en slutbrugers synspunkt ser det således ud til, at mere end én proces kører samtidigt. Men når du ser bag kulisserne, gør CPU'en stadig tingene i orden.

Forresten, som diagrammet ovenfor viser, mangler Round Robin-algoritmen nogen optimerings- eller behandlingsprioritetsbegreber. Som følge heraf er det en ret rudimentær metode, der sjældent bruges i rigtige systemer.

For at forstå alt dette bedre, forestil dig, at der kører to tråde. Hvis trådene får adgang til en fælles variabel, kan der opstå en racetilstand.

Et eksempel på webapplikation og racetilstand

Tjek den enkle Flask-app nedenfor for at reflektere over et konkret eksempel på alt, hvad du har læst indtil videre. Formålet med denne applikation er at administrere pengetransaktioner, der vil finde sted på nettet. Gem følgende i en fil med navnet money.py:

fra kolbe importere Kolbe
fra flask.ext.sqlalchemy importere SQLAlchemy

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

klasseKonto(db. Model):
id = db. Kolonne (db. Heltal, primær_nøgle = Rigtigt)
beløb = db. Kolonne (db. Snor(80), unik = Rigtigt)

def__i det__(selv, tælle):
selv.beløb = beløb

def__repr__(selv):
Vend tilbage '' % selv.beløb

@app.route("/")
defHej():
konto = Account.query.get(1) # Der er kun én tegnebog.
Vend tilbage "Samlede penge = {}".format (konto.beløb)

@app.route("/send/")
defsende(beløb):
konto = Account.query.get(1)

hvis int (konto.beløb) < beløb:
Vend tilbage "Utilstrækkelig balance. Nulstil penge med /reset!)"

konto.beløb = int (konto.beløb) - beløb
db.session.commit()
Vend tilbage "Beløb sendt = {}".format (beløb)

@app.route("/reset")
defNulstil():
konto = Account.query.get(1)
konto.beløb = 5000
db.session.commit()
Vend tilbage "Penge nulstillet."

hvis __navn__ == "__main__":
app.secret_key = 'heLLoTHisIsSeCReTKey!'
app.run()

For at køre denne kode skal du oprette en post i kontotabellen og fortsætte transaktionerne over denne post. Som du kan se i koden, er dette et testmiljø, så det foretager transaktioner mod den første post i tabellen.

fra penge importere db
db.opret_alle()
fra penge importere Konto
konto = Konto (5000)
db.session.tilføje(konto)
db.session.begå()

Du har nu oprettet en konto med en saldo på $5.000. Til sidst skal du køre ovenstående kildekode ved hjælp af følgende kommando, forudsat at du har Flask- og Flask-SQLAlchemy-pakkerne installeret:

pythonpenge.py

Så du har Flask-webapplikationen, der udfører en simpel ekstraktionsproces. Denne applikation kan udføre følgende handlinger med GET-anmodningslinks. Da Flask kører på 5000-porten som standard, er den adresse, du får adgang til den på 127.0.0.1:5000/. Appen giver følgende slutpunkter:

  • 127.0.0.1:5000/ viser den aktuelle saldo.
  • 127.0.0.1:5000/send/{amount} trækker beløb fra kontoen.
  • 127.0.0.1:5000/nulstil nulstiller kontoen til $5.000.

Nu, på dette stadium, kan du undersøge, hvordan racebetingelsens sårbarhed opstår.

Sandsynlighed for en racetilstandssårbarhed

Ovenstående webapplikation indeholder en mulig sårbarhed for racetilstand.

Forestil dig, at du har $5.000 til at starte med og opret to forskellige HTTP-anmodninger, der sender $1. Til dette kan du sende to forskellige HTTP-anmodninger til linket 127.0.0.1:5000/send/1. Antag, at så snart webserveren behandler den første anmodning, stopper CPU'en denne proces og behandler den anden anmodning. For eksempel kan den første proces stoppe efter at have kørt følgende kodelinje:

konto.beløb = int(konto.beløb) - beløb

Denne kode har beregnet en ny total, men har endnu ikke gemt posten i databasen. Når den anden anmodning begynder, vil den udføre den samme beregning, trække $1 fra værdien i databasen—$5.000—og gemme resultatet. Når den første proces genoptages, gemmer den sin egen værdi - $4.999 - som ikke afspejler den seneste kontosaldo.

Så to anmodninger er gennemført, og hver skal have trukket $1 fra kontosaldoen, hvilket resulterer i en ny saldo på $4.998. Men afhængigt af den rækkefølge, som webserveren behandler dem i, kan den endelige kontosaldo være $4.999.

Forestil dig, at du sender 128 anmodninger om at foretage en $1-overførsel til målsystemet inden for en tidsramme på fem sekunder. Som et resultat af denne transaktion vil det forventede kontoudtog være $5.000 - $128 = $4.875. På grund af løbets tilstand kan den endelige saldo dog variere mellem $4.875 og $4.999.

Programmører er en af ​​de vigtigste komponenter i sikkerhed

I et softwareprojekt har du som programmør en del ansvar. Eksemplet ovenfor var til en simpel pengeoverførselsapplikation. Forestil dig at arbejde på et softwareprojekt, der administrerer en bankkonto eller backend på et stort e-handelswebsted.

Du skal være bekendt med sådanne sårbarheder, så det program, du har skrevet for at beskytte dem, er fri for sårbarheder. Dette kræver et stærkt ansvar.

En racetilstandssårbarhed er kun en af ​​dem. Uanset hvilken teknologi du bruger, skal du være opmærksom på sårbarheder i den kode, du skriver. En af de vigtigste færdigheder, du kan tilegne dig som programmør, er fortrolighed med softwaresikkerhed.