ಒಂದು ಸಾಲಿನ ಕೋಡ್ ನಿಮ್ಮ ಇಡೀ ಪ್ರವೇಶ ನಿಯಂತ್ರಣ ಮಾದರಿಯನ್ನು (access control model) ಅಳಿಸಿಹಾಕಬಲ್ಲದು. ರಿಕ್ವೆಸ್ಟ್ ಬಾಡಿಯನ್ನು (request body) ನೇರವಾಗಿ ಡೇಟಾಬೇಸ್ ಅಪ್‌ಡೇಟ್‌ಗೆ ಬಳಸಿದರೆ, ನಿಮ್ಮ ಸ್ಕೆಮಾವನ್ನು (schema) ಮರುಬರೆಯಲು ನೀವು ಕ್ಲೈಂಟ್‌ಗೆ ಪೆನ್ನು ನೀಡಿದಂತೆ. ಇದನ್ನೇ 'ಮಾಸ್ ಅಸೈನ್‌ಮೆಂಟ್' (Mass Assignment) ಎನ್ನಲಾಗುತ್ತದೆ. ಇದು ಯಾವುದೋ ಅಪರೂಪದ ಬಗ್ ಅಥವಾ ಅಂಚಿನಲ್ಲಿರುವ ಪ್ರಕರಣವಲ್ಲ. ಒಂದು API ಪೇಲೋಡ್ ಅನ್ನು ತನ್ನದೇ ಆದ ಅಪ್‌ಡೇಟ್ ಪಾಲಿಸಿ ಎಂದು ಪರಿಗಣಿಸಿದಾಗಲೆಲ್ಲಾ ಕಾಣಿಸಿಕೊಳ್ಳುವ ವಿನ್ಯಾಸದ ವೈಫಲ್ಯವಿದು.

await db.users.update(req.params.id, { ...req.body });

ಇದು ನೋಡಲು ಸುಲಭ ಮತ್ತು ಕ್ಲೀನ್ ಆಗಿ ಕಾಣುತ್ತದೆ. ಟೈಪಿಂಗ್ ಸಮಯವನ್ನು ಉಳಿಸುತ್ತದೆ. ಆದರೆ ಕೀಲಿಗಳನ್ನು (keys) ಕ್ಲೈಂಟ್ ನಿಯಂತ್ರಿಸುತ್ತದೆ. ಒಬ್ಬ ದಾಳಿಕೋರ ಸಾಮಾನ್ಯ ಪ್ರೊಫೈಲ್ ಅಪ್‌ಡೇಟ್‌ನಲ್ಲಿ "role": "admin", "accountId": "someone_else", ಅಥವಾ "credit": 99999" ಅನ್ನು ಸೇರಿಸಬಹುದು. ನಿಮ್ಮ ವ್ಯಾಲಿಡೇಶನ್ ಲೇಯರ್ ಆ ಮೌಲ್ಯಗಳು ಸ್ಟ್ರಿಂಗ್ ಅಥವಾ ನಂಬರ್ ಆಗಿವೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ, ಅವು ಸರಿಯಾಗಿವೆ ಎಂದು ಹೇಳಬಹುದು. ಆದರೆ, ಮೌಲ್ಯದ ಮಾನ್ಯತೆ (Validity) ಎಂದರೆ ಅಧಿಕಾರೀಕರಣ (Authorization) ಎಂದಲ್ಲ. ಒಬ್ಬ ಬಳಕೆದಾರರಿಗೆ ಗುರಿ ದಾಖಲೆಯ (target record) ಮಾಲೀಕತ್ವ ಇರಬಹುದು. ಆದರೆ ಅದರ ಒಳಗಿರುವ ಪ್ರತಿಯೊಂದು ಫೀಲ್ಡ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡುವ ಹಕ್ಕು ಅವರಿಗಿದೆ ಎಂದರ್ಥವಲ್ಲ.

ಮಾಸ್ ಅಸೈನ್‌ಮೆಂಟ್ (Mass Assignment) ವಾಸ್ತವವಾಗಿ ಹೇಗಿರುತ್ತದೆ

