PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL सुरक्षा_बैरियर दृश्य कैसे काम करते हैं?

आपने security_barrier . के लिए जोड़ा गया समर्थन देखा होगा PostgreSQL 9.2 में देखा गया। मैं AXLE प्रोजेक्ट के लिए पंक्ति-स्तरीय सुरक्षा कार्य की प्रगति के हिस्से के रूप में उनके लिए स्वचालित अपडेट समर्थन जोड़ने के लिए उस कोड को देख रहा हूं, और मैंने सोचा कि मैं यह समझाने का मौका दूंगा कि वे कैसे काम करते हैं।

रॉबर्ट ने पहले ही समझाया कि वे क्यों उपयोगी हैं और वे किससे बचाव करते हैं। (यह पता चला है कि 9.2 में नया क्या है, इसकी भी चर्चा की गई है)। अब मैं कैसे . में जाना चाहता हूँ वे काम करते हैं और चर्चा करते हैं कि कैसे security_barrier विचार स्वचालित रूप से अद्यतन करने योग्य दृश्यों के साथ सहभागिता करते हैं।

सामान्य दृश्य

एक सामान्य सरल दृश्य को मैक्रो-जैसी फैशन में एक सबक्वायरी के रूप में विस्तारित किया जाता है जिसे आमतौर पर इसके विधेय को ऊपर खींचकर और इसे युक्त क्वेरी के गुणों में जोड़कर अनुकूलित किया जाता है। यह एक उदाहरण के साथ और अधिक समझ में आ सकता है। दी गई तालिका:

चुनें n के रूप में तालिका बनाएं, 'गुप्त' 

और देखें:

चुनें n के रूप में t_odd दृश्य बनाएं, जहां से n % 2 =1 गुप्त;

एक प्रश्न जैसे:

चुनें * t_odd से जहां n <4

क्वेरी रीराइटर के अंदर एक क्वेरी के पार्स ट्री प्रतिनिधित्व में दृश्य-विस्तारित किया जाता है जैसे:

चुनें * से (चुनें * टी से n% 2 =1) t_odd जहां n <4

जिसे ऑप्टिमाइज़र फिर सबक्वेरी को हटाकर और WHERE को जोड़कर सिंगल पास क्वेरी में फ़्लैट करता है बाहरी क्वेरी के लिए क्लॉज शब्द, उत्पादन:

चुनें * t t_odd से जहां (n% 2 =1) और (n <4)

भले ही आप मध्यवर्ती प्रश्नों को सीधे नहीं देख सकते हैं और वे वास्तविक SQL के रूप में कभी मौजूद नहीं हैं, आप debug_print_parse =on को सक्षम करके इस प्रक्रिया का निरीक्षण कर सकते हैं। , debug_print_reलिखित =चालू और debug_print_plan =चालू postgresql.conf . में . मैं यहां पार्स को पुन:पेश नहीं करूंगा और पेड़ों की योजना नहीं बनाऊंगा क्योंकि वे काफी बड़े हैं और ऊपर दिए गए उदाहरणों के आधार पर उत्पन्न करना आसान है।

सुरक्षा के लिए दृश्यों का उपयोग करने में समस्या

आप सोच सकते हैं कि किसी को अंतर्निहित तालिका तक पहुंच प्रदान किए बिना दृश्य तक पहुंच प्रदान करने से उन्हें सम-संख्या वाली पंक्तियों को देखना बंद हो जाएगा। शुरू में ऐसा लगता है कि यह सच है:

regress=> चुनें * t_odd से जहां n <4; एन | गुप्त ---+---------- 1 | गुप्त1 3 | गुप्त3(2 पंक्तियाँ)

लेकिन जब आप योजना को देखते हैं तो आपको एक संभावित समस्या दिखाई दे सकती है:

regress=> व्याख्या करें चुनें * t_odd से जहां n <4; प्रश्न योजना ------------------------------------------------- --- t पर Seq स्कैन (लागत=0.00..31.53 पंक्तियाँ=2 चौड़ाई=36) फ़िल्टर:((n <4) और ((n% 2) =1))(2 पंक्तियाँ)

व्यू सबक्वेरी को ऑप्टिमाइज़ किया गया है, व्यू के क्वालिफायर को सीधे बाहरी क्वेरी में जोड़ दिया गया है।

