Signed URL-കളെ തകരാറിലാക്കുന്ന ട്രാക്കിംഗ്-ലിങ്ക് ബഗ്
ഒരു ബഗ് നിങ്ങളുടെ കോഡിൽ ദീർഘകാലം ഒളിഞ്ഞിരിക്കാം. അത് മിക്ക ലിങ്കുകളിലും ശരിയായി പ്രവർത്തിക്കും. മാർക്കറ്റിംഗ് ലിങ്കുകളിൽ അത് പ്രശ്നമുണ്ടാക്കില്ല. എന്നാൽ ഏറ്റവും പ്രധാനപ്പെട്ട ലിങ്കുകളെ അത് തകരാറിലാക്കും.
എന്റെ mail-history എന്ന ടൂളിലാണ് ഞാൻ ഈ ബഗ് കണ്ടെത്തിയത്. ഇത് signed URL-കളെ തകരാറിലാക്കുന്നു. ഇമെയിൽ വെരിഫിക്കേഷനോ സുരക്ഷിതമായ ഡൗൺലോഡുകൾക്കോ വേണ്ടി ഉപയോഗിക്കുന്ന ലിങ്കുകളാണ് ഇവ.
ഇത് എങ്ങനെയാണ് സംഭവിച്ചത് എന്ന് നോക്കാം.
ക്ലിക്കുകൾ ട്രാക്ക് ചെയ്യുന്നതിനായി എന്റെ ടൂൾ ഇമെയിൽ HTML റീറൈറ്റ് ചെയ്യുന്നു. ഇത് ഒറിജിനൽ URL എടുത്ത്, അത് എൻക്രിപ്റ്റ് ചെയ്ത് ഒരു ട്രാക്കിംഗ് ലിങ്കാക്കി മാറ്റുന്നു. ഒരു ഉപയോക്താവ് ക്ലിക്ക് ചെയ്യുമ്പോൾ, ടൂൾ ആ URL ഡീക്രിപ്റ്റ് ചെയ്യുകയും അവരെ യഥാർത്ഥ ലക്ഷ്യസ്ഥാനത്തേക്ക് എത്തിക്കുകയും ചെയ്യുന്നു.
റെൻഡർ ചെയ്ത HTML-ൽ നിന്ന് URL എടുക്കാൻ തുടങ്ങിയപ്പോഴാണ് പ്രശ്നം തുടങ്ങിയത്.
Laravel-ഉം Blade-ഉം HTML അറ്റ്രിബ്യൂട്ടുകളെ എസ്കേപ്പ് (escape) ചെയ്യുന്നു. ഒരു URL-ലെ ampersand (&) ഒരു HTML എൻ്റിറ്റിയായി മാറുന്നു. അതായത്, & എന്നത് & ആയി മാറുന്നു.
ഒരു സാധാരണ ലിങ്കിനെ സംബന്ധിച്ചിടത്തോളം, ബ്രൗസർ ഇത് സ്വയമേവ ശരിയാക്കും. നിങ്ങൾ ഈ വ്യത്യാസം ശ്രദ്ധിക്കില്ല.
എന്നാൽ എന്റെ ടൂൾ ലിങ്ക് ഒരു ബ്രൗസറിലേക്കല്ല അയക്കുന്നത്. പകരം അത് ഒരു ഡീക്രിപ്ഷൻ ഫംഗ്ഷനിലേക്കാണ് (decryption function) അയക്കുന്നത്.
നിങ്ങളുടെ signed URL ഇപ്രകാരമാണെങ്കിൽ: https://example.com/verify?expires=123&signature=abc
HTML ഇപ്രകാരമായിരിക്കും: https://example.com/verify?expires=123&signature=abc
എന്റെ ടൂൾ & ഉള്ള വേർഷൻ എൻക്രിപ്റ്റ് ചെയ്യുന്നു. ഉപയോക്താവ് ക്ലിക്ക് ചെയ്യുമ്പോൾ, ടൂൾ അത് ഡീക്രിപ്റ്റ് ചെയ്യുകയും അവരെ വീണ്ടും & ഉള്ള വേർഷനിലേക്ക് തന്നെ എത്തിക്കുകയും ചെയ്യുന്നു.
Laravel ഈ & കാണുകയും സിഗ്നേച്ചർ തെറ്റാണെന്ന് കരുതുകയും ചെയ്യുന്നു. അങ്ങനെ വെരിഫിക്കേഷൻ പരാജയപ്പെടുന്നു.
ഇതിനുള്ള പരിഹാരം ഒരു വരി കോഡ് മാത്രമാണ്. എൻക്രിപ്ഷൻ നടക്കുന്നതിന് മുമ്പ് & എന്നതിനെ തിരികെ & ആക്കി മാറ്റാൻ ഞാൻ html_entity_decode ഉപയോഗിക്കുന്നു.
ഇത് ഡീക്രിപ്റ്റ് ചെയ്ത URL, ഒറിജിനൽ signed URL-മായി ബൈറ്റ്ാ ബൈറ്റായി (byte for byte) ഒത്തുപോകുന്നുവെന്ന് ഉറപ്പാക്കുന്നു.
നിങ്ങളുടെ ജോലിക്കായുള്ള ഒരു പാഠം:
- ഒരു ഫംഗ്ഷനിൽ ഉപയോഗിക്കാൻ റെൻഡർ ചെയ്ത HTML-ൽ നിന്ന് ഡാറ്റ എടുക്കുകയാണെങ്കിൽ, അത് എസ്കേപ്പ് ചെയ്യപ്പെട്ടതാണെന്ന് കരുതുക.
- ബ്രൗസറുകൾ തെറ്റുകൾ ക്ഷമിക്കും. എന്നാൽ എൻക്രിപ്ഷനും സിഗ്നേച്ചർ വാലിഡേഷനും അങ്ങനെയല്ല.
- ഒരു വരി കോഡ് ഉപയോഗിച്ചാണ് നിങ്ങൾ പരിഹാരം കാണുന്നതെങ്കിൽ, അതിനായി ഒരു ടെസ്റ്റ് എഴുതുക.
& ഉണ്ടോ എന്ന് പ്രത്യേകം പരിശോധിക്കുന്ന ഒരു ടെസ്റ്റ് ഞാൻ എഴുതിയിട്ടുണ്ട്. ഭാവിയിൽ ഒരു ഡെവലപ്പർ കോഡ് ക്ലീൻ ചെയ്യുന്നതിനിടെ എന്റെ ഈ പരിഹാരം നീക്കം ചെയ്താൽ, ആ ടെസ്റ്റ് ഉടൻ തന്നെ പരാജയപ്പെടും.
Source: https://dev.to/nasrulhazim/the-tracking-link-bug-that-only-breaks-signed-urls-38c