ಅಪಾಯವು ಅನುಕೂಲತೆಯಲ್ಲಿ ಅಡಗಿದೆ. ಫ್ರೇಮ್‌ವರ್ಕ್‌ಗಳು ಮತ್ತು ORMಗಳು JSON ಕೀಗಳನ್ನು ನೇರವಾಗಿ ಡೇಟಾಬೇಸ್ ಕಾಲಮ್‌ಗಳಿಗೆ ಮ್ಯಾಪ್ ಮಾಡುವುದನ್ನು ಅತ್ಯಂತ ಸುಲಭವಾಗಿಸಿವೆ. ನೀವು ಇದನ್ನು ಮಾಡಿದಾಗ, ಏನನ್ನು ಬದಲಾಯಿಸಬೇಕು ಎಂಬುದರ ಬಗ್ಗೆ ಡೇಟಾಬೇಸ್‌ಗೆ ಕ್ಲೈಂಟ್ ಹೇಳಿದ್ದನ್ನು ನಂಬಲು ನೀವು ಸೂಚಿಸುತ್ತಿದ್ದೀರಿ.

ತಮ್ಮ ಪ್ರೊಫೈಲ್ ಅಪ್‌ಡೇಟ್ ಮಾಡುವ ಬಳಕೆದಾರರು displayName ಮತ್ತು bio ಗೆ ಮಾನ್ಯವಾದ ಡೇಟಾವನ್ನು ಕಳುಹಿಸಬಹುದು, ಆದರೆ ಅದರ ಜೊತೆಗೆ role ಅಥವಾ balance ಅನ್ನು ಅಡಗಿಸಿ ಕಳುಹಿಸಬಹುದು. ನಿಮ್ಮ ಕಂಟ್ರೋಲರ್ ಕೇವಲ ಆ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಫಾರ್ವರ್ಡ್ ಮಾಡಿದರೆ, ಡೇಟಾಬೇಸ್ ಎಲ್ಲವನ್ನೂ ಬರೆಯುತ್ತದೆ. ವ್ಯಾಲಿಡೇಶನ್ ತಪ್ಪಾದ ಮೌಲ್ಯಗಳನ್ನು ಹಿಡಿಯುತ್ತದೆ. ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಕೀಗಳನ್ನು (malicious keys) ಹಿಡಿಯುವುದು ಅಪರೂಪ. "ಈ ಬಳಕೆದಾರರಿಗೆ ತಮ್ಮ ಪ್ರೊಫೈಲ್ ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಅನುಮತಿಯಿದೆ" ಎಂಬ ವ್ಯವಹಾರದ ನಿಯಮವು ಆ ಸಾಲಿನ ಪ್ರತಿಯೊಂದು ಕಾಲಮ್ ಮೇಲಿನ ಸರ್ವವ್ಯಾಪಿ ಅನುಮತಿಯಾಗಿ ಬದಲಾಗುತ್ತದೆ.

ಇದಕ್ಕೆ ಪರಿಹಾರವೆಂದರೆ ಹೆಚ್ಚಿನ ವ್ಯಾಲಿಡೇಶನ್ ಅಲ್ಲ. ಬದಲಾಗಿ ಕಟ್ಟುನಿಟ್ಟಾದ ಆರ್ಕಿಟೆಕ್ಚರ್ (architecture).

ಮೂರು ದ್ವಾರಗಳು (The Three Gates)

ಸುರಕ್ಷಿತ ರೂಪಾಂತರವು (mutation) ಸ್ಟೋರೇಜ್ ಅನ್ನು ತಲುಪುವ ಮೊದಲು ಮೂರು ಪ್ರತ್ಯೇಕ ಪರಿಶೀಲನೆಗಳ ಮೂಲಕ ಹಾದುಹೋಗಬೇಕು.

ಅಂಗೀಕರಿಸಲಾದ ಫೀಲ್ಡ್‌ಗಳು (Allowlist)

