ఓపెన్-సోర్స్ బుక్‌కీపింగ్ టూల్ Akauntingలో కేవలం 'రీడ్-ఓన్లీ' (read-only) అనుమతి ఉన్న అకౌంటెంట్ కూడా ఇన్వాయిస్‌లను రద్దు చేయగలరు మరియు పేమెంట్ హిస్టరీని తుడిచివేయగలరు, దీనివల్ల చిన్న వ్యాపారాలు తెలియకుండానే డేటా నష్టాన్ని ఎదుర్కోవాల్సి వస్తుంది. ఈ లోపాన్ని వెర్షన్ 3.2.0లో సరిదిద్దారు, కానీ పర్మిషన్ చెక్‌లను హార్డ్-కోడ్ చేయబడిన మెథడ్ పేర్ల జాబితాతో అనుసంధానించడం అనే పొరపాటు, రోల్-బేస్డ్ యాక్సెస్ కంట్రోల్ (role-based access control) పై ఆధారపడే ఏ వ్యవస్థకైనా ఇంకా ముప్పుగానే ఉంది.

ఈ బగ్ ఎలా దొర్లింది

Akaunting యొక్క API, మెథడ్ పేర్ల యొక్క 'అలౌలిస్ట్' (allowlist) ను పరిశీలించడం ద్వారా వినియోగదారుని హక్కులను ధృవీకరిస్తుంది. ఈ జాబితా సాధారణ CRUD ఆపరేషన్లను—create, read, update, delete—కవర్ చేసింది, కానీ స్టేటస్ మార్చే కొన్ని ఎండ్‌పాయింట్లు (endpoints) మిస్ అయ్యాయి:

  • markSent
  • markCancelled
  • markReceived

ఆ హ్యాండ్లర్లు జాబితాలో లేకపోవడం వల్ల, అవి రన్ అయినప్పుడు ఫ్రేమ్‌వర్క్ పర్మిషన్-చెకింగ్ రూటీన్‌ను ఎప్పుడూ పిలవలేదు. రీడ్-ఓన్లీ రోల్ ఉన్న వినియోగదారు markCancelled ఎండ్‌పాయింట్‌కు ఒక సాధారణ GET రిక్వెస్ట్‌ను పంపితే, సిస్టమ్ దానిని చట్టబద్ధమైన స్టేట్ చేంజ్ (state change) గా పరిగణిస్తుంది.

ఇన్వాయిస్‌ను రద్దు చేయడం అంటే కేవలం ఆ డాక్యుమెంట్‌ను చెల్లకుండా (void) చేయడం మాత్రమే కాదు; అది ఆ ఇన్వాయిస్‌కు అనుసంధానించబడిన ఏ పేమెంట్ రికార్డులనైనా తొలగిస్తుంది. ఫలితంగా: ఎడిట్ చేసే హక్కులు లేని వినియోగదారుడు ఒక లావాదేవీ యొక్క ఆర్థిక రికార్డులను (financial trail) తుడిచివేయగలరు.

టెస్టింగ్ ఏమి చూపిస్తుంది

ఈ లోపం Akaunting యొక్క అధికారిక Docker ఇమేజ్‌లో కనిపించింది:

  • ఇన్వాయిస్‌ను అప్‌డేట్ చేయడానికి పంపిన సాధారణ PUT రిక్వెస్ట్ 403 Forbidden అని తిరిగి ఇచ్చింది, దీనివల్ల సాధారణ అప్‌డేట్ మార్గం సురక్షితంగా ఉందని నిర్ధారించబడింది.
  • క్యాన్సిలేషన్ ఎండ్‌పాయింట్‌కు పంపిన GET రిక్వెస్ట్ ఎటువంటి అథరైజేషన్ ఎర్రర్ లేకుండా విజయవంతమైంది, ఇది ఆ లోపాన్ని బయటపెట్టింది.

ఇది ఎందుకు ముఖ్యం

స్పష్టమైన ఆడిట్ ట్రయల్ (audit trail) లేకుండా ఆర్థిక నివేదికలను మార్చవచ్చు, దీనివల్ల మోసాలను గుర్తించడం కష్టమవుతుంది మరియు నిజాయితీతో కూడిన పొరపాట్లను సరిదిద్దడం కూడా కష్టమవుతుంది.

పరిష్కారం

