ഒരു GET collection endpoint-ൽ സുരക്ഷാ പരിശോധന (security check) വിട്ടുപോയതിനാൽ, അടിസ്ഥാനപരമായ ഒരു CoopCycle അക്കൗണ്ടുള്ള ആർക്കും ഒരു shared instance-ലെ എല്ലാ സ്റ്റോറുകളുടെയും പൂർണ്ണമായ അഡ്രസ് ബുക്ക് എടുക്കാൻ സാധിച്ചു. ഇത് എണ്ണമറ്റ ഉപഭോക്താക്കളുടെ പേരുകളും തെരുവുപേരുകളും പോസ്റ്റ് കോഡുകളും വെളിപ്പെടുത്തി. ഈ പിഴവ് രണ്ട് ദിവസത്തിനുള്ളിൽ പരിഹരിച്ചു (patched), ഉപയോക്താക്കൾ ഏറ്റവും പുതിയ പതിപ്പിലേക്ക് അപ്‌ഗ്രേഡ് ചെയ്യാൻ നിർദ്ദേശിക്കുന്നു.

ചോർച്ച എങ്ങനെ സംഭവിച്ചു

ഫുഡ്-ഡെലിവറി സഹകരണ സംഘങ്ങൾ (food-delivery cooperatives) ഉപയോഗിക്കുന്ന ഒരു ഓപ്പൺ സോഴ്സ് ലോജിസ്റ്റിക്സ് പ്ലാറ്റ്‌ഫോമായ CoopCycle, അതിന്റെ API നിർവചിക്കുന്നത് PHP ഫ്രെയിംവർക്കായ API Platform ഉപയോഗിച്ചാണ്. ആ ഫ്രെയിംവർക്കിൽ ഓരോ ഓപ്പറേഷനും (POST, GET, മുതലായവ) ഒരു സുരക്ഷാ പ്രകടനവുമായി (security expression) ജോഡി ചേർക്കേണ്ടതുണ്ട്; ഈ പ്രകടനം ഒഴിവാക്കിയാൽ, ഫ്രെയിംവർക്ക് യാതൊരു ഓതറൈസേഷൻ പരിശോധനയും കൂടാതെ കോഡ് പ്രവർത്തിപ്പിക്കുന്നു.

ഒരു സ്റ്റോറിന്റെ അഡ്രസ് ലിസ്റ്റ് നിർമ്മിക്കുകയോ പുതുക്കുകയോ ചെയ്യുന്ന POST റിക്വസ്റ്റിനെ ഡെവലപ്പർമാർ is_granted('edit', object) എന്ന സ്റ്റാൻഡേർഡ് പ്രകടനത്തിലൂടെ സംരക്ഷിച്ചിരുന്നു. ഇത് പ്രവർത്തിക്കുന്നത് ആ റിക്വസ്റ്റ് ഒരു സിംഗിൾ സ്റ്റോർ എൻ്റിറ്റിയെ ലക്ഷ്യം വെക്കുന്നതുകൊണ്ടാണ്, ഇത് ഫ്രെയിംവർക്കിന് വിലയിരുത്താൻ ഒരു കൃത്യമായ "object" നൽകുന്നു.

ഇതേ റിസോഴ്സ് വായിക്കുന്ന GET റിക്വസ്റ്റ് ഒരു കളക്ഷനെയാണ് ലക്ഷ്യം വെക്കുന്നത്: /api/stores/{id}/addresses. ഒരു കളക്ഷനിൽ ഒറ്റപ്പെട്ട ഒരു ഒബ്ജക്റ്റ് ഇല്ല, അതിനാൽ ഇതേ is_granted('edit', object) പ്രകടനം അവിടെ പ്രയോഗിക്കാൻ കഴിയില്ല. ഡെവലപ്പർമാർ സുരക്ഷാ വരി ഒഴിവാക്കിയതിനാൽ, ടെനൻസി (tenancy) പരിഗണിക്കാതെ തന്നെ ഏതൊരു ഓതറൈസ്ഡ് യൂസർക്കും ഫ്രെയിംവർക്ക് അഡ്രസ് ഡാറ്റ നൽകി.