ನೀವು ಯಾವ ಕೀಲಿಗಳನ್ನು ಪರಿಶೀಲಿಸುತ್ತೀರಿ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸುವ ಮೂಲಕ ಪ್ರಾರಂಭಿಸಿ. ಒಂದು ಫೀಲ್ಡ್ 'ಅಲೌ್‌ಲಿಸ್ಟ್' (allowlist) ನಲ್ಲಿ ಇಲ್ಲದಿದ್ದರೆ, ರಿಕ್ವೆಸ್ಟ್ ಅನ್ನು ತಿರಸ್ಕರಿಸಿ ಅಥವಾ ಆ ಕೀಯನ್ನು ಬಿಟ್ಟುಬಿಡಿ. ಇದು ಡಿಫಾಲ್ಟ್ ಸ್ಥಿತಿಯನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ: ಹೊಸ ಡೇಟಾಬೇಸ್ ಕಾಲಮ್‌ಗಳನ್ನು ಒಬ್ಬ ಡೆವಲಪರ್ ಸ್ಪಷ್ಟವಾಗಿ ಪ್ರದರ್ಶಿಸುವವರೆಗೆ ಅವುಗಳನ್ನು ಬರೆಯಲು (non-writable) ಅನುಮತಿಸುವುದಿಲ್ಲ. ಸ್ಕೆಮಾಗಳು ಕಾಲಾನಂತರದಲ್ಲಿ ಬೆಳೆಯುತ್ತವೆ. ನಿಮ್ಮ ಸಹೋದ್ಯೋಗಿ stripeCustomerId, departmentBudget, ಅಥವಾ isVerified ಫ್ಲಾಗ್ ಅನ್ನು ಸೇರಿಸಬಹುದು. ಅಲೌ್‌ಲಿಸ್ಟ್ ಇದ್ದರೆ, ಆ ಹೊಸ ಕಾಲಮ್‌ಗಳು ಕ್ಲೈಂಟ್ ಬರವಣಿಗೆಯಿಂದ ತಾನಾಗಿಯೇ ರಕ್ಷಿಸಲ್ಪಡುತ್ತವೆ. ಅದು ಇಲ್ಲದಿದ್ದರೆ, ಪ್ರತಿಯೊಂದು ಹೊಸ ಕಾಲಮ್ ಕೂಡ ಅಕಸ್ಮಾತ್ ಆಗಿ API ಸರ್ಫೇಸ್ ಆಗಿ ಬದಲಾಗುತ್ತದೆ.

ಮಾನ್ಯವಾದ ಮೌಲ್ಯಗಳು (Valid Values)

ಯಾವ ಫೀಲ್ಡ್‌ಗಳಿಗೆ ಅನುಮತಿಯಿದೆ ಎಂದು ತಿಳಿದ ನಂತರ, ಮೌಲ್ಯಗಳು ಅರ್ಥಪೂರ್ಣವಾಗಿವೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ. ಟೈಮ್‌ಜೋನ್ ಸ್ಟ್ರಿಂಗ್ ನಿಜವಾಗಿಯೂ ಗುರುತಿಸಲ್ಪಟ್ಟ ಟೈಮ್‌ಜೋನ್ ಆಗಿದೆಯೇ? ಇಮೇಲ್ ಫಾರ್ಮ್ಯಾಟ್ ಇಮೇಲ್‌ನಂತೆಯೇ ಇದೆಯೇ? ಸಂಖ್ಯೆಯು ಸರಿಯಾದ ವ್ಯಾಪ್ತಿಯಲ್ಲಿದೆಯೇ? ಇದು ಮೂಲಭೂತ ಸ್ವಚ್ಛತೆಯಾಗಿದೆ (hygiene). ಇದು ನಿಮ್ಮ ಸಿಸ್ಟಮ್‌ಗೆ ಕಸದಂತಹ ಡೇಟಾ ಬರದಂತೆ ತಡೆಯುತ್ತದೆ, ಆದರೆ ದುರುಪಯೋಗವನ್ನು ತಡೆಯುವುದಿಲ್ಲ. ತಪ್ಪು ವ್ಯಕ್ತಿಯು role ಫೀಲ್ಡ್‌ನಲ್ಲಿ ಕಳುಹಿಸಿದರೂ ಸಹ, ಸಂಪೂರ್ಣವಾಗಿ ಮಾನ್ಯವಾದ "admin" ಸ್ಟ್ರಿಂಗ್ ಅಪಾಯಕಾರಿಯಾಗಿದೆ.

ಅಧಿಕೃತ ಪರಿವರ್ತನೆಗಳು (Authorized Transitions)

