ഒരു Next.js API റൂട്ടിലെ റേസ് കണ്ടീഷൻ
ഒരു തവണ മാത്രം ഉപയോഗിക്കാവുന്ന കൂപ്പൺ ഒരു തവണ മാത്രമേ പ്രവർത്തിക്കാവൂ.
എന്നാൽ ഈ സാഹചര്യത്തിൽ, മുപ്പത് ആളുകൾക്ക് ഒരേ സമയം തന്നെ അത് ഉപയോഗിക്കാൻ സാധിക്കും.
ഇത് സംഭവിക്കുന്നത് Time-of-Check Time-of-Use (TOCTOU) എന്ന റേസ് കണ്ടീഷൻ (race condition) കാരണമാണ്.
ഈ പിശക് രണ്ട് ഘട്ടങ്ങളിലൂടെയാണ് സംഭവിക്കുന്നത്:
- ഘട്ടം 1: ഉപയോഗിച്ച എണ്ണം പരിശോധിക്കുന്നതിനായി സെർവർ ഡാറ്റാബേസ് വായിക്കുന്നു.
- ഘട്ടം 2: ആ എണ്ണം വർദ്ധിപ്പിക്കുന്നതിനായി സെർവർ രണ്ടാമതൊരു കമാൻഡ് അയക്കുന്നു.
നിങ്ങൾ ഒരേസമയം നിരവധി റിക്വസ്റ്റുകൾ അയക്കുകയാണെങ്കിൽ, ഈ രണ്ട് ഘട്ടങ്ങൾക്കിടയിൽ സെർവർ അവയെല്ലാം കൈകാര്യം ചെയ്യുന്നു.
എണ്ണം പൂജ്യമായിരിക്കുന്ന സമയത്ത് തന്നെ നിരവധി റിക്വസ്റ്റുകൾ അത് വായിക്കുന്നു. അവയെല്ലാം പരിശോധനയിൽ വിജയിക്കുന്നു. അവയെല്ലാം ഡിസ്കൗണ്ട് നൽകുന്നു. അവയെല്ലാം കൗണ്ടർ വർദ്ധിപ്പിക്കുന്നു.
ഫലം? ഒരാൾക്ക് വേണ്ടി മാത്രം ഉദ്ദേശിച്ച കൂപ്പൺ മുപ്പത് തവണ ഉപയോഗിക്കപ്പെടുന്നു.
കോഡ് റിവ്യൂ ചെയ്യുമ്പോൾ ഇത് ശ്രദ്ധിക്കാതെ പോകാൻ സാധ്യതയുണ്ട്. ഓരോ വരിയായി വായിക്കുമ്പോൾ ലോജിക് തികച്ചും ശരിയാണെന്ന് തോന്നും. എന്നാൽ വേഗതയും കൺകറൻസിയും (concurrency) പരിഗണിക്കുമ്പോഴാണ് ഈ പിശക് വെളിപ്പെടുന്നത്.
ഇത് എങ്ങനെ പരിഹരിക്കാം:
റീഡ് (read), റൈറ്റ് (write) കമാൻഡുകൾ പ്രത്യേകം ഉപയോഗിക്കുന്നത് നിർത്തുക. പകരം, ഒരു സിംഗിൾ അറ്റോമിക് ഓപ്പറേഷൻ (atomic operation) ഉപയോഗിക്കുക.
Prisma-യിൽ, WHERE clause-ൽ ഒരു കണ്ടീഷൻ നൽകിക്കൊണ്ട് updateMany ഉപയോഗിക്കാം:
• ഡാറ്റാബേസ് കണ്ടീഷൻ പരിശോധിക്കുകയും ഒരൊറ്റ പ്രക്രിയയിലൂടെ അപ്ഡേറ്റ് നടത്തുകയും ചെയ്യുന്നു. • എണ്ണം പരിധിയിൽ എത്തിയിട്ടുണ്ടെങ്കിൽ, അപ്ഡേറ്റ് ഉടൻ തന്നെ പരാജയപ്പെടുന്നു. • പരിശോധനയ്ക്കും റൈറ്റിനും ഇടയിൽ മറ്റൊരു റിക്വസ്റ്റും കടന്നുകൂടാൻ കഴിയില്ല.
മറ്റൊരു ഓപ്ഷൻ ഡാറ്റാബേസ് ട്രാൻസാക്ഷൻ (database transaction) ഉപയോഗിക്കുക എന്നതാണ്. ഇത് ഡാറ്റ ലോക്ക് ചെയ്യുന്നതിലൂടെ നിങ്ങളുടെ പ്രക്രിയ പൂർത്തിയാകുന്നതുവരെ മറ്റൊരു റിക്വസ്റ്റിനും അതിൽ മാറ്റം വരുത്താൻ കഴിയില്ലെന്ന് ഉറപ്പാക്കുന്നു.
SQLite-നെ സംബന്ധിച്ചിടത്തോളം, സിംഗിൾ അപ്ഡേറ്റ് കമാൻഡ് ആണ് ഏറ്റവും വിശ്വസനീയമായ രീതി.
എപ്പോഴും സ്വയം ചോദിക്കുക: ഒരേ മില്ലിസെക്കൻഡിൽ രണ്ട് റിക്വസ്റ്റുകൾ ഈ ലോജിക്കിൽ എത്തിയാൽ എന്ത് സംഭവിക്കും?
Source: https://dev.to/oopssec-store/racing-a-nextjs-api-route-coupon-abuse-with-prisma-and-sqlite-3gma