ਇੱਕ ਰੀਡ-ਓਨਲੀ (read-only) ਅਕਾਊਂਟੈਂਟ ਓਪਨ-ਸੋਰਸ ਬੁੱਕਕੀਪਿੰਗ ਟੂਲ Akaunting ਵਿੱਚ ਇਨਵੌਇਸਾਂ ਨੂੰ ਰੱਦ ਕਰ ਸਕਦਾ ਸੀ ਅਤੇ ਭੁਗਤਾਨ ਇਤਿਹਾਸ ਨੂੰ ਮਿਟਾ ਸਕਦਾ ਸੀ, ਜਿਸ ਨਾਲ ਛੋਟੇ ਕਾਰੋਬਾਰਾਂ ਨੂੰ ਚੁੱਪਚਾਪ ਡਾਟਾ ਨੁਕਸਾਨ ਦਾ ਖ਼ਤਰਾ ਪੈਦਾ ਹੋ ਗਿਆ। ਇਸ ਖ਼ਰਾਬੀ ਨੂੰ ਵਰਜ਼ਨ 3.2.0 ਵਿੱਚ ਠੀਕ ਕਰ ਦਿੱਤਾ ਗਿਆ ਸੀ, ਪਰ ਗਲਤੀ—ਪਰਮਿਸ਼ਨ ਚੈੱਕਾਂ ਨੂੰ ਮੈਥਡ ਨਾਮਾਂ ਦੀ ਇੱਕ ਹਾਰਡ-ਕੋਡਡ ਸੂਚੀ ਨਾਲ ਜੋੜਨਾ—ਅਜੇ ਵੀ ਕਿਸੇ ਵੀ ਅਜਿਹੇ ਸਿਸਟਮ ਲਈ ਖ਼ਤਰਾ ਬਣਿਆ ਹੋਇਆ ਹੈ ਜੋ ਰੋਲ-ਅਧਾਰਤ ਐਕਸੈਸ ਕੰਟਰੋਲ (role-based access control) 'ਤੇ ਨਿਰਭਰ ਕਰਦਾ ਹੈ।

ਬੱਗ (bug) ਕਿਵੇਂ ਨਿਕਲ ਗਿਆ

Akaunting ਦਾ API ਮੈਥਡ ਨਾਮਾਂ ਦੀ ਇੱਕ allowlist ਦੀ ਜਾਂਚ ਕਰਕੇ ਉਪਭੋਗਤਾ ਦੇ ਅਧਿਕਾਰਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰਦਾ ਹੈ। ਇਸ ਸੂਚੀ ਵਿੱਚ ਆਮ CRUD ਆਪਰੇਸ਼ਨਾਂ—create, read, update, delete—ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਸੀ, ਪਰ ਕੁਝ ਸਟੇਟਸ-ਬਦਲਣ ਵਾਲੇ endpoints ਰਹਿ ਗਏ ਸਨ:

  • markSent
  • markCancelled
  • markReceived

ਕਿਉਂਕਿ ਉਹ ਹੈਂਡਲਰ ਸੂਚੀ ਵਿੱਚ ਨਹੀਂ ਸਨ, ਇਸ ਲਈ ਫਰੇਮਵਰਕ ਨੇ ਉਹਨਾਂ ਨੂੰ ਚਲਾਉਣ ਵੇਲੇ ਪਰਮਿਸ਼ਨ-ਚੈਕਿੰਗ ਰੁਟੀਨ ਨੂੰ ਕਦੇ ਵੀ ਕਾਲ ਨਹੀਂ ਕੀਤਾ। ਰੀਡ-ਓਨਲੀ ਰੋਲ ਵਾਲਾ ਇੱਕ ਉਪਭੋਗਤਾ markCancelled endpoint ਨੂੰ ਇੱਕ ਸਧਾਰਨ GET ਰਿਕੁਐਸ ਭੇਜ ਸਕਦਾ ਸੀ ਅਤੇ ਸਿਸਟਮ ਇਸਨੂੰ ਇੱਕ ਜਾਇਜ਼ ਸਟੇਟ ਚੇਂਜ (state change) ਵਜੋਂ ਮੰਨ ਲੈਂਦਾ।

ਕਿਸੇ ਇਨਵੌਇਸ ਨੂੰ ਰੱਦ ਕਰਨ ਦਾ ਮਤਲਬ ਸਿਰਫ਼ ਦਸਤਾਵੇਜ਼ ਨੂੰ ਰੱਦ (void) ਵਜੋਂ ਚਿੰਨ੍ਹਿਤ ਕਰਨਾ ਹੀ ਨਹੀਂ ਹੈ; ਇਹ ਉਸ ਇਨਵੌਇਸ ਨਾਲ ਜੁੜੇ ਕਿਸੇ ਵੀ ਭੁਗਤਾਨ ਰਿਕਾਰਡ ਨੂੰ ਵੀ ਹਟਾ ਦਿੰਦਾ ਹੈ। ਨਤੀਜਾ: ਐਡਿਟ ਅਧਿਕਾਰਾਂ ਤੋਂ ਬਿਨਾਂ ਇੱਕ ਉਪਭੋਗਤਾ ਲੈਣ-ਦੇਣ ਦੇ ਵਿੱਤੀ ਰਿਕਾਰਡ ਨੂੰ ਮਿਟਾ ਸਕਦਾ ਹੈ।