ಹೆಚ್ಚಿನ ತಂಡಗಳು ಬಿಟ್ಟುಬಿಡುವ ದ್ವಾರವಿದು, ಮತ್ತು ನಿಜವಾದ ರಕ್ಷಣೆ ಇಲ್ಲಿದೆ. ಒಂದು ಸೂಕ್ಷ್ಮವಾದ ಪ್ರಶ್ನೆಯನ್ನು ಕೇಳಿ: ಈ ನಿರ್ದಿಷ್ಟ ವ್ಯಕ್ತಿಗೆ (actor) ಈ ನಿರ್ದಿಷ್ಟ ದಾಖಲೆಯ ಈ ನಿರ್ದಿಷ್ಟ ಫೀಲ್ಡ್ ಅನ್ನು ಬದಲಾಯಿಸಲು ಅನುಮತಿಯಿದೆಯೇ? "ಬಳಕೆದಾರನು ಅಡ್ಮಿನಾ?" ಎಂದು ಕೇಳಬೇಡಿ. "ಬಳಕೆದಾರನಿಗೆ write:users ಸ್ಕೋಪ್ ಇದೆಯೇ?" ಎಂದು ಕೇಳಬೇಡಿ. ಬದಲಾಗಿ, "ಈ ಬಳಕೆದಾರನು ತನ್ನದೇ ಆದ displayName ಅನ್ನು ಬದಲಾಯಿಸಲು ಅನುಮತಿಯನ್ನು ಹೊಂದಿದ್ದಾನೆಯೇ, ಆದರೆ ಎಂದಿಗೂ ತನ್ನ accountId ಅನ್ನು ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲವೇ?" ಎಂದು ಕೇಳಿ. ಪ್ರತಿ-ಫೀಲ್ಡ್ ಅಧಿಕಾರೀಕರಣವು (Per-field authorization) "ಎಡಿಟರ್" ಅಥವಾ "ಬಳಕೆದಾರ" ಎಂಬ ವಿಶಾಲವಾದ ಅನುಮತಿಯು ಸಾಲಿನ ಪ್ರತಿಯೊಂದು ಪ್ರಾಪರ್ಟಿಯ ಮಾಸ್ಟರ್ ಕೀಯಾಗದಂತೆ ತಡೆಯುತ್ತದೆ.

ಪ್ಯಾಚ್ ಫಂಕ್ಷನ್ (Patch Function) ನಿರ್ಮಿಸುವುದು

ಮೂರು ದ್ವಾರಗಳನ್ನು ಒಂದೇ ಪೈಪ್‌ಲೈನ್‌ಗೆ ಜೋಡಿಸಿ. ಪ್ಯಾಚ್ ರಿಕ್ವೆಸ್ಟ್ ಬಂದಾಗ, ಅದನ್ನು ಕ್ರಮಬದ್ಧವಾಗಿ ಹಂತಗಳ ಮೂಲಕ ನಡೆಸಿಕೊಡಿ.

ಮೊದಲನೆಯದಾಗಿ, ನಿಮ್ಮ ಅಲೌಸ್‌ಲಿಸ್ಟ್ ವಿರುದ್ಧ ಇನ್‌ಪುಟ್ ಅನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ. ಈ ಎಂಡ್‌ಪಾಯಿಂಟ್‌ಗೆ role ಅನುಮತಿಸಲಾದ ಫೀಲ್ಡ್ ಅಲ್ಲದಿದ್ದರೆ, ಅಲ್ಲೇ ನಿಲ್ಲಿಸಿ. ನೀವು ಎಂದಿಗೂ ಸ್ವೀಕರಿಸಬಾರದ ಮೌಲ್ಯವನ್ನು ವ್ಯಾಲಿಡೇಟ್ ಮಾಡಲು ಅಥವಾ ಅಧಿಕಾರೀಕರಿಸಲು ಯಾವುದೇ ಕಾರಣವಿಲ್ಲ.

ಎರಡನೆಯದಾಗಿ, ಅನುಮತಿಸಲಾದ ಮೌಲ್ಯಗಳನ್ನು ವ್ಯಾಲಿಡೇಟ್ ಮಾಡಿ. ಟೈಪ್‌ಗಳು, ಫಾರ್ಮ್ಯಾಟ್‌ಗಳು ಮತ್ತು ವ್ಯವಹಾರದ ನಿಯಮಗಳನ್ನು ಪರಿಶೀಲಿಸಿ. ಲೊಕೇಶನ್ ಫೀಲ್ಡ್ ಒಂದು ನೈಜ ಟೈಮ್‌ಜೋನ್ ಆಗಿರುವ ಸ್ಟ್ರಿಂಗ್ ಆಗಿರಬೇಕು. ಅವತಾರ್ URL ಒಂದು ನಿರ್ದಿಷ್ಟ ಉದ್ದದ ವ್ಯಾಲಿಡ್ URI ಆಗಿರಬೇಕು.