ഒരു shared CoopCycle ഇൻസ്റ്റൻസിൽ, ഒരു ദുരുദ്ദേശ്യപരമായ ഉപയോക്താവിന് (malicious user) സ്റ്റോർ ഐഡികൾ പരിശോധിച്ചുകൊണ്ട് (iterate), എൻഡ്‌പോയിന്റിലേക്ക് GET റിക്വസ്റ്റുകൾ അയച്ചുകൊണ്ട് സിസ്റ്റത്തിൽ സൂക്ഷിച്ചിട്ടുള്ള ഓരോ ഉപഭോക്താവിന്റെയും വീട്ടുപേരുകൾ ശേഖരിക്കാൻ (scrape) സാധിക്കുമായിരുന്നു. ഒരു സാധാരണ അക്കൗണ്ടിൽ കൂടുതൽ അധികാരം (privileges) ആവശ്യമില്ലായിരുന്നു.

ബഗ് എന്തുകൊണ്ട് നിലനിന്നു

ഈ പ്രശ്നം വെറുമൊരു അശ്രദ്ധ കൊണ്ടല്ല ഉണ്ടായത്. "ഉപയോക്താവ് കളക്ഷനിലെ ഓരോ ഒബ്ജക്റ്റും ഉള്ള അതേ ടെനന്റിൽ (tenant) തന്നെയായിരിക്കണം" എന്ന് പ്രകടിപ്പിക്കാൻ API Platform-ന്റെ ഡിക്ലറേറ്റീവ് സുരക്ഷാ മോഡലിന് (declarative security model) നേരിട്ടുള്ള മാർഗ്ഗമില്ല. ഫ്രെയിംവർക്ക് ഓതറൈസേഷൻ പ്രയാസകരമാക്കിയ ഇടത്താണ് ആ വിട്ടുപോയ കോഡ് വരാനുണ്ടായിരുന്നത്.

പ്രശ്നം കൂടുതൽ സങ്കീർണ്ണമാക്കിയത് പ്രോജക്റ്റിന്റെ ടെസ്റ്റ് സ്യൂട്ട് (test suite) ആണ്; എല്ലാ അഡ്രസ്സുകളും അടങ്ങിയ GET റെസ്പോൺസ് എന്നത് പ്രതീക്ഷിച്ച രീതിയിലുള്ള പെരുമാറ്റമാണെന്ന് അത് ഉറപ്പിച്ചു പറഞ്ഞു. മറ്റൊരു വിധത്തിൽ പറഞ്ഞാൽ, ടെസ്റ്റിംഗിനായി ഉപയോഗിച്ച ഫിക്സ്ചറുകൾ (fixtures) ക്രോസ്-ടെനന്റ് ആക്സസ് അനുവദിച്ചിരുന്നതിനാൽ ഓട്ടോമേറ്റഡ് ടെസ്റ്റുകൾ വിജയിച്ചു, ഇത് സുരക്ഷാ വീഴ്ചയെ മറച്ചുവെച്ചു. ഈ സാഹചര്യത്തിൽ, പച്ച നിറത്തിൽ കാണിച്ച ടെസ്റ്റ് സ്യൂട്ട് സുരക്ഷയെക്കുറിച്ച് തെറ്റായ ഒരു തോന്നൽ നൽകി.

