Jukwaa la kujifunzia linalowaruhusu wanafunzi kuunda maswali ya MongoDB limeacha kutumia moduli ya vm ya Node.js na sasa linachanganua kila swali kuwa mti wa muundo wa sintaksi (AST) kabla ya utekelezaji. Mabadiliko haya yanaondoa mfumo wa sandbox ambao ungeweza kuvunjika, hivyo kulinda mfumo wa nyuma (backend) dhidi ya kodi yoyote inayoweza kuingizwa kupitia mfululizo wa maandishi yaliyoharibika.
Kwa nini sandbox ya awali ilishindwa
Utekelezaji wa kwanza uliweka kiunganishi hai cha hifadhidata (database handle) ndani ya wito wa vm.runInContext na kujaribu kuwazuia watumiaji kwa kutumia kanuni ya kawaida (regular expression). Iliruhusu majina ya njia (methods) pekee kama vile find au aggregate; kila utambulisho mwingine ulikusudiwa kuchujwa.
Mapungufu mawili yalifanya njia hiyo isiwe salama:
- Uchujaji wa Regex unaweza kukwepwa. JavaScript inaruhusu kodi kutumia mfumo wa mabano (
obj["constructor"]) ili kufikia sifa (property) yoyote. Mshambuliaji anaweza kupata kiondoa (constructor) waFunction, kutengeneza kazi (function) mpya, na kuendesha kodi yoyote anayotaka. Regex haioni kamwe ufikiaji wa sifa ya msingi kwa sababu chanzo kinaweza kuandikwa upya kwa njia nyingi zisizo na kikomo. vmsi mpaka wa usalama. Maelezo ya Node yanasema kwambavmhutenga kitu cha global lakini si mchakato (process) mzima. Kwa kuingiza muunganisho hai wa hifadhidata kwenye sandbox, kodi iliyo ndani ya muktadha (context) ilibaki na uwezo wa kuita njia yoyote kwenye muunganisho huo, ikiwa ni pamoja na zile zinazoandika au kufuta data. Sandbox haikuzuia kodi hiyo kuathiri mchakato mkuu (host process).
Suluhisho linalozingatia AST
Timu ilibadilisha utekelezaji wa kodi kwa uchambuzi wa tuli (static analysis). Sasa, maandishi ya maswali yanaingizwa kwenye mchanganuzi wa acorn, ambao hutoa AST—uwakilishi wa mti wa muundo wa sintaksi wa kodi. AST huchunguzwa kipengele kwa kipengele (node-by-node) dhidi ya orodha ya ruhusa (whitelist) kali:
- Literals, arrays na objects zinaruhusiwa tu wakati zinapoonekana kama thamani za kawaida.
- Wito wa njia (Method calls) umezuiliwa kwenye seti iliyopangwa mapema (
find,sort,limit, n.k.). Wito mwingine wowote unakataliwa. - Ufikiaji wa sifa uliopigiwa hesabu (mfano,
obj[expr]) au aina yoyote ya node ambayo haijaorodheshwa wazi inasababisha kufeli mara moja.
Kwa sababu mchanganuzi hufanya kazi kwenye mti, si kwenye maandishi ghafi, hawezi kudanganywa na tahajia mbadala au mbinu za mfumo wa mabano. Mnyororo wa kiondoa (constructor chain) ambao ungepita kwenye regex utaonekana kama node isiyotambulika na utakatalikwa kabla ya kodi yoyote kuendeshwa.
Hii inamaanisha nini kwa usalama
Muundo mpya unafuata falsafa ya “kataa kwa kiasi cha msingi” (deny by default):
- Define kile kinachoruhusiwa, si kile kinachozuiwa. Orodha ya ruhusa ya maandishi haiwezi kuwa ya kina kabisa; AST ina seti maalum ya aina za node, jambo linalofanya ukaguzi wa kina uwezekane.
- Usitoe rasilimali hai ndani ya sandbox kamwe. Kupitisha kiunganishi cha hifadhidata kwenye muktadha uliotengwa kunatoa njia ya moja kwa moja kwa kodi ya sandbox kuelekea kwenye backend. Njia ya mchanganuzi haitoi kamwe kitu hai (live object) kwa kodi ya mtumiaji; inatoa tu nia ya swali.
- Hakiki muundo, kisha utekeleze kwa usalama. Mara tu AST inapopita uhakiki, jukwaa linatafsiri wito ulioruhusiwa kuwa njia halisi za programu ya MongoDB (MongoDB driver methods) kwa kutumia njia yake ya kodi inayofahamika.
Nini cha kufuatilia baadaye
- Kagua matumizi yoyote ya
eval,new Function, auvmkatika kodi yako. Hata orodha ya ruhusa inaweza kudhibitiwa na asili ya JavaScript ya mabadiliko (dynamic nature). - Tumia uchanganuzi wa AST kwa kodi inayozalishwa na mtumiaji kila inapowezekana. Maktaba kama
acorn,esprima, aubabel-parserhufanya mabadiliko hayo kuwa rahisi. - Weka mipaka ya ufikiaji wa vitu hai. Ikiwa muunganisho wa hifadhidata, kiunganishi cha faili, au socket ya mtandao lazima ifikiwe, kifunike kwenye proxy ambayo inatoa njia (methods) za chini kabisa unazokusudia kuruhusu.
- Weka mifumo ya kiotomatiki ya kujaribu hali za kipekee (edge cases). Tengeneza maswali yanayotumia mfumo wa mabano, funguo zilizopigiwa hesabu (computed keys), au urekebishaji wa prototype ili kuhakikisha mchanganuzi wako unayakataa.
Hitimisho
Kutegemea vm.runInContext kama sandbox kunatoa hisia ya uongo ya usalama; vichujio vya regex haviwezi kuimarisha sintaksi inayobadilika ya JavaScript, na sandbox haitengi rasilimali za mchakato. Kuchanganua ingizo la mtumiaji kuwa AST na kuweka orodha ya ruhusa kwa node unazozielewa pekee kunatoa kizuizi madhubuti na kinachoweza kudhibitiwa ambacho kinazuia kodi hasidi kabla haijaanza kufanya kazi. Ikiwa jukwaa lako linaruhusu watumiaji kuandika kodi, badilisha utekelezaji wa aina ya eval kwa uchambuzi wa tuli leo.