ಮೂರನೆಯದಾಗಿ, ಕ್ರಿಯೆಯನ್ನು ಅಧಿಕಾರೀಕರಿಸಿ (authorize). ಆ ವ್ಯಕ್ತಿಯು ಗುರಿ ದಾಖಲೆಯ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದ್ದಾರೆಯೇ ಅಥವಾ ಈ ಫೀಲ್ಡ್‌ಗೆ ಅಗತ್ಯವಿರುವ ನಿಖರವಾದ ಅನುಮತಿಯನ್ನು ಹೊಂದಿದ್ದಾರೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ. ವೈಯಕ್ತಿಕ ಡೇಟಾಕ್ಕಾಗಿ ಮಾಲೀಕತ್ವವು (ownership) ಉತ್ತಮ ಡಿಫಾಲ್ಟ್ ಆಗಿದೆ, ಆದರೆ ಕೆಲವು ಫೀಲ್ಡ್‌ಗಳಿಗೆ ಇನ್ನೂ ಹೆಚ್ಚಿನ ದ್ವಾರಗಳ ಅಗತ್ಯವಿದೆ. ಒಬ್ಬ ಬಳಕೆದಾರನು ತನ್ನ ಪ್ರೊಫೈಲ್‌ನ ಮಾಲೀಕನಾಗಿರಬಹುದು, ಆದರೂ ಕೇವಲ ಬಿಲ್ಲಿಂಗ್ ಅಡ್ಮಿನು ಮಾತ್ರ taxRegion ಅನ್ನು ಸ್ಪರ್ಶಿಸಬೇಕು.

ನಾಲ್ಕನೆಯದಾಗಿ, ಡೇಟಾವನ್ನು ನಾರ್ಮಲೈಸ್ ಮಾಡಿ. ವೈಟ್‌ಸ್ಪೇಸ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿ, ಪುನರಾವರ್ತಿತ ಸ್ಪೇಸ್‌ಗಳನ್ನು ಕಡಿಮೆ ಮಾಡಿ, ಇಮೇಲ್‌ಗಳನ್ನು ಲೋಕರ್‌ಕೇಸ್ (lowercase) ಮಾಡಿ ಅಥವಾ ಕಂಟ್ರೋಲ್ ಕ್ಯಾರೆಕ್ಟರ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕಿ. ವ್ಯಾಲಿಡೇಶನ್ ಮಾಡಿದ ನಂತರ ಆದರೆ ಸ್ಟೋರೇಜ್‌ಗೆ ಮೊದಲು ಇದನ್ನು ಮಾಡಿ, ಇದರಿಂದ ನೀವು ಅಧಿಕಾರೀಕರಣ ಪರಿಶೀಲನೆಗಳ ಸಮಯದಲ್ಲಿ ಅಸ್ಪಷ್ಟ ಸ್ಟ್ರಿಂಗ್‌ಗಳನ್ನು (dirty strings) ಹೋಲಿಕೆ ಮಾಡಬೇಕಾಗಿ ಬರುವುದಿಲ್ಲ.

ಇನ್‌ಪುಟ್ ಯಾವುದೇ ನಿಯಂತ್ರಣವನ್ನು (gate) ದಾಟಲು ವಿಫಲವಾದರೆ, ಇಡೀ ಮ್ಯುಟೇಶನ್ ಅನ್ನು ತಿರಸ್ಕರಿಸಿ. ಸುರಕ್ಷಿತ ಫೀಲ್ಡ್‌ಗಳನ್ನು ಮಾತ್ರ ಭಾಗಶಃ ಅನ್ವಯಿಸಿ, ತಪ್ಪು ಫೀಲ್ಡ್‌ಗಳನ್ನು ಸುಮ್ಮನೆ ಬಿಡಬೇಡಿ. ಮಿಶ್ರ ಪ್ರತಿಕ್ರಿಯೆಯು ಕ್ಲೈಂಟ್‌ಗಳು ತಮಗೆ ನೆನಪಾದ ಪ್ರತಿಯೊಂದು ಕೀಯನ್ನು (key) ಪ್ರಯತ್ನಿಸಿ ನೋಡಿ, ಯಾವುದು ಕೆಲಸ ಮಾಡುತ್ತದೆ ಎಂದು ನೋಡುವಂತೆ ಪ್ರೇರೇಪಿಸುತ್ತದೆ. ವಿಫಲವಾದರೆ ಅದನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ತಿಳಿಸಿ.

ನಿಜವಾಗಿಯೂ ಮುಖ್ಯವಾದ ಎಡ್ಜ್ ಕೇಸ್‌ಗಳು (Edge Cases)

Mass assignment ರಕ್ಷಣೆಯು ಯೂನಿಟ್ ಟೆಸ್ಟ್‌ಗಳು (unit tests) ಸಾಮಾನ್ಯವಾಗಿ ಕಣಗಣ್ಣಿಗೆ ಬೀಳದ ವಿವರಗಳ ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿದೆ.