ആർക്കാണ് നേട്ടവും ആർക്കാണ് നഷ്ടവും

  • ഉപഭോക്താക്കൾ: അവരുടെ വ്യക്തിഗത വിവരങ്ങൾ (PII) – പൂർണ്ണമായ പേരുകളും വീട്ടുപേരുകളും – പ്ലാറ്റ്‌ഫോമിലുള്ള ആർക്കും കാണാൻ സാധിക്കുന്ന രീതിയിൽ വെളിപ്പെട്ടു. ഡാറ്റ പരസ്യമായി പോസ്റ്റ് ചെയ്തിട്ടില്ലെങ്കിലും, ഈ ലംഘനം ഒന്നിലധികം സഹകരണ സംഘങ്ങളുടെ സ്വകാര്യതയെ ബാധിച്ചു.
  • CoopCycle ഉപയോഗിക്കുന്ന സഹകരണ സംഘങ്ങൾ: ടെനന്റ് ഡാറ്റ സംരക്ഷിക്കാനുള്ള പ്ലാറ്റ്‌ഫോമിന്റെ കഴിവിനെക്കുറിച്ചുള്ള വിശ്വാസം തകർന്നു. ഇതുവരെ അപ്‌ഗ്രേഡ് ചെയ്യാത്ത ഏതൊരു സഹകരണ സംഘത്തിനും വിവരങ്ങൾ വെളിപ്പെടാനുള്ള അപകടസാധ്യത നേരിടേണ്ടി വന്നു.
  • CoopCycle മെയിന്റൈനർമാർ: രണ്ട് ദിവസത്തിനുള്ളിൽ പാച്ച് (patch) നൽകുകയും റഗ്രഷൻ ടെസ്റ്റുകൾ (regression tests) ചേർക്കുകയും ചെയ്തുകൊണ്ടുള്ള അവരുടെ വേഗത്തിലുള്ള പ്രതികരണം, ദുരുപയോഗം ചെയ്യപ്പെടാനുള്ള സാധ്യത കുറയ്ക്കുകയും ഉത്തരവാദിത്തമുള്ള ഓപ്പൺ സോഴ്സ് മേൽനോട്ടം പ്രകടിപ്പിക്കുകയും ചെയ്തു. എന്നിരുന്നാലും, ഈ സംഭവം സുരക്ഷാ പരിശോധനാ പ്രക്രിയകൾ കൂടുതൽ കർശനമാക്കേണ്ടതിന്റെ ആവശ്യകതയെ, പ്രത്യേകിച്ച് ഫ്രെയിംവർക്ക് അടിസ്ഥാനമാക്കിയുള്ള ഡിഫോൾട്ടുകളെക്കുറിച്ച് (framework-driven defaults) ഓർമ്മിപ്പിക്കുന്നു.

ഡെവലപ്പർമാരും ഓഡിറ്റർമാരും ശ്രദ്ധിക്കേണ്ട കാര്യങ്ങൾ

  • ഓപ്പറേഷൻ അസിമെട്രി (Operation asymmetry): ഒരു പാത്തിലെ POST (അല്ലെങ്കിൽ മറ്റേതെങ്കിലും മാറ്റം വരുത്തുന്ന ഓപ്പറേഷൻ) സംരക്ഷിക്കപ്പെട്ടിട്ടുണ്ടെങ്കിലും അതിന് അനുബന്ധമായ GET ഓപ്പൺ ആണെങ്കിൽ, ആ വ്യത്യാസം ഒരു മുന്നറിയിപ്പാണ് (red flag). റിസോഴ്സ് സംരക്ഷിക്കാനുള്ള ഡെവലപ്പർമാരുടെ ഉദ്ദേശ്യം POST വഴി വ്യക്തമാണ്.
  • കളക്ഷൻ എൻഡ്‌പോയിന്റുകൾ: ഒരു ഐറ്റത്തിന് പകരം ഒരു ലിസ്റ്റ് നൽകുന്നവ പലപ്പോഴും സാധാരണ സുരക്ഷാ രീതികൾക്ക് പുറത്തായിരിക്കും. ബൾക്ക് റീഡുകൾക്കായി (bulk reads) ഓതറൈസേഷൻ പരിശോധനകൾ പ്രത്യേകം ചേർത്തിട്ടുണ്ടെന്ന് ഉറപ്പുവരുത്തുക.
  • ടെസ്റ്റ് സ്യൂട്ടിന്റെ യാഥാർത്ഥ്യം: ഫിക്സ്ചറുകൾ യഥാർത്ഥ ടെനൻസി പരിധികൾ പ്രതിഫലിപ്പിക്കുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക. ക്രോസ്-ടെനന്റ് ഡാറ്റാ ചോർച്ചയെ സാധൂകരിക്കുന്ന ഒരു പാസ്സ് ആയ ടെസ്റ്റ് ഒരു മുന്നറിയിപ്പാണ്, അല്ലാതെ ഒരു പച്ചക്കൊടിയല്ല.