ਟੈਸਟਿੰਗ ਨੇ ਕੀ ਦਿਖਾਇਆ

ਇਹ ਕਮਜ਼ੋਰੀ Akaunting ਦੀ ਅਧਿਕਾਰਤ Docker image ਵਿੱਚ ਦਿਖਾਈ ਦਿੱਤੀ:

  • ਇਨਵੌਇਸ ਨੂੰ ਅਪਡੇਟ ਕਰਨ ਲਈ ਇੱਕ ਸਟੈਂਡਰਡ PUT ਰਿਕੁਐਸ ਨੇ 403 Forbidden ਦਿੱਤਾ, ਜਿਸ ਨੇ ਪੁਸ਼ਟੀ ਕੀਤੀ ਕਿ ਆਮ ਅਪਡੇਟ ਪਾਥ ਸੁਰੱਖਿਅਤ ਸੀ।
  • ਕੈਂਸਲੇਸ਼ਨ endpoint ਨੂੰ ਕੀਤੀ ਗਈ GET ਰਿਕੁਐਸ ਬਿਨਾਂ ਕਿਸੇ ਅਥੋਰਾਈਜ਼ੇਸ਼ਨ ਐਰਰ ਦੇ ਸਫਲ ਰਹੀ, ਜਿਸ ਨਾਲ ਇਹ ਖਾਮੀ ਸਾਹਮਣੇ ਆ ਗਈ।

ਇਹ ਕਿਉਂ ਮਹੱਤਵਪੂਰਨ ਹੈ

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

ਹੱਲ

ਵਰਜ਼ਨ 3.2.0 ਪਰਮਿਸ਼ਨ ਮੈਪ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ ਤਾਂ ਜੋ ਪਹਿਲਾਂ ਰਹਿ ਗਏ ਸਟੇਟਸ ਐਕਸ਼ਨਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਜਾ ਸਕੇ। ਉਸ ਰਿਲੀਜ਼ ਤੋਂ ਬਾਅਦ, ਕੋਈ ਵੀ ਰਿਕੁਐਸ ਜੋ ਦਸਤਾਵੇਜ਼ ਦੀ ਸਟੇਟ ਨੂੰ ਬਦਲਦੀ ਹੈ—ਚਾਹੇ ਉਹ sent, cancelled, ਜਾਂ received ਵਜੋਂ ਚਿੰਨ੍ਹਿਤ ਕੀਤੀ ਗਈ ਹੋਵੇ—ਉਸਨੂੰ ਇੱਕ ਸਟੈਂਡਰਡ ਅਪਡੇਟ ਵਾਂਗ ਹੀ ਰੋਲ ਵੈਰੀਫਿਕੇਸ਼ਨ ਤੋਂ ਲੰਘਣਾ ਪਵੇਗਾ। ਇਹ ਇਸ ਉਮੀਦ ਨੂੰ ਦੁਬਾਰਾ ਸਥਾਪਿਤ ਕਰਦਾ ਹੈ ਕਿ ਰੀਡ-ਓਨਲੀ ਰੋਲ ਸੱਚਮੁੱਚ ਡਾਟਾ ਨੂੰ ਸੋਧ ਨਹੀਂ ਸਕਦਾ।