వెర్షన్ 3.2.0 పర్మిషన్ మ్యాప్‌ను విస్తరించి, గతంలో వదిలేసిన స్టేటస్ చర్యలను కూడా చేర్చింది. ఆ విడుదల నుండి, డాక్యుమెంట్ యొక్క స్టేట్‌ను మార్చే ఏ రిక్వెస్ట్ అయినా—అది marked sent, cancelled, లేదా received అయినా—సాధారణ అప్‌డేట్‌లాగే అదే రోల్ వెరిఫికేషన్‌ను దాటాల్సి ఉంటుంది. దీనివల్ల రీడ్-ఓన్లీ రోల్ నిజంగా డేటాను మార్చలేదని నమ్మకం పుడుతుంది.

డెవలపర్ల కోసం పాఠాలు

  • మెథడ్ పేర్లను భద్రతతో ఎప్పుడూ సమానంగా చూడకండి. కొత్త ఎండ్‌పాయింట్‌ను జోడించడం వల్ల దానికి ఆటోమేటిక్‌గా రక్షణ లభించదు; ప్రతి పబ్లిక్ మెథడ్‌ను దాని సైడ్ ఎఫెక్ట్స్ (side effects) కోసం తనిఖీ చేయండి.
  • అలౌలిస్ట్‌లు (Allowlists) ఆ జాబితా ఎంత పరిపూర్ణంగా ఉంటే అంత మాత్రమే పనిచేస్తాయి. "మంచి" వెర్బ్స్ (verbs) యొక్క స్టాటిక్ జాబితా అనేది పొరపాట్ల కోసం తలుపులు తెరిచి ఉంచుతుంది.
  • HTTP వెర్బ్ నుండి ఉద్దేశ్యాన్ని (intent) వేరు చేయండి. GET అనేది కేవలం చదవడానికి (read-only) మాత్రమే ఉద్దేశించబడింది, కానీ ఇక్కడ అది స్టేట్ చేంజ్‌ను నిర్వహించింది. మ్యుటేషన్లను (mutations) POST, PUT, DELETE, PATCHలకు మాత్రమే పరిమితం చేయండి.
  • పర్మిషన్ కవరేజ్ చెక్‌లను ఆటోమేట్ చేయండి. స్టాటిక్ అనాలిసిస్ టూల్స్ అథరైజేషన్ కాల్ లేని కంట్రోలర్ మెథడ్స్‌ను గుర్తించగలవు, తద్వారా సాఫ్ట్‌వేర్ విడుదల కావడానికి ముందే లోపాలను పట్టుకోవచ్చు.
  • కనీస అధికారాలు (least-privilege) ఉన్న అకౌంట్‌లతో పరీక్షించండి. Docker ఆధారిత టెస్టింగ్‌లో రీడ్-ఓన్లీ యూజర్‌ను ఉపయోగించారు; CI పైప్‌లైన్‌లలో ఇటువంటి పరిస్థితులను పునరావృతం చేయడం వల్ల ఇలాంటి సమస్యలను ముందుగానే గుర్తించవచ్చు.

తదుపరి ఏమి గమనించాలి

Akaunting కమ్యూనిటీ ఇప్పటికే ప్యాచ్ చేయబడిన వెర్షన్‌ను విడుదల చేసింది. అడ్మినిస్ట్రేటర్లు తమ ఇన్‌స్టాన్స్ వెర్షన్‌ను తనిఖీ చేసి, వెంటనే అప్‌డేట్‌ను వర్తింపజేయాలి.

రోల్-బేస్డ్ సిస్టమ్‌ను నిర్మిస్తున్న డెవలపర్లకు దీని నుండి నేర్చుకోవాల్సింది స్పష్టంగా ఉంది: ప్రతి సాధ్యమయ్యే చర్యను గుర్తుంచుకోవడంపై ఆధారపడే పర్మిషన్ మోడల్ డిజైన్ పరంగానే బలహీనంగా ఉంటుంది. ఏ ఆపరేషన్లు స్టేట్‌ను మారుస్తాయో స్పష్టంగా ప్రకటించండి, ఫ్రేమ్‌వర్క్ స్థాయిలో చెక్‌లను అమలు చేయండి మరియు కోడ్‌బేస్‌ను క్రమం తప్పకుండా ఆడిట్ చేయండి. అప్పుడే "రీడ్-ఓన్లీ" లేబుల్‌ను ఆర్థిక రికార్డులను సురక్షితంగా ఉంచడానికి నమ్మవచ్చు.