ಡ್ಯೂಪ್ಲಿಕೇಟ್ JSON ಕೀಗಳು (Duplicate JSON keys). ದಾಳಿಕೋರರು {"role": "user", "role": "admin"} ನಂತಹ ಪೇಲೋಡ್‌ಗಳನ್ನು ಕಳುಹಿಸಬಹುದು. ನಿಮ್ಮ HTTP ಪಾರ್ಸರ್ ಮತ್ತು ಫ್ರೇಮ್‌ವರ್ಕ್ ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿ, ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಕೋಡ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ನೋಡುವ ಮೊದಲೇ ಎರಡನೇ ಮೌಲ್ಯವು ಮೊದಲನೆಯದನ್ನು ಅಳಿಸಿಹಾಕಬಹುದು (overwrite). ಈ ವರ್ತನೆಯನ್ನು ಪಾರ್ಸರ್ ಮಟ್ಟದಲ್ಲಿ ಪರೀಕ್ಷಿಸಿ. ನಿಮ್ಮ ಫ್ರೇಮ್‌ವರ್ಕ್ ಕೊನೆಯ ಕೀಯನ್ನು ಸುಮ್ಮನೆ ಸ್ವೀಕರಿಸಿದರೆ, ನಿಮ್ಮ ಅಲೋಲಿಸ್ಟ್ (allowlist) "user" ಅನ್ನು ನೋಡುತ್ತಿರಬಹುದು, ಆದರೆ ಡೇಟಾಬೇಸ್ "admin" ಅನ್ನು ಸ್ವೀಕರಿಸಬಹುದು.

ನೆಸ್ಟೆಡ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳು, nulls ಮತ್ತು ಅರೇಗಳು (Nested objects, nulls, and arrays). ಪೇಲೋಡ್ ಸರಳವಾಗಿದೆ (flat) ಎಂದು ಭಾವಿಸಬೇಡಿ. ಕ್ಲೈಂಟ್ ಒಂದು ನಿರ್ಬಂಧಿತ ಫೀಲ್ಡ್ ಅನ್ನು { "profile": { "role": "admin" } } ನಂತಹ ನೆಸ್ಟೆಡ್ ಆಬ್ಜೆಕ್ಟ್‌ನೊಳಗೆ ಇರಿಸಬಹುದು. ನಿಮ್ಮ ಸ್ಕೀಮಾ (schema) ರಿಸರ್ಸ್ (recurse) ಮಾಡಿದರೆ, ನಿಮ್ಮ ಅಲೋಲಿಸ್ಟ್ ಕೂಡ ಹಾಗೆಯೇ ಮಾಡಬೇಕು. ಅದೇ ರೀತಿ, ನೀವು null ಅನ್ನು ಹೇಗೆ ನಿರ್ವಹಿಸುತ್ತೀರಿ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸಿ. ಇದರರ್ಥ "ಈ ಫೀಲ್ಡ್ ಅನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ" ಎಂದೇ ಅಥವಾ "ಈ ಫೀಲ್ಡ್ ಅನ್ನು ಅಳಿಸಿಹಾಕಿ" ಎಂದೇ? ಮತ್ತು ಒಂದು ಅರೇ (array) ನಿರೀಕ್ಷಿತವಾಗಿದ್ದರೆ, ನಿಮ್ಮ ವ್ಯಾಲಿಡೇಟರ್ ಅನಿರೀಕ್ಷಿತ ರಚನೆಗಳನ್ನು ತಿರಸ್ಕರಿಸುತ್ತದೆಯೇ ಅಥವಾ ಒಂದೇ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಅರೇ ಆಗಿ ಪರಿವರ್ತಿಸಿ ಒಳಗೆ ಬಿಡುತ್ತದೆಯೇ?

