ਇੱਕ ਲਰਨਿੰਗ ਪਲੇਟਫਾਰਮ ਜੋ ਵਿਦਿਆਰਥੀਆਂ ਨੂੰ MongoDB ਕੁਐਰੀਆਂ (queries) ਲਿਖਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ, ਉਸਨੇ Node.js ਦੇ vm ਮੋਡਿਊਲ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਹੈ ਅਤੇ ਹੁਣ ਚਲਾਉਣ ਤੋਂ ਪਹਿਲਾਂ ਹਰ ਕੁਐਰੀ ਨੂੰ ਇੱਕ ਐਬਸਟਰੈਕਟ ਸਿੰਟੈਕਸ ਟ੍ਰੀ (AST) ਵਿੱਚ ਪਾਰਸ (parse) ਕਰਦਾ ਹੈ। ਇਹ ਤਬਦੀਲੀ ਉਸ ਸੈਂਡਬਾਕਸ (sandbox) ਨੂੰ ਹਟਾ ਦਿੰਦੀ ਹੈ ਜਿਸ ਨੂੰ ਤੋੜਿਆ ਜਾ ਸਕਦਾ ਸੀ, ਜਿਸ ਨਾਲ ਬੈਕਐਂਡ ਨੂੰ ਅਜਿਹੇ ਕਿਸੇ ਵੀ ਅਨਿਯੰਤ ਕੋਡ ਤੋਂ ਬਚਾਇਆ ਜਾ ਸਕਦਾ ਹੈ ਜੋ ਇੱਕ ਗਲਤ ਤਰੀਕੇ ਨਾਲ ਬਣਾਈ ਗਈ ਸਟ੍ਰਿੰਗ ਰਾਹੀਂ ਇੰਜੈਕਟ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।

ਅਸਲ ਸੈਂਡਬਾਕਸ ਕਿਉਂ ਫੇਲ ਹੋ ਗਿਆ

ਪਹਿਲੀ ਇਮਪਲੀਮੈਂਟੇਸ਼ਨ (implementation) ਵਿੱਚ ਇੱਕ ਲਾਈਵ ਡਾਟਾਬੇਸ ਹੈਂਡਲ ਨੂੰ vm.runInContext ਕਾਲ ਵਿੱਚ ਲਪੇਟਿਆ ਗਿਆ ਸੀ ਅਤੇ ਰੈਗੂਲਰ ਐਕਸਪ੍ਰੈਸ਼ਨ (regular expression) ਨਾਲ ਉਪਭੋਗਤਾਵਾਂ ਨੂੰ ਸੀਮਤ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਗਈ ਸੀ। ਇਸਨੇ ਸਿਰਫ਼ find ਜਾਂ aggregate ਵਰਗੇ ਮੈਥਡ ਨਾਮਾਂ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ; ਬਾਕੀ ਸਾਰੇ ਆਈਡੈਂਟੀਫਾਇਰਾਂ (identifiers) ਨੂੰ ਫਿਲਟਰ ਕੀਤਾ ਜਾਣਾ ਸੀ।