ਡਿਵੈਲਪਰਾਂ ਲਈ ਸਬਕ

  • ਮੈਥਡ ਨਾਮਾਂ ਨੂੰ ਕਦੇ ਵੀ ਸੁਰੱਖਿਆ ਦੇ ਬਰਾਬਰ ਨਾ ਸਮਝੋ। ਇੱਕ ਨਵਾਂ endpoint ਜੋੜਨ ਨਾਲ ਸੁਰੱਖਿਆ ਆਪਣੇ ਆਪ ਨਹੀਂ ਮਿਲਦੀ; ਹਰੇਕ ਪਬਲਿਕ ਮੈਥਡ ਦੀ ਸਾਈਡ-ਇਫੈਕਟਸ (side effects) ਲਈ ਜਾਂਚ ਕਰੋ।
  • Allowlists ਉਨੀ ਹੀ ਮੁਕੰਮਲ ਹੁੰਦੀਆਂ ਹਨ ਜਿੰਨੀ ਉਹ ਸੂਚੀ ਖੁਦ ਹੈ। "ਚੰਗੇ" ਵਰਬਸ (verbs) ਦੀ ਇੱਕ ਸਟੈਟਿਕ ਸੂਚੀ ਲਾਪਰਵਾਹੀ ਲਈ ਖੁੱਲ੍ਹਾ ਦਰਵਾਜ਼ਾ ਛੱਡ ਦਿੰਦੀ ਹੈ।
  • ਇਰਾਦੇ (intent) ਨੂੰ HTTP verb ਤੋਂ ਵੱਖ ਕਰੋ। GET ਸਿਰਫ਼ ਪੜ੍ਹਨ (read-only) ਲਈ ਹੁੰਦਾ ਹੈ, ਪਰ ਇੱਥੇ ਇਸਨੇ ਸਟੇਟ ਚੇਂਜ ਕੀਤੀ। ਮਿਊਟੇਸ਼ਨਾਂ (mutations) ਨੂੰ POST, PUT, DELETE, PATCH ਤੱਕ ਸੀਮਤ ਰੱਖੋ।
  • ਪਰਮਿਸ਼ਨ ਕਵਰੇਜ ਚੈੱਕਾਂ ਨੂੰ ਆਟੋਮੇਟ ਕਰੋ। ਸਟੈਟਿਕ ਐਨਾਲਿਸਿਸ ਟੂਲ ਅਜਿਹੇ ਕੰਟਰੋਲਰ ਮੈਥਡਾਂ ਨੂੰ ਫਲੈਗ ਕਰ ਸਕਦੇ ਹਨ ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਅਥੋਰਾਈਜ਼ੇਸ਼ਨ ਕਾਲ ਦੀ ਕਮੀ ਹੈ, ਜਿਸ ਨਾਲ ਸ਼ਿਪ ਹੋਣ ਤੋਂ ਪਹਿਲਾਂ ਹੀ ਖਾਮੀਆਂ ਫੜੀਆਂ ਜਾ ਸਕਦੀਆਂ ਹਨ।
  • ਘੱਟ ਤੋਂ ਘੱਟ ਅਧਿਕਾਰਾਂ (least-privilege) ਵਾਲੇ ਖਾਤਿਆਂ ਨਾਲ ਟੈਸਟ ਕਰੋ। Docker-ਅਧਾਰਤ ਟੈਸਟ ਵਿੱਚ ਰੀਡ-ਓਨਲੀ ਯੂਜ਼ਰ ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਗਈ ਸੀ; CI ਪਾਈਪਲਾਈਨਾਂ ਵਿੱਚ ਅਜਿਹੇ ਦ੍ਰਿਸ਼ਾਂ ਨੂੰ ਦੁਹਰਾਉਣ ਨਾਲ ਅਜਿਹੀਆਂ ਸਮੱਸਿਆਵਾਂ ਜਲਦੀ ਸਾਹਮਣੇ ਆ ਜਾਂਦੀਆਂ ਹਨ।

ਅੱਗੇ ਕੀ ਦੇਖਣਾ ਹੈ

Akaunting ਦੀ ਕਮਿਊਨਿਟੀ ਨੇ ਪਹਿਲਾਂ ਹੀ ਪੈਚਡ (patched) ਵਰਜ਼ਨ ਰਿਲੀਜ਼ ਕਰ ਦਿੱਤਾ ਹੈ। ਐਡਮਿਨਿਸਟ੍ਰੇਟਰਾਂ ਨੂੰ ਆਪਣੇ ਇੰਸਟੈਂਸ ਦੇ ਵਰਜ਼ਨ ਦੀ ਜਾਂਚ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ ਅਤੇ ਤੁਰੰਤ ਅਪਡੇਟ ਲਾਗੂ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ।

ਕਿਸੇ ਵੀ ਰੋਲ-ਅਧਾਰਤ ਸਿਸਟਮ ਨੂੰ ਬਣਾਉਣ ਵਾਲੇ ਡਿਵੈਲਪਰਾਂ ਲਈ ਸਿੱਖਿਆ ਸਪੱਸ਼ਟ ਹੈ: ਇੱਕ ਪਰਮਿਸ਼ਨ ਮਾਡਲ ਜੋ ਹਰ ਸੰਭਵ ਕਾਰਵਾਈ ਨੂੰ ਯਾਦ ਰੱਖਣ 'ਤੇ ਨਿਰਭਰ ਕਰਦਾ ਹੈ, ਉਹ ਡਿਜ਼ਾਈਨ ਅਨੁਸਾਰ ਕਮਜ਼ੋਰ ਹੁੰਦਾ ਹੈ। ਸਪੱਸ਼ਟ ਰੂਪ ਵਿੱਚ ਘੋਸ਼ਣਾ ਕਰੋ ਕਿ ਕਿਹੜੇ ਆਪਰੇਸ਼ਨ ਸਟੇਟ ਨੂੰ ਬਦਲਦੇ ਹਨ, ਫਰੇਮਵਰਕ ਪੱਧਰ 'ਤੇ ਚੈੱਕ ਲਾਗੂ ਕਰੋ, ਅਤੇ ਨਿਯਮਤ ਤੌਰ 'ਤੇ ਕੋਡਬੇਸ ਦੀ ਜਾਂਚ ਕਰੋ। ਕੇਵਲ ਉਦੋਂ ਹੀ "ਰੀਡ-ਓਨਲੀ" ਲੇਬਲ 'ਤੇ ਵਿੱਤੀ ਰਿਕਾਰਡਾਂ ਨੂੰ ਸਹੀ ਰੱਖਣ ਲਈ ਭਰੋਸਾ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।