ಯುನಿಕೋಡ್ ನಾರ್ಮಲೈಸೇಶನ್ (Unicode normalization). ಎರಡು ಸ್ಟ್ರಿಂಗ್‌ಗಳು ಮನುಷ್ಯನಿಗೆ ಒಂದೇ ರೀತಿ ಕಾಣಿಸಬಹುದು, ಆದರೆ ಅವುಗಳ ಬೈಟ್ ಸರಣಿಗಳು (byte sequences) ವಿಭಿನ್ನವಾಗಿರಬಹುದು. ಬಳಕೆದಾರರು ಒಂದು ಸಂಯೋಜಿತ é ಅಥವಾ ವಿಭಜಿತ e ಮತ್ತು ಕಾಂಬೈನಿಂಗ್ ಅಕ್ಸೆಂಟ್ ಅನ್ನು ಕಳುಹಿಸಬಹುದು. ನಿಮ್ಮ ಅಧಿಕಾರೀಕರಣ ಪರಿಶೀಲನೆ (authorization check) ಒಂದು ರೀತಿಯಲ್ಲಿ ನಾರ್ಮಲೈಸ್ ಮಾಡಿ ಮತ್ತು ನಿಮ್ಮ ಸ್ಟೋರೇಜ್ ಲೇಯರ್ ವಿಭಿನ್ನವಾಗಿ ನಾರ್ಮಲೈಸ್ ಮಾಡಿದರೆ, ಅಸಮರ್ಪಕ ಡೇಟಾ ಅಥವಾ ಅದಕ್ಕಿಂತ ಕೆಟ್ಟದಾಗಿ, ಬಳಕೆದಾರರ ಹೆಸರುಗಳ ಘರ್ಷಣೆಯು (username collision) ನಿಮ್ಮ ಲಾಜಿಕ್ ಅನ್ನು ಮೀರಿ ಹೋಗುವ ಅಪಾಯವಿರುತ್ತದೆ. ಮೊದಲೇ ನಾರ್ಮಲೈಸ್ ಮಾಡಿ ಮತ್ತು ಸ್ಥಿರವಾಗಿ ನಾರ್ಮಲೈಸ್ ಮಾಡಿ.

ರೇಸ್ ಕಂಡೀಷನ್ಸ್ (Race conditions). ಅಧಿಕಾರೀಕರಣ ನಿರ್ಧಾರಗಳು ಸ್ಥಿರವಾದವುಗಳಲ್ಲ. ಅವು ಒಂದು ನಿರ್ದಿಷ್ಟ ಸಮಯದಲ್ಲಿ ನಡೆಯುತ್ತವೆ. ಎರಡು ವಿನಂತಿಗಳು (requests) ಒಂದೇ ರೆಕಾರ್ಡ್ ಅನ್ನು ಓದಬಹುದು, ಎರಡೂ ವಿನಂತಿಗಳು ಆ ವ್ಯಕ್ತಿಗೆ ಬರೆಯಲು ಅನುಮತಿಯಿದೆ ಎಂದು ನೋಡಬಹುದು ಮತ್ತು ಎರಡೂ ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ನೀಡಬಹುದು. ಈ ಮಧ್ಯೆ, ಸ್ಥಿತಿ (state) ಅಥವಾ ಆ ವ್ಯಕ್ತಿಯ ಅನುಮತಿಗಳು ಬದಲಾಗಿರಬಹುದು. ಯಾವಾಗಲೂ ವರ್ಷನ್ ನಂಬರ್ ಅಥವಾ ಸ್ಟೇಟ್ ಮೆಷಿನ್ ವ್ಯಾಲ್ಯೂ ಮೇಲೆ ಕಂಡೀಷನ್ ಬಳಸಿ ಡೇಟಾಬೇಸ್ ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ಅನ್ವಯಿಸಿ. UPDATE users SET ... WHERE id = ? AND version = 5 ನಂತಹದ್ದನ್ನು ಬಳಸಿ. ನೀವು ಓದಿದ ನಂತರ ಆ ಸಾಲು (row) ಬದಲಾಗಿದ್ದರೆ, ಬರೆಯುವ ಪ್ರಕ್ರಿಯೆಯು ವಿಫಲವಾಗುತ್ತದೆ. ವಿಫಲವಾದರೆ ಅದನ್ನು ಮರುಪ್ರಯತ್ನಿಸುವ ಮೂಲಕ ಅಥವಾ ತಿರಸ್ಕರಿಸುವ ಮೂಲಕ ನಿರ್ವಹಿಸಿ. ಇದು ಹಳೆಯ ಅಧಿಕಾರೀಕರಣ ಪರಿಶೀಲನೆಗಳು ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಹಾಳು ಮಾಡದಂತೆ ತಡೆಯುತ್ತದೆ.

ಮುಖ್ಯವಾದದ್ದನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ (Monitor What Matters)