SQL में, और और या आदेशित नहीं हैं। अनुकूलक/निष्पादक किसी भी शाखा को चलाने के लिए स्वतंत्र हैं जो उन्हें लगता है कि उन्हें त्वरित उत्तर देने की अधिक संभावना है और संभवतः उन्हें अन्य शाखाओं को चलाने से बचने दें। तो अगर योजनाकार को लगता है कि n <4 n % 2 =1 . से बहुत तेज़ है यह पहले उसका मूल्यांकन करेगा। हानिरहित लगता है, है ना? कोशिश करें:

regress=> फ़ंक्शन बनाएं या बदलें f_leak(text) $$BEGIN RAISE नोटिस के रूप में बूलियन लौटाता है 'गुप्त है:%',$1; सही लौटें;END;$$ लागत 1 भाषा plpgsql;regress=> चुनें * t_odd से जहां f_leak (गुप्त) और n <4; नोटिस:गुप्त है:गुप्त 1 नोटिस:गुप्त है:गुप्त 2 नोटिस:गुप्त है:गुप्त 3 नोटिस:गुप्त है:गुप्त 4 नोटिस :सीक्रेट है:सीक्रेट5नोटिस:सीक्रेट है:सीक्रेट6नोटिस:सीक्रेट है:सीक्रेट7नोटिस:सीक्रेट है:सीक्रेट8नोटिस:सीक्रेट है:सीक्रेट9नोटिस:सीक्रेट है:सीक्रेट10नोटिस:सीक्रेट है:सीक्रेट11नोटिस:सीक्रेट है:सीक्रेट12नोटिस:सीक्रेट है:सीक्रेट13नोटिस:सीक्रेट है:सीक्रेट14नोटिस :सीक्रेट है:सीक्रेट15नोटिस:सीक्रेट है:सीक्रेट16नोटिस:सीक्रेट है:सीक्रेट17नोटिस:सीक्रेट है:सीक्रेट18नोटिस:सीक्रेट है:सीक्रेट19नोटिस:सीक्रेट है:सीक्रेट20 एन | गुप्त ---+---------- 1 | गुप्त1 3 | सीक्रेट 3(2 रो) रिग्रेस=> एक्सप्लेन सेलेक्ट * t_odd से जहां f_leak(गुप्त) और n <4; प्रश्न योजना ------------------------------------------------- ---------- t पर Seq स्कैन (लागत =0.00..34.60 पंक्तियाँ =1 चौड़ाई =36) फ़िल्टर:(f_leak (गुप्त) और (n <4) और ((n% 2) =1 ))(2 पंक्तियाँ)

ओह! जैसा कि आप देख सकते हैं, उपयोगकर्ता द्वारा प्रदत्त विधेय फ़ंक्शन को अन्य परीक्षणों की तुलना में चलाने के लिए सस्ता माना जाता था, इसलिए दृश्य के विधेय द्वारा इसे बाहर करने से पहले इसे हर पंक्ति में पारित किया गया था। एक दुर्भावनापूर्ण फ़ंक्शन पंक्ति को कॉपी करने के लिए उसी ट्रिक का उपयोग कर सकता है।

सुरक्षा_बाधा दृश्य

सुरक्षा_अवरोध विचार ठीक करते हैं कि किसी भी उपयोगकर्ता द्वारा आपूर्ति किए गए क्वालिफायर के चलने से पहले, क्वालिफायर को पहले निष्पादित करने के लिए मजबूर करके। दृश्य का विस्तार करने और किसी भी दृश्य योग्यता को बाहरी क्वेरी में जोड़ने के बजाय, वे दृश्य के संदर्भ को सबक्वेरी से बदल देते हैं। इस सबक्वेरी में security_barrier है इसकी रेंज-टेबल प्रविष्टि पर ध्वज सेट, जो ऑप्टिमाइज़र को बताता है कि उसे सबक्वेरी को समतल नहीं करना चाहिए या बाहरी क्वेरी शर्तों को इसमें नीचे नहीं धकेलना चाहिए जैसे कि यह एक सामान्य सबक्वेरी के लिए होता है।

तो एक सुरक्षा बाधा दृश्य के साथ:

चुनें के रूप में (सुरक्षा_बैरियर) के साथ t_odd_sb दृश्य बनाएं, जहां से n % 2 =1 गुप्त है;

हमें मिलता है:

regress=> चुनें * t_odd_sb से जहां f_leak(secret) और n <4;नोटिस:सीक्रेट है:सीक्रेट1नोटिस:सीक्रेट है:सीक्रेट3 एन | गुप्त ---+---------- 1 | गुप्त1 3 | सीक्रेट 3(2 रो) रिग्रेस=> एक्सप्लेन सेलेक्ट * t_odd_sb से जहां f_leak (गुप्त) और n <4; प्रश्न योजना ------------------------------------------------- --------------- t_odd_sb पर सबक्वेरी स्कैन (लागत =0.00..31.55 पंक्तियाँ =1 चौड़ाई =36) फ़िल्टर:f_leak (t_odd_sb.secret) -> t पर Seq स्कैन (लागत =0.00..31.53 पंक्तियाँ=2 चौड़ाई=36) फ़िल्टर:((n <4) और ((n% 2) =1))(4 पंक्तियाँ)

क्वेरी योजना आपको बताएगी कि क्या हो रहा है, हालांकि यह व्याख्या आउटपुट में सुरक्षा अवरोध विशेषता नहीं दिखाता है। नेस्टेड सबक्वेरी t . पर स्कैन के लिए बाध्य करती है व्यू क्वालिफायर के साथ, उपयोगकर्ता द्वारा प्रदत्त फ़ंक्शन सबक्वेरी के परिणाम पर चलता है।

लेकिन। एक सेकंड रुको। उपयोगकर्ता द्वारा प्रदत्त विधेय n <4 . क्यों है सबक्वायरी के अंदर भी? क्या यह एक संभावित सुरक्षा छेद नहीं है? अगर n <4 नीचे धकेल दिया गया है, f_leak(गुप्त) . क्यों नहीं है ?

लीकप्रूफ ऑपरेटरों और कार्यों

इसके लिए स्पष्टीकरण यह है कि < ऑपरेटर को LEAKPROOF . के रूप में चिह्नित किया गया है . यह विशेषता इंगित करती है कि एक ऑपरेटर या फ़ंक्शन पर भरोसा किया जाता है कि वह जानकारी लीक न करे, इसलिए इसे security_barrier के माध्यम से सुरक्षित रूप से नीचे धकेला जा सकता है विचार। स्पष्ट कारणों से आप LEAKPROOF . सेट नहीं कर सकते एक सामान्य उपयोगकर्ता के रूप में:

regress=> ALTER FUNCTION f_leak(text) LEAKPROOF;ERROR:केवल सुपरयूजर ही लीकप्रूफ फंक्शन को परिभाषित कर सकता है

और सुपरयूज़र पहले से ही जो चाहें कर सकते हैं, इसलिए उन्हें सुरक्षा बाधा दृश्य से बाहर निकलने के लिए जानकारी लीक करने वाले कार्यों के साथ चाल चलने की आवश्यकता नहीं है।

आप security_barrier को अपडेट क्यों नहीं कर सकते? दृश्य

PostgreSQL 9.3 में सरल दृश्य स्वचालित रूप से अद्यतन करने योग्य हैं, लेकिन security_barrier विचारों को "सरल" नहीं माना जाता है। ऐसा इसलिए है क्योंकि अपडेटिंग व्यू व्यू सबक्वेरी को दूर करने में सक्षम होने पर निर्भर करता है, अपडेट को टेबल पर एक साधारण अपडेट में बदल देता है। security_barrier . का संपूर्ण बिंदु विचारों को रोकना . है कि चपटा। अद्यतन करें वर्तमान में सीधे सबक्वेरी पर काम नहीं कर सकता है, इसलिए PostgreSQL security_barrier को अपडेट करने के किसी भी प्रयास को अस्वीकार कर देगा देखें:

प्रतिगमन=> अद्यतन t_odd SET गुप्त ='secret_haha'||n;अद्यतन 10regress=> अद्यतन t_odd_sb SET गुप्त ='secret_haha'||n;त्रुटि:"t_odd_sb" दृश्य को अपडेट नहीं कर सकता विवरण:सुरक्षा-बाधा दृश्य नहीं हैं स्वचालित रूप से अद्यतन करने योग्य। संकेत:दृश्य को अद्यतन करने में सक्षम करने के लिए, अद्यतन के बजाय एक ट्रिगर या बिना शर्त अद्यतन करें के बजाय नियम प्रदान करें।

यही वह सीमा है जिसे AXLE प्रोजेक्ट के लिए पंक्ति-स्तरीय सुरक्षा को आगे बढ़ाने के लिए काम के हिस्से के रूप में उठाने में मेरी दिलचस्पी है। Kohei KaiGai ने पंक्ति-स्तरीय सुरक्षा और security_barrier जैसी सुविधाओं के साथ कुछ बेहतरीन काम किया है और लीकप्रूफ बड़े पैमाने पर पोस्टग्रेएसक्यूएल में पंक्ति स्तर की सुरक्षा जोड़ने की दिशा में उनके काम से उत्पन्न हुए हैं। अगली चुनौती यह है कि सुरक्षा अवरोध पर अद्यतनों को सुरक्षित रूप से कैसे निपटाया जाए और इस तरह से भविष्य में बनाए रखा जा सके।

सबक्वायरी क्यों?

आप सोच रहे होंगे कि इसके लिए हमें सबक्वायरी का इस्तेमाल क्यों करना पड़ता है। मैंने किया। संक्षिप्त संस्करण यह है कि हमें ऐसा करने की आवश्यकता नहीं है, लेकिन यदि हम सबक्वेरी का उपयोग नहीं करते हैं तो हमें इसके बजाय AND के नए ऑर्डर-संवेदी वेरिएंट बनाने होंगे और या ऑपरेटरों और अनुकूलक को सिखाते हैं कि यह उनके बीच की स्थितियों को स्थानांतरित नहीं कर सकता है। चूंकि दृश्यों को पहले से ही सबक्वेरी के रूप में विस्तारित किया गया है, इसलिए सबक्वायरीज़ को फ़ेंस के रूप में फ़्लैग करना बहुत कम जटिल है जो पुल-अप / पुश-डाउन को ब्लॉक करते हैं।

हालांकि PostgreSQL में पहले से ही शॉर्ट-सर्किटिंग का आदेश दिया गया है - CASE . CASE . का उपयोग करने में समस्या कि नहीं संचालन को CASE . की सीमा के पार ले जाया जा सकता है , यहां तक ​​कि LEAKPROOF वाले। न ही अनुकूलक किसी CASE . के भावों के आधार पर अनुक्रमणिका उपयोग संबंधी निर्णय ले सकता है अवधि। तो अगर हम CASE . का इस्तेमाल करते हैं जैसा कि मैंने ऑन-हैकर्स के बारे में पूछा था, हम उपयोगकर्ता द्वारा आपूर्ति किए गए क्वालीफायर को संतुष्ट करने के लिए कभी भी इंडेक्स का उपयोग नहीं कर सके।

कोड में

सुरक्षा_अवरोध समर्थन 0e4611c0234d89e288a53351f775c59522baed7c में जोड़ा गया था . इसे cd30728fb2ed7c367d545fc14ab850b5fa2a4850 में लीकप्रूफ समर्थन के साथ बढ़ाया गया था . क्रेडिट कमिट नोट में दिखाई देते हैं। इसमें शामिल सभी लोगों को धन्यवाद।

फ़्रंट पेज फ़ीचर इमेज फ़्लिकर पर क्रेग ए. रोडवे द्वारा सिक्योरिटी बैरियर है

इन परिणामों की ओर ले जाने वाले शोध को अनुदान समझौते n° 318633 के तहत यूरोपीय संघ के सातवें फ्रेमवर्क प्रोग्राम (FP7/2007-2013) से धन प्राप्त हुआ है


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL में दो स्कीमा की तुलना कैसे करें

  2. PostgreSQL इनर जॉइन के साथ डिलीट

  3. पोस्टग्रेएसक्यूएल रिवर्स लाइक

  4. सभी मापदंडों के साथ एनएसआईएस के साथ पोस्टग्रेज कैसे स्थापित करें?

  5. हेल्म चार्ट की निर्भरता में मूल्य निर्धारित करें