പരിഹാരവും അടുത്ത ഘട്ടങ്ങളും

സുരക്ഷാ വീഴ്ച റിപ്പോർട്ട് ചെയ്തതിന് ശേഷം, CoopCycle കോർ ടീം GET കളക്ഷൻ ഓപ്പറേഷനിലേക്ക് വിട്ടുപോയ സുരക്ഷാ പ്രകടനവും, സിംഗിൾ-ഐറ്റം, കളക്ഷൻ എൻഡ്‌പോയിന്റുകൾ എന്നിവയ്‌ക്കായി ടെനന്റ് ഐസൊലേഷൻ (tenant isolation) നടപ്പിലാക്കുന്ന റഗ്രഷൻ ടെസ്റ്റുകളും അവതരിപ്പിച്ചു. ഈ പാച്ച് സോഫ്റ്റ്‌വെയറിന്റെ അടുത്ത പതിപ്പിൽ ലഭ്യമാക്കി.

CoopCycle ഉപയോക്താക്കൾ ചെയ്യേണ്ടത്:

  1. സോഫ്റ്റ്‌വെയറിന്റെ ഏറ്റവും പുതിയ പതിപ്പാണ് ഉപയോഗിക്കുന്നതെന്ന് ഉറപ്പുവരുത്തുക.
  2. സമാനമായ കളക്ഷൻ-ലെവൽ വിടവുകൾ ഉണ്ടാക്കാൻ സാധ്യതയുള്ള കസ്റ്റം എക്സ്റ്റൻഷനുകളോ പ്ലഗിനുകളോ പരിശോധിക്കുക.
  3. എല്ലാ API റൂട്ടുകളിലുമുള്ള റീഡ്/റൈറ്റ് അസിമെട്രികൾക്ക് (read/write asymmetries) മുൻഗണന നൽകിക്കൊണ്ട് സുരക്ഷാ സ്കാനുകൾ വീണ്ടും നടത്തുക.

ചുരുക്കത്തിൽ

സുരക്ഷാ ക്രമീകരണങ്ങൾ ഡിക്ലറേറ്റീവ് (declarative) ആക്കുന്ന ഫ്രെയിംവർക്കുകൾ, ഡെവലപ്പർമാർ ഒറ്റപ്പെട്ട ഒബ്ജക്റ്റുകൾക്ക് (single objects) മാത്രം പ്രവർത്തിക്കുന്ന പാറ്റേണുകളെ ആശ്രയിക്കുമ്പോൾ അപകടകരമായ വിടവുകൾ മറച്ചുവെച്ചേക്കാം. ഒരു എൻഡ്പോയിന്റിന്റെ റീഡ് സൈഡിലും (read side) റൈറ്റ് സൈഡിലും (write side) ഒരേ സുരക്ഷാ സംവിധാനം (guard) തന്നെയാണോ ഉള്ളതെന്ന ലളിതമായ ഒരു പരിശോധന—പച്ച നിറത്തിലുള്ള ടെസ്റ്റ് സ്യൂട്ടുകൾക്ക് (green test suites) പിന്നിൽ മറഞ്ഞിരിക്കാൻ സാധ്യതയുള്ള ക്രോസ്-ടെനന്റ് ലീക്കുകളെ (cross-tenant leaks) വെളിപ്പെടുത്താൻ ഇതിലൂടെ സാധിക്കും.