ವಿದ್ಯಾರ್ಥಿಗಳು MongoDB ಕ್ವೆರಿಗಳನ್ನು (queries) ರಚಿಸಲು ಅನುಮತಿಸುವ ಕಲಿಕಾ ವೇದಿಕೆಯು Node.js ನ vm ಮಾಡ್ಯೂಲ್ ಅನ್ನು ಕೈಬಿಟ್ಟಿದೆ ಮತ್ತು ಈಗ ಪ್ರತಿಯೊಂದು ಕ್ವೆರಿಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಮೊದಲು ಅಬ್ಸ್ಟ್ರಾಕ್ಟ್ ಸಿಂಟ್ಯಾಕ್ಸ್ ಟ್ರೀ (AST) ಗೆ ಪಾರ್ಸ್ ಮಾಡುತ್ತದೆ. ಈ ಬದಲಾವಣೆಯು ಮುರಿಯಬಹುದಾದ ಸ್ಯಾಂಡ್ಬಾಕ್ಸ್ ಅನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ, ಇದರಿಂದ ತಪ್ಪಾದ ಸ್ಟ್ರಿಂಗ್ ಮೂಲಕ ಹೂಡಿಕೆ ಮಾಡಬಹುದಾದ ಯಾವುದೇ ಅನಿರ್ದಿಷ್ಟ ಕೋಡ್ನಿಂದ (arbitrary code) ಬ್ಯಾಕೆಂಡ್ ಅನ್ನು ರಕ್ಷಿಸುತ್ತದೆ.
ಮೂಲ ಸ್ಯಾಂಡ್ಬಾಸ್ ಏಕೆ ವಿಫಲವಾಯಿತು
ಮೊದಲ ಅನುಷ್ಠಾನವು ಲೈವ್ ಡೇಟಾಬೇಸ್ ಹ್ಯಾಂಡಲ್ ಅನ್ನು vm.runInContext ಕರಲ್ನಲ್ಲಿ ಸುತ್ತುವರಿಯಿತು ಮತ್ತು ರೆಗ್ಯುಲರ್ ಎಕ್ಸ್ಪ್ರೆಶನ್ (regular expression) ಮೂಲಕ ಬಳಕೆದಾರರನ್ನು ನಿರ್ಬಂಧಿಸಲು ಪ್ರಯತ್ನಿಸಿತು. ಇದು find ಅಥವಾ aggregate ನಂತಹ ಮೆಥಡ್ ಹೆಸರುಗಳನ್ನು ಮಾತ್ರ ಅನುಮತಿಸಿತು; ಉಳಿದ ಎಲ್ಲಾ ಐಡೆಂಟಿಫೈಯರ್ಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಬೇಕೆಂದು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು.
ಆ ವಿಧಾನವು ಅಸುರಕ್ಷಿತವಾಗಲು ಎರಡು ದೋಷಗಳು ಕಾರಣವಾದವು:
- Regex ಫಿಲ್ಟರಿಂಗ್ ಅನ್ನು ಬೈಪಾಸ್ ಮಾಡಬಹುದು. ಬ್ರ್ಯಾಕೆಟ್ ನೋಟೇಶನ್ (
obj["constructor"]) ಬಳಸಿ ಯಾವುದೇ ಪ್ರಾಪರ್ಟಿಯನ್ನು ತಲುಪಲು JavaScript ಕೋಡ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ. ಒಬ್ಬ ದಾಳಿಕೋರನುFunctionಕನ್ಸ್ಟ್ರಕ್ಟರ್ ಅನ್ನು ಪಡೆಯಬಹುದು, ಹೊಸ ಫಂಕ್ಷನ್ ಅನ್ನು ನಿರ್ಮಿಸಬಹುದು ಮತ್ತು ತಮಗೆ ಬೇಕಾದ ಯಾವುದೇ ಕೋಡ್ ಅನ್ನು ಚಲಾಯಿಸಬಹುದು. ಮೂಲವನ್ನು ಅಸಂಖ್ಯಾತ ರೀತಿಯಲ್ಲಿ ಮರುಬರೆಯಬಹುದಾದ ಕಾರಣ, regex ಎಂದಿಗೂ ಅಡಗಿರುವ ಪ್ರಾಪರ್ಟಿ ಅಕ್ಸೆಸ್ ಅನ್ನು ನೋಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. vmಒಂದು ಸೆಕ್ಯೂರಿಟಿ ಬೌಂಡರಿ ಅಲ್ಲ. Node ನ ಡಾಕ್ಯುಮೆಂಟೇಶನ್ ಪ್ರಕಾರ,vmಕೇವಲ global ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಪ್ರತ್ಯೇಕಿಸುತ್ತದೆ ಆದರೆ ಇಡೀ ಪ್ರಕ್ರಿಯೆಯನ್ನು (process) ಅಲ್ಲ. ಸ್ಯಾಂಡ್ಬಾಸ್ಗೆ ಲೈವ್ ಡೇಟಾಬೇಸ್ ಕನೆಕ್ಷನ್ ಅನ್ನು ಸೇರಿಸುವ ಮೂಲಕ, ಆ ಕನೆಕ್ಷನ್ನಲ್ಲಿನ ಯಾವುದೇ ಮೆಥಡ್ ಅನ್ನು (ಡೇಟಾವನ್ನು ಬರೆಯುವ ಅಥವಾ ಅಳಿಸುವ ಮೆಥಡ್ಗಳು ಸೇರಿದಂತೆ) ಕರೆಯುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಸ್ಯಾಂಡ್ಬಾಸ್ ಒಳಗಿನ ಕೋಡ್ ಉಳಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಈ ಸ್ಯಾಂಡ್ಬಾಸ್ ಕೋಡ್ ಹೋಸ್ಟ್ ಪ್ರಕ್ರಿಯೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುವುದನ್ನು ತಡೆಯಲಿಲ್ಲ.
AST ಆಧಾರಿತ ಪರಿಹಾರ
ತಂಡವು ಕೋಡ್ ಎಕ್ಸಿಕ್ಯೂಶನ್ ಬದಲಿಗೆ ಸ್ಟ್ಯಾಟಿಕ್ ಅನಾಲಿಸಿಸ್ ಅನ್ನು ಅಳವಡಿಸಿಕೊಂಡಿದೆ. ಕ್ವೆರಿ ಸ್ಟ್ರಿಂಗ್ಗಳು ಈಗ acorn ಪಾರ್ಸರ್ ಅನ್ನು ಬಳಸುತ್ತವೆ, ಇದು ಕೋಡ್ನ ಸಿಂಟ್ಯಾಕ್ಟಿಕ್ ರಚನೆಯ ಮರದ ಪ್ರತಿನಿಧಿಯಾದ (tree representation) AST ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ. AST ಅನ್ನು ಕಟ್ಟುನಿಟ್ಟಾದ ವೈಟ್ಲಿಸ್ಟ್ (whitelist) ವಿರುದ್ಧ ನೋಡ್-ಬೈ-ನೋಡ್ ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ:
- Literals, arrays ಮತ್ತು objectsಗಳು ಕೇವಲ ಸಾಮಾನ್ಯ ಮೌಲ್ಯಗಳಾಗಿ (plain values) ಇದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಲ್ಪಡುತ್ತವೆ.
- Method callsಗಳನ್ನು ಮೊದಲೇ ನಿರ್ಧರಿಸಿದ ಸೆಟ್ಗೆ (
find,sort,limit, ಇತ್ಯಾದಿ) ಸೀಮಿತಗೊಳಿಸಲಾಗಿದೆ. ಯಾವುದೇ ಇತರ ಕರಲ್ ಅನ್ನು ತಿರಸ್ಕರಿಸಲಾಗುತ್ತದೆ. - Computed property access (ಉದಾಹರಣೆಗೆ,
obj[expr]) ಅಥವಾ ಸ್ಪಷ್ಟವಾಗಿ ಪಟ್ಟಿ ಮಾಡದ ಯಾವುದೇ ನೋಡ್ ಪ್ರಕಾರವು ತಕ್ಷಣವೇ ವಿಫಲಗೊಳ್ಳುತ್ತದೆ.
ಪಾರ್ಸರ್ ಕೇವಲ ಪಠ್ಯದ (raw text) ಬದಲಿಗೆ ಮರದ (tree) ಮೇಲೆ ಕೆಲಸ ಮಾಡುವುದರಿಂದ, ಪರ್ಯಾಯ ಕಾಗುಣಿತಗಳು ಅಥವಾ ಬ್ರ್ಯಾಕೆಟ್-ನೋಟೇಶನ್ ತಂತ್ರಗಳಿಂದ ಇದನ್ನು ವಂಚಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ರೆಗ ſ (regex) ಅನ್ನು ತಪ್ಪಿಸಿಕೊಂಡು ಹೋಗಬಹುದಾದ ಕನ್ಸ್ಟ್ರಕ್ಟರ್ ಚೈನ್, ಗುರುತ unrecognized ನೋಡ್ ಆಗಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ಯಾವುದೇ ಕೋಡ್ ಚಲಾಯಿಸುವ ಮೊದಲು ತಿರಸ್ಕರಿಸಲ್ಪಡುತ್ತದೆ.
ಇದು ಭದ್ರತೆಗೆ ಏನನ್ನು ಸೂಚಿಸುತ್ತದೆ
ಹೊಸ ವಿನ್ಯಾಸವು “deny by default” (ಡಿಫಾಲ್ಟ್ ಆಗಿ ನಿರಾಕರಿಸು) ತತ್ವವನ್ನು ಅನುಸರಿಸುತ್ತದೆ:
- ಏನು ಅನುಮತಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ವ್ಯಾಖ್ಯಾನಿಸಿ, ಏನನ್ನು ನಿಷೇಧಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನಲ್ಲ. ಪಠ್ಯದ ಮೂಲಕ ಅಲೋ-ಲಿಸ್ಟಿಂಗ್ (allow-listing) ಮಾಡುವುದು ಸಂಪೂರ್ಣವಾಗಿ ಅಸಾಧ್ಯ; ಆದರೆ AST ಗೆ ಸೀಮಿತ ಸಂಖ್ಯೆಯ ನೋಡ್ ಪ್ರಕಾರಗಳಿರುತ್ತವೆ, ಇದು ಸಂಪೂರ್ಣ ಪರಿಶೀಲನೆಯನ್ನು ಸಾಧ್ಯವಾಗಿಸುತ್ತದೆ.
- ಸ್ಯಾಂಡ್ಬಾಸ್ ಒಳಗೆ ಎಂದಿಗೂ ಲೈವ್ ಸಂಪನ್ಮೂಲಗಳನ್ನು (live resources) ಪ್ರದರ್ಶಿಸಬೇಡಿ. ಪ್ರತ್ಯೇಕಗೊಂಡ ಸಂದರ್ಭಕ್ಕೆ (isolated context) ಡೇಟಾಬೇಸ್ ಹ್ಯಾಂಡಲ್ ಅನ್ನು ವರ್ಗಾಯಿಸುವುದು ಸ್ಯಾಂಡ್ಬಾಕ್ಸ್ ಕೋಡ್ಗೆ ಬ್ಯಾಕೆಂಡ್ನೊಂದಿಗೆ ನೇರ ಸಂಪರ್ಕವನ್ನು ನೀಡುತ್ತದೆ. ಪಾರ್ಸರ್ ವಿಧಾನವು ಬಳಕೆದಾರರ ಕೋಡ್ಗೆ ಎಂದಿಗೂ ಲೈವ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ನೀಡುವುದಿಲ್ಲ; ಇದು ಕೇವಲ ಕ್ವೆರಿಯ ಉದ್ದೇಶವನ್ನು ಮಾತ್ರ ಹೊರತೆಗೆಯುತ್ತದೆ.
- ರಚನೆಯನ್ನು (structure) ವ್ಯಾಲಿಡೇಟ್ ಮಾಡಿ, ನಂತರ ಸುರಕ್ಷಿತವಾಗಿ ಕಾರ್ಯಗತಗೊಳಿಸಿ. ಒಮ್ಮೆ AST ವ್ಯಾಲಿಡೇಶನ್ ಅನ್ನು ಪಾಸಾದ ನಂತರ, ಪ್ಲಾಟ್ಫಾರ್ಮ್ ತನ್ನದೇ ಆದ ವಿಶ್ವಾಸಾರ್ಹ ಕೋಡ್ ಪಾತ್ ಬಳಸಿ ಅನುಮತಿಸಲಾದ ಕರಲ್ಗಳನ್ನು ನೈಜ MongoDB ಡ್ರೈವರ್ ಮೆಥಡ್ಗಳಾಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ.
ಮುಂದೆ ಯಾವುದನ್ನು ಗಮನಿಸಬೇಕು
- ನಿಮ್ಮ ಕೋಡ್ಬೇಸ್ನಲ್ಲಿ ಯಾವುದೇ
eval,new Function, ಅಥವಾvmಬಳಕೆಯನ್ನು ಆಡಿಟ್ (Audit) ಮಾಡಿ. ವೈಟ್ಲಿಸ್ಟ್ ಇದ್ದರೂ ಸಹ JavaScript ನ ಡೈನಾಮಿಕ್ ಸ್ವಭಾವದಿಂದ ಅದನ್ನು ತಪ್ಪಿಸಬಹುದು. - ಸಾಧ್ಯವಿರುವ ಕಡೆಗಳಲ್ಲಿ ಬಳಕೆದಾರರು ರಚಿಸುವ ಕೋಡ್ಗಾಗಿ AST ಪಾರ್ಸಿಂಗ್ ಅನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳಿ.
acorn,esprima, ಅಥವಾbabel-parserನಂತಹ ಲೈಬ್ರರಿಗಳು ಈ ಪರಿವರ್ತನೆಯನ್ನು ಸುಲಭಗೊಳಿಸುತ್ತವೆ. - ಲೈವ್ ಆಬ್ಜೆಕ್ಟ್ಗಳ ಪ್ರದರ್ಶನವನ್ನು (exposure) ಸೀಮಿತಗೊಳಿಸಿ. ಡೇಟಾಬೇಸ್ ಕನೆಕ್ಷನ್, ಫೈಲ್ ಹ್ಯಾಂಡಲ್ ಅಥವಾ ನೆಟ್ವರ್ಕ್ ಸಾಕೆಟ್ ಅನ್ನು ತಲುಪಲು ಸಾಧ್ಯವಾಗಬೇಕಾದಲ್ಲಿ, ನೀವು ಅನುಮತಿಸಲು ಉದ್ದೇಶಿಸಿರುವ ಕನಿಷ್ಠ ಮೆಥಡ್ಗಳನ್ನು ಮಾತ್ರ ಪ್ರದರ್ಶಿಸುವ ಪ್ರೊಕ್ಸಿ (proxy) ಮೂಲಕ ಅದನ್ನು ಸುತ್ತುವರಿಯಿರಿ.
- ಎಡ್ಜ್ ಕೇಸ್ಗಳ (edge cases) ಪರೀಕ್ಷೆಯನ್ನು ಸ್ವಯಂಚಾಲಿತಗೊಳಿಸಿ. ನಿಮ್ಮ ಪಾರ್ಸರ್ ಅವುಗಳನ್ನು ತಿರಸ್ಕರಿಸುತ್ತದೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಬ್ರ್ಯಾಕೆಟ್ ನೋಟೇಶನ್, ಕಂಪ್ಯೂಟೆಡ್ ಕೀಗಳು ಅಥವಾ ಪ್ರೊಟೊಟೈಪ್ ಮ್ಯಾನಿಪ್ಯುಲೇಷನ್ ಬಳಸುವ ಕ್ವೆರಿಗಳನ್ನು ರಚಿಸಿ.
ಸಾರಾಂಶ
ಸ್ಯಾಂಡ್ಬಾಸ್ ಆಗಿ vm.runInContext ಅನ್ನು ಅವಲಂಬಿಸುವುದು ಸುಳ್ಳು ಭದ್ರತೆಯ ಭಾವನೆಯನ್ನು ನೀಡುತ್ತದೆ; regex ಫಿಲ್ಟರ್ಗಳು JavaScript ನ ಹೊಂದಾಣಿಕೆಯ ಸಿಂಟ್ಯಾಕ್ಸ್ ಅನ್ನು ಒಳಗೊಳ್ಳಲು ಸಾಧ್ಯವಿಲ್ಲ ಮತ್ತು ಸ್ಯಾಂಡ್ಬಾಸ್ ಪ್ರಕ್ರಿಯೆಯ ಸಂಪನ್ಮೂಲಗಳನ್ನು (process resources) ಪ್ರತ್ಯೇಕಿಸುವುದಿಲ್ಲ. ಬಳಕೆದಾರರ ಇನ್ಪುಟ್ ಅನ್ನು AST ಗೆ ಪಾರ್ಸ್ ಮಾಡುವುದು ಮತ್ತು ನಿಮಗೆ ತಿಳಿದಿರುವ ನೋಡ್ಗಳನ್ನು ಮಾತ್ರ ವೈಟ್ಲಿಸ್ಟ್ ಮಾಡುವುದು, ದುಷ್ಟ ಕೋಡ್ ಚಲಾಯಿಸುವ ಮೊದಲು ಅದನ್ನು ತಡೆಯುವ ಒಂದು ಭದ್ರವಾದ ಮತ್ತು ಸುಸ್ಥಿರ ಅಡೆತಡೆಯನ್ನು ಒದಗಿಸುತ್ತದೆ. ನಿಮ್ಮ ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಬಳಕೆದಾರರಿಗೆ ಕೋಡ್ ಬರೆಯಲು ಅವಕಾಶ ನೀಡುತ್ತಿದ್ದರೆ, ಇಂದೇ eval-ಶೈಲಿಯ ಎಕ್ಸಿಕ್ಯೂಶನ್ ಅನ್ನು ಸ್ಟ್ಯಾಟಿಕ್ ಅನಾಲಿಸಿಸ್ನೊಂದಿಗೆ ಬದಲಾಯಿಸಿ.
