Ծրագրային անվտանգության ամենահին դասերից մեկը մինչև հիմա էլ ամենակարևորներից է․ երբեք մի վստահեք input-ին միայն այն պատճառով, որ այն եկել է ձեր սեփական app-ից։
Կայքերը, API-ները, admin panel-ները և mobile app-երը բոլորը ստանում են input՝ օգտատերերից, սարքերից, form-երից, file-երից և այլ համակարգերից։ Այդ input-ը interface-ում կարող է նորմալ թվալ, բայց backend-ը երբեք չպետք է ենթադրի, որ այն անվտանգ է, ամբողջական է, ճիշտ type ունի կամ ազնիվ է։
Հենց դրա համար input validation-ը մինչև հիմա այսքան կարևոր է։ Շատ լուրջ bug-եր սկսվում են այն պահից, երբ համակարգը ընդունում է տվյալ, որը պետք է մերժեր։
Պարզ իրական օրինակ
Պատկերացրեք՝ checkout API-ն սպասում է՝
- վավեր product ID
- զրոյից մեծ quantity
- price, որը պետք է գա server-ից
- delivery address ճիշտ format-ով
Հիմա պատկերացրեք, որ developer-ը չափազանց շատ է վստահում client-ին։ Frontend-ը quantity-ի համար ցույց է տալիս միայն 1-ից 10 տարբերակներ, և backend-ը ենթադրում է, որ օգտատերը ուրիշ բան չի կարող ուղարկել։
Բայց հարձակվողին նորմալ interface-ը պետք չէ։ Նա կարող է փոխել request-ը և ուղարկել՝
- quantity: -5
- quantity: 100000
- price: 0.01
- անսպասելի fields, որոնք UI-ում երբեք չեն երևում
Եթե backend-ը ընդունի այդ արժեքները առանց ուժեղ validation-ի, համակարգը կարող է աշխատել այնպես, ինչպես արտադրանքը երբեք չէր նախատեսել։
Սա է հիմնական խնդիրը․ interface-երը ուղղորդում են օգտատիրոջը, բայց request-երն են որոշում իրականությունը։
Ինչու input validation-ը այսքան կարևոր է
- Հարձակվողները կարող են փոխել request-երը։ Նրանք սահմանափակված չեն ձեր form control-ներով կամ app screen-երով։
- Անսպասելի արժեքները կոտրում են ենթադրությունները։ Բացասական թվերը, հսկա payload-ները, սխալ format-ները կամ տարօրինակ state-երը կարող են trigger անել bug-եր։
- Վատ տվյալ կարող են ուղարկել նաև այլ համակարգեր։ Ամեն ռիսկային input չարամիտ մարդուց չէ գալիս։ Integration-ներն ու automation-ներն էլ կարող են սխալվել։
- Validation-ը պաշտպանում է և՛ անվտանգությունը, և՛ correctness-ը։ Այն կանխում է abuse-ը, բայց նաև նվազեցնում է սովորական product bug-երը։
Այսինքն՝ validation-ը միայն հարձակումներից պաշտպանվելու համար չէ։ Այն նաև համակարգը տրամաբանական վիճակում պահելու համար է։
Validation-ի տարածված ձախողումներ
- client-side check-երին վստահելը, կարծես դրանք բավարար են
- ընդունել fields, որոնք պետք է server-controlled լինեն
- թույլ տալ values expected range-ից դուրս
- չստուգել object ownership-ը կամ կապված entity ID-ները
- չափազանց թույլ ընդունել file-եր, URL-ներ կամ HTML content
- ենթադրել type correctness միայն այն պատճառով, որ frontend-ը typed է
Զարգացման ընթացքում այս ձախողումները փոքր են թվում։ Production-ում դրանք կարող են վերածվել fraud-ի, corruption-ի, broken logic-ի կամ security incident-ի։
Ինչ տեսք ունի իրականում լավ validation-ը
Յուրաքանչյուր կարևոր input-ի համար backend-ը պետք է տա այսպիսի հարցեր՝
- Այս field-ը պարտադի՞ր է։
- Type-ը ճի՞շտ է։
- Format-ը ճի՞շտ է։
- Value-ը թույլատրելի սահմանի մե՞ջ է։
- Օգտատերը ընդհանրապես պե՞տք է իրավունք ունենա այս field-ը դնել։
- Այս value-ը իմաստ ունի՞ այս business state-ում։
Սա է ուժեղ validation-ը։ Դա միայն payload-ի «գոյություն ունենալը» ստուգելը չէ։ Դա ստուգելն է՝ request-ը իմաստ ունի՞ համակարգի համար։
Client-side validation-ը օգտակար է, բայց բավարար չէ
Client-side validation-ը լավ է user experience-ի համար։ Այն օգնում է օգտատերերին արագ ուղղել սխալները և խուսափել ավելորդ failed request-երից։
Բայց client-side validation-ը security boundary չէ։ Այն կարելի է bypass անել, հեռացնել կամ վերագրել ցանկացած մարդու կողմից, ով վերահսկում է client environment-ը։
Հենց դրա համար անվտանգ կանոնը պարզ է՝ validate արեք client-ում usability-ի համար, server-ում՝ վստահության համար։
Թաքնված դասը․ համակարգերը հաճախ ձախողվում են եզրային դեպքերում
Շատ developer-ներ իրենց էներգիայի մեծ մասը կենտրոնացնում են happy path-ի վրա՝ ինչ պետք է լինի, երբ օգտատերը նորմալ է վարքագծում։ Դա պետք է, բայց բավարար չէ։
Իրական անվտանգության մտածելակերպը ուշադրություն է դարձնում եզրերին՝
- բացակա fields
- ավելորդ fields
- սխալ types
- անթույլատրելի state transition-ներ
- անսպասելի համադրություններ
- payload-ներ, որոնք տեխնիկապես հնարավոր են, բայց տրամաբանական չեն
Հենց այստեղ է հաճախ երևում՝ համակարգը իսկապես robust է, թե միայն արտաքինից polished։
Տարածված վտանգավոր հավատքը
Տարածված միտքն է՝ «Frontend-ն արդեն դա կանխում է»։
Այդ միտքը ստեղծում է փխրուն համակարգեր։ Frontend-ը կարող է ուղղորդել վարքը, բայց չի վերահսկում՝ ինչ է հասնում ձեր backend-ին։ Եթե backend-ը դա չի validate անում, համակարգը վստահում է մի բանի, որը իրականում չի վերահսկում։
Եզրակացություն
Input validation-ը կարևոր է, որովհետև համակարգերը պետք է ընդունեն միայն այն տվյալը, որը թույլատրելի է, ճիշտ ձևավորված է և կոնտեքստում իմաստ ունի։ Այն պաշտպանում է հարձակումներից, վատ ենթադրություններից, կոտրված workflow-ներից և նուրբ corruption-ից։ Եթե կայքը կամ mobile app-ը ընդունում է input, ուժեղ backend validation-ը optional polish չէ։ Դա արտադրանքի իրական անվտանգության մոդելի մասն է։