ਦੋ ਕਮੀਆਂ ਨੇ ਉਸ ਪਹੁੰਚ ਨੂੰ ਅਸੁਰੱਖਿਅਤ ਬਣਾ ਦਿੱਤਾ:

  • Regex ਫਿਲਟਰਿੰਗ ਨੂੰ ਬਾਈਪਾਸ (bypass) ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ। JavaScript ਕੋਡ ਨੂੰ ਕਿਸੇ ਵੀ ਪ੍ਰਾਪਰਟੀ ਤੱਕ ਪਹੁੰਚਣ ਲਈ ਬ੍ਰੈਕਟ ਨੋਟੇਸ਼ਨ (obj["constructor"]) ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ। ਇੱਕ ਹਮਲਾਵਰ Function ਕੰਸਟ੍ਰਕਟਰ (constructor) ਪ੍ਰਾਪਤ ਕਰ ਸਕਦਾ ਹੈ, ਇੱਕ ਨਵਾਂ ਫੰਕਸ਼ਨ ਬਣਾ ਸਕਦਾ ਹੈ, ਅਤੇ ਉਹ ਕੋਈ ਵੀ ਕੋਡ ਚਲਾ ਸਕਦਾ ਹੈ ਜੋ ਉਹ ਚਾਹੁੰਦਾ ਹੈ। ਰੈਗੈਕਸ (regex) ਕਦੇ ਵੀ ਅੰਡਰਲਾਈਂਗ ਪ੍ਰਾਪਰਟੀ ਐਕਸੈਸ ਨੂੰ ਨਹੀਂ ਦੇਖ ਸਕਦਾ ਕਿਉਂਕਿ ਸੋਸ (source) ਨੂੰ ਅਣਗਿਣਤ ਤਰੀਕਿਆਂ ਨਾਲ ਦੁਬਾਰਾ ਲਿਖਿਆ ਜਾ ਸਕਦਾ ਹੈ।
  • vm ਕੋਈ ਸੁਰੱਖਿਆ ਸੀਮਾ (security boundary) ਨਹੀਂ ਹੈ। Node ਦੇ ਦਸਤਾਵੇਜ਼ਾਂ ਵਿੱਚ ਕਿਹਾ ਗਿਆ ਹੈ ਕਿ vm ਗਲੋਬਲ (global) ਆਬਜੈਕਟ ਨੂੰ ਅਲੱਗ ਕਰਦਾ ਹੈ ਪਰ ਪੂਰੇ ਪ੍ਰੋਸੈਸ (process) ਨੂੰ ਨਹੀਂ। ਸੈਂਡਬਾਕਸ ਵਿੱਚ ਇੱਕ ਲਾਈਵ ਡਾਟਾਬੇਸ ਕਨੈਕਸ਼ਨ ਇੰਜੈਕਟ ਕਰਕੇ, ਕੰਟੈਕਸਟ ਦੇ ਅੰਦਰਲੇ ਕੋਡ ਕੋਲ ਉਸ ਕਨੈਕਸ਼ਨ 'ਤੇ ਕੋਈ ਵੀ ਮੈਥਡ ਕਾਲ ਕਰਨ ਦੀ ਸਮਰੱਥਾ ਬਣੀ ਰਹੀ, ਜਿਸ ਵਿੱਚ ਡਾਟਾ ਲਿਖਣ ਜਾਂ ਡਿਲੀਟ ਕਰਨ ਵਾਲੇ ਮੈਥਡ ਵੀ ਸ਼ਾਮਲ ਸਨ। ਸੈਂਡਬਾਕਸ ਨੇ ਕੋਡ ਨੂੰ ਹੋਸਟ ਪ੍ਰੋਸੈਸ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰਨ ਤੋਂ ਨਹੀਂ ਰੋਕਿਆ।

AST-ਅਧਾਰਤ ਹੱਲ

ਟੀਮ ਨੇ ਕੋਡ ਐਗਜ਼ੀਕਿਊਸ਼ਨ (execution) ਨੂੰ ਸਟੈਟਿਕ ਐਨਾਲਿਸਿਸ (static analysis) ਨਾਲ ਬਦਲ ਦਿੱਤਾ ਹੈ। ਕੁਐਰੀ ਸਟ੍ਰਿੰਗਾਂ ਹੁਣ acorn ਪਾਰਸਰ ਨੂੰ ਭੇਜੀਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਇੱਕ AST ਬਣਾਉਂਦਾ ਹੈ—ਕੋਡ ਦੀ ਸਿੰਟੈਕਟਿਕ ਬਣਤਰ (syntactic structure) ਦਾ ਇੱਕ ਟ੍ਰੀ ਰਿਪ੍ਰਜ਼ੈਂਟੇਸ਼ਨ। AST ਦੀ ਸਖ਼ਤ ਵ੍ਹਾਈਟਲਿਸਟ (whitelist) ਦੇ ਵਿਰੁੱਧ ਨੋਡ-ਦਰ-ਨੋਡ ਜਾਂਚ ਕੀਤੀ ਜਾਂਦੀ ਹੈ:

  • ਲਿਟਰਲਜ਼ (Literals), ਐਰੇਜ਼ (arrays) ਅਤੇ ਆਬਜੈਕਟਸ (objects) ਦੀ ਇਜਾਜ਼ਤ ਸਿਰਫ਼ ਉਦੋਂ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ ਜਦੋਂ ਉਹ ਸਾਧਾਰਨ ਮੁੱਲਾਂ (plain values) ਵਜੋਂ ਦਿਖਾਈ ਦਿੰਦੇ ਹਨ।
  • ਮੈਥਡ ਕਾਲਜ਼ (Method calls) ਨੂੰ ਇੱਕ ਪਹਿਲਾਂ ਤੋਂ ਨਿਰਧਾਰਤ ਸੈੱਟ (find, sort, limit, ਆਦਿ) ਤੱਕ ਸੀਮਤ ਰੱਖਿਆ ਗਿਆ ਹੈ। ਕੋਈ ਵੀ ਹੋਰ ਕਾਲ ਰੱਦ ਕਰ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ।
  • ਕੰਪਿਊਟਡ ਪ੍ਰਾਪਰਟੀ ਐਕਸੈਸ (ਜਿਵੇਂ ਕਿ obj[expr]) ਜਾਂ ਕੋਈ ਵੀ ਨੋਡ ਕਿਸਮ ਜੋ ਸਪੱਸ਼ਟ ਤੌਰ 'ਤੇ ਸੂਚੀਬੱਧ ਨਹੀਂ ਹੈ, ਤੁਰੰਤ ਫੇਲ ਹੋ ਜਾਂਦੀ ਹੈ।