ನೀವು ನೋಡಲಾಗದ ವಸ್ತುವನ್ನು ಸುರಕ್ಷಿತಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ಆಡಿಟ್ ಲಾಗಿಂಗ್ ಅನ್ನು ಕೇವಲ ಕ್ರಿಯೆಯ ಸುತ್ತ ಮಾತ್ರವಲ್ಲದೆ, ನಿರ್ಧಾರದ ಸುತ್ತಲೂ ನಿರ್ಮಿಸಿ.

ಆಕ್ಟರ್ ಐಡಿ (actor ID) ಮತ್ತು ಟಾರ್ಗೆಟ್ ಐಡಿ (target ID) ಅನ್ನು ಲಾಗ್ ಮಾಡಿ. ಸ್ವೀಕರಿಸಲಾದ ನಿಖರವಾದ ಫೀಲ್ಡ್ ಹೆಸರುಗಳು ಮತ್ತು ತಿರಸ್ಕರಿಸಲಾದವುಗಳನ್ನು ಲಾಗ್ ಮಾಡಿ. ನಿರ್ಧಾರವನ್ನು ತೆಗೆದುಕೊಂಡ ಪಾಲಿಸಿ ವರ್ಷನ್ (policy version) ಮತ್ತು ಅಂತಿಮ ಫಲಿತಾಂಶವನ್ನು ಲಾಗ್ ಮಾಡಿ. ಬಳಕೆದಾರರ ಪ್ರೊಫೈಲ್ ಅಪ್‌ಡೇಟ್‌ನಲ್ಲಿ ಇದ್ದಕ್ಕಿದ್ದಂತೆ role ತಿರಸ್ಕರಿಸಲ್ಪಡುತ್ತಿದ್ದರೆ, ನೀವು ಅದನ್ನು ತಕ್ಷಣವೇ ತಿಳಿಯಬೇಕು.

ಬೇರರ್ ಟೋಕನ್‌ಗಳನ್ನು (bearer tokens) ಎಂದಿಗೂ ಲಾಗ್ ಮಾಡಬೇಡಿ. ಇಡೀ ರಿಕ್ವೆಸ್ಟ್ ಬಾಡಿಗಳನ್ನು (request bodies) ನಿಮ್ಮ ಲಾಗ್‌ಗಳಿಗೆ ಹಾಕಬೇಡಿ. ಆಡಿಟ್ ಟ್ರೈಲ್ ಎಂಬುದು ದುರುಪಯೋಗವನ್ನು ತನಿಖೆ ಮಾಡಲು ಸಹಾಯ ಮಾಡಬೇಕೇ ಹೊರತು, ಕ್ರೆಡೆನ್ಶಿಯಲ್ಸ್ ಮತ್ತು ವೈಯಕ್ತಿಕ ಡೇಟಾದ ಸಂಗ್ರಹವಾಗಬಾರದು.

ನಿಮಗೆ ಬೇಕಾದ ಏಕೈಕ ನಿಯಮ

ರಿಕ್ವೆಸ್ಟ್ ಬಾಡಿ ಡೇಟಾವನ್ನು ಪ್ರಸ್ತಾಪಿಸುತ್ತದೆ. ಅದು ತನ್ನದೇ ಆದ ಅಧಿಕಾರವನ್ನು ಎಂದಿಗೂ ವ್ಯಾಖ್ಯಾನಿಸುವುದಿಲ್ಲ. ಕ್ಲೈಂಟ್ ಯಾವುದನ್ನಾದರೂ ಕೇಳಬಹುದು. ನಿಮ್ಮ ಸರ್ವರ್, ಫೀಲ್ಡ್ ಬೈ ಫೀಲ್ಡ್ ಮತ್ತು ರೋ ಬೈ ರೋ ಆಗಿ, ಶಾಶ್ವತ ಸ್ಟೋರೇಜ್‌ನಲ್ಲಿ ಏನನ್ನು ಇರಿಸಲು ಅನುಮತಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ. ಆ ಪ್ರತ್ಯೇಕತೆಯನ್ನು ಮನಸ್ಸಿನಲ್ಲಿಟ್ಟುಕೊಂಡು ನಿಮ್ಮ ಪ್ಯಾಚ್‌ಗಳನ್ನು (patches) ನಿರ್ಮಿಸಿ, ಆಗ mass assignment ಎಂಬುದು ನಿಮ್ಮ ಅಧಿಕಾರೀಕರಣ ಲೇಯರ್‌ಗೆ ತಲುಪುವ ಮೊದಲೇ ನೀವು ನಿಲ್ಲಿಸುವ ಸಮಸ್ಯೆಯಾಗುತ್ತದೆ.