How to Stop Race condition on t3 pages api

dupe
18 Replies
Styly
StylyOP16mo ago
@cfkeef
Keef
Keef16mo ago
so how are you fetching this data if balance x is owned by user y, me looking up balance z as user a shouldn't really be a thing happening
Styly
StylyOP16mo ago
? on prisma
Keef
Keef16mo ago
share your query
Styly
StylyOP16mo ago
await prisma.token.update({where:{token:token!.token}, data:{used:true}});
await prisma.token.update({where:{token:token!.token}, data:{used:true}});
il use this one as it also applies, since its shorter
Keef
Keef16mo ago
This really shouldnt' be happening if your query looks something like
SELECT * FROM BALANCE WHERE id="jake"
SELECT * FROM BALANCE WHERE id="jake"
Another user querying for paul shouldn't get this unless you are querying very broadly in this case token narrows it for you Does balance have the token on it and you are using it to query?
Styly
StylyOP16mo ago
the problem is if you send 2 requests at this api endpoint you can use a token twice instead of once but those requests have to happen at the same time
Keef
Keef16mo ago
is the token some kind of session token? or csrf? or what Are you changing it after each request?
Styly
StylyOP16mo ago
its more like a giftcard, i do
let token = await prisma.token.findFirst({where:{token:req.body.token}})
if(token==null || token?.used) return res.status(418).end()
let token = await prisma.token.findFirst({where:{token:req.body.token}})
if(token==null || token?.used) return res.status(418).end()
before that query
Keef
Keef16mo ago
Is it possible for users to fetch more than one balance at a time?
Styly
StylyOP16mo ago
yes, this exploit applies to almost all of my api endpoints
Keef
Keef16mo ago
Yeah this is probably too simple for your use case if you are trying to limit requests to some balance or some limit What i've done in the past is use redis and you can just claim tokens from there. Its single threaded so atomicity is a given for you. Before each request claim a token by pulling it out of redis then send it away
Styly
StylyOP16mo ago
on, the createID they both run and check the if at the same time so they pass
Keef
Keef16mo ago
You can look at distributed locks if you want which try to solve this over a distributed system which serverless is
Styly
StylyOP16mo ago
there probably is a setting in prisma for this or next
Keef
Keef16mo ago
nope you can probably do locking in the database you use but i haven't touched that before Lock the token at the start of the request flow and when you query skip locked rows you just have to be careful about releasing the lock if the thing fails/succeeds idk if thats given
Styly
StylyOP16mo ago
yea its given
Styly
StylyOP16mo ago
@cfkeef i feel like this should be in the t3 wiki
Prisma
Transactions
Explore techniques for handling transactions with Prisma Client.
Want results from more Discord servers?
Add your server