ਕਿਉਂਕਿ ਪਾਰਸਰ ਟ੍ਰੀ 'ਤੇ ਕੰਮ ਕਰਦਾ ਹੈ, ਨਾ ਕਿ ਰਅਅ ਟੈਕਸਟ (raw text) 'ਤੇ, ਇਸ ਲਈ ਇਸਨੂੰ ਬਦਲੀਆਂ ਸਪੈਲਿੰਗਾਂ ਜਾਂ ਬ੍ਰੈਕਟ-ਨੋਟੇਸ਼ਨ ਦੀਆਂ ਚਾਲਾਂ ਨਾਲ ਧੋਖਾ ਨਹੀਂ ਦਿੱਤਾ ਜਾ ਸਕਦਾ। ਇੱਕ ਕੰਸਟ੍ਰਕਟਰ ਚੇਨ ਜੋ ਰੈਗੈਕਸ ਤੋਂ ਬਚ ਕੇ ਨਿਕਲ ਸਕਦੀ ਸੀ, ਇੱਕ ਅਣਪਛਾਤੇ ਨੋਡ ਵਜੋਂ ਦਿਖਾਈ ਦਿੰਦੀ ਹੈ ਅਤੇ ਕੋਡ ਚੱਲਣ ਤੋਂ ਪਹਿਲਾਂ ਹੀ ਰੱਦ ਕਰ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ।

ਸੁਰੱਖਿਆ ਲਈ ਇਸਦਾ ਕੀ ਮਤਲਬ ਹੈ

ਨਵਾਂ ਡਿਜ਼ਾਈਨ "ਡੀਨਾਈ ਬਾਈ ਡਿਫਾਲਟ" (deny by default) ਫਿਲਾਸਫੀ ਦੀ ਪਾਲਣਾ ਕਰਦਾ ਹੈ:

  • ਤੈਅ ਕਰੋ ਕਿ ਕੀ ਇਜਾਜ਼ਤ ਹੈ, ਨਾ ਕਿ ਕੀ ਮਨ੍ਹਾ ਹੈ। ਟੈਕਸਟਅਲ ਅਲਾਓ-ਲਿਸਟਿੰਗ (allow-listing) ਮੁਕੰਮਲ ਨਹੀਂ ਹੋ ਸਕਦੀ; ਇੱਕ AST ਵਿੱਚ ਨੋਡ ਕਿਸਮਾਂ ਦਾ ਇੱਕ ਸੀਮਤ ਸੈੱਟ ਹੁੰਦਾ ਹੈ, ਜੋ ਮੁਕੰਮਲ ਜਾਂਚ ਨੂੰ ਸੰਭਵ ਬਣਾਉਂਦਾ ਹੈ।
  • ਸੈਂਡਬਾਕਸ ਦੇ ਅੰਦਰ ਕਦੇ ਵੀ ਲਾਈਵ ਸਰੋਤਾਂ (resources) ਨੂੰ ਪ੍ਰਗਟ ਨਾ ਕਰੋ। ਇੱਕ ਅਲੱਗ ਕੀਤੇ ਗਏ ਕੰਟੈਕਸਟ ਵਿੱਚ ਡਾਟਾਬੇਸ ਹੈਂਡਲ ਭੇਜਣ ਨਾਲ ਸੈਂਡਬਾਕਸਡ ਕੋਡ ਨੂੰ ਬੈਕਐਂਡ ਤੱਕ ਸ