2011-06-23 13 views
43

मेरे पास एक साधारण वेबसाइट है जहां मैं पीडीओ का उपयोग कर एक MySQL सर्वर से कनेक्शन स्थापित करता हूं।कनेक्शन विफल होने पर पीडीओ मेरा पासवर्ड क्यों प्रिंट करता है?

$dbh = new PDO('mysql:host=localhost;dbname=DB;port=3306', 'USER', 
'SECRET',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); 

मैं अपनी साइट और सर्वर कनेक्शन सीमा पर कुछ यातायात था पर पहुँच गया था, और वेबसाइट में इस त्रुटि फेंकता है, मेरी मैदान पासवर्ड के साथ!

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[08004] [1040] Too many connections' in /home/domain/html/index.php:xxx Stack trace: #0 /home/domain/html/index.php(64): PDO->__construct('mysql:host=loca...', 'USER', 'SECRET', Array) #1 {main} thrown in /home/domain/html/index.php on line 64

विडंबना यह है कि मैं सुरक्षा कारणों के लिए पीडीओ का प्रयोग किया, तो यह वास्तव में, मुझे हैरान इस सटीक त्रुटि कुछ आप सरल http बाढ़ का उपयोग कर सबसे साइटों पर बहुत आसानी से उत्तेजित कर सकते हैं क्योंकि।

अब मैंने कोशिश/पकड़ ब्लॉक में अपना कनेक्शन लपेट लिया है, लेकिन फिर भी मुझे लगता है कि यह विनाशकारी है!

मैं पीडीओ के लिए नया हूं और इसलिए मेरा सवाल है: मुझे सुरक्षित होने पर विचार करने के लिए क्या करना है? मैं एक सुरक्षित तरीके से कनेक्शन कैसे स्थापित करूं? क्या इस तरह के अन्य ज्ञात सुरक्षा छेद हैं जिन्हें मुझे अवगत होना चाहिए?

+0

देखें: http://stackoverflow.com/questions/5811834/why - यह-हो-खराब-php-code/5811853 # 5811853 गतिशील तालिका/डीबी/कॉलम नामों का उपयोग करते समय एक छेद के लिए, और उस छेद को कैसे प्लग करें। – Johan

+0

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

+0

पवित्र मोली यह बीमार है! हे भगवान! यह बिल्कुल अपमानजनक है! आपको अपने ठंडा रखने और सीएपीएस आरएजी में नहीं जाने के लिए बस अधिक अपवॉट की आवश्यकता है। – Sharky

उत्तर

16

इस समस्या से बचने के लिए आपको अपने PHP.ini में display_errors = off होना चाहिए। पीडीओ के अलावा, इन तरह के विवरण प्रकट करने वाली त्रुटियां कई स्थानों से आती हैं।

हां, आपको इसे एक कोशिश/पकड़ ब्लॉक में भी होना चाहिए।

आप $pdo->setAttribute(PDO::ERRMODE_SILENT) भी कर सकते हैं, लेकिन फिर आपको कोशिश/पकड़ ब्लॉक का उपयोग करने के बजाय मैन्युअल रूप से त्रुटि कोड की जांच करने की आवश्यकता है। अधिक त्रुटि स्थिरांक के लिए http://php.net/manual/en/pdo.setattribute.php देखें।

+12

ठीक है, मैं समझता हूं लेकिन मुझे अभी भी लगता है कि डिफ़ॉल्ट सुरक्षित पक्ष होना चाहिए ... –

+2

@ जो, तो आपको इसे पीडीओ डेवलपर्स के साथ ले जाना चाहिए। मुझे इस तरह के ढेर से जानकारी लौटने के साथ कोई समस्या नहीं है। एक बार जब आप इसके बारे में जानते हैं, तो यह कोई मुद्दा नहीं है। बेशक, कोशिश/पकड़ कुछ अनुप्रयोगों पर भुला दिया जाएगा ... अनिवार्य रूप से यह कुछ के लिए एक समस्या होगी ... आप इसके बारे में सही हैं। – Brad

+1

इन दोनों सुझावों के लिए मेरे लिए काम नहीं लग रहा है। जब कनेक्शन विफल हो जाता है, तो त्रुटि स्टैक स्क्रीन पर मुद्रित होता है जिसमें सादा पाठ पासवर्ड दिखाई देता है। मैं PHP ActiveRecord का उपयोग कर रहा हूँ। –

6

ठीक है, इससे मुझे थोड़ा गड़बड़ कर दिया गया है, त्रुटि रिपोर्टिंग का उपयोग डिबगिंग उद्देश्यों के लिए है, यह आपको समस्याओं को तुरंत ढूंढने और ठीक करने की अनुमति देता है।

जब आप एक जीवंत वातावरण में हों तो आपका सर्वर केवल आंतरिक लॉगिंग के लिए कॉन्फ़िगर किया जाना चाहिए, और प्रत्यक्ष आउटपुट नहीं, इसलिए मूल रूप से आपको अपने php.ini में त्रुटियों के आउटपुट को बंद करना होगा।

display_errors = Off 

लेकिन जब आप अपने परीक्षण वातावरण में हैं, तो यह ढेर केवल आपकी मदद करने के लिए एक उपकरण है, और कॉन्फ़िगर करने योग्य है।

जब लाइव वातावरण में त्रुटियां होती हैं तो वे लॉग इन होंगी, इसलिए आपको हमेशा अपनी लॉग फाइलों की जांच करनी चाहिए और फिर तदनुसार ठीक करना चाहिए।

लोग निर्दिष्ट कर सकते हैं कि आप अपने PHP एप्लिकेशन में त्रुटियों का प्रबंधन कर सकते हैं लेकिन व्यक्तिगत वरीयता से मुझे लगता है कि यह इसके बारे में जाने का गलत तरीका है, आईएनआई को कॉन्फ़िगर करना और आपके वेब सर्वर और MySQL/MsSQL के लिए कॉन्फ़िगरेशन फ़ाइलों को कॉन्फ़िगर करना परिणामस्वरूप होगा अधिक तीव्र प्रबंधन।

यदि आपका आवेदन एक सार्वजनिक एप्लिकेशन है तो आवेदन के भीतर त्रुटियों को संभालने का भी एक अच्छा विचार होगा क्योंकि ग्राहकों का एक बड़ा प्रतिशत साझा होस्टिंग पर हो सकता है और सर्वर कॉन्फ़िगरेशन तक पूर्ण पहुंच नहीं है।

+0

आप अपनी लॉग फ़ाइलों में पासवर्ड भी नहीं चाहते हैं ... – HackSlash

7

सरल समाधान का यह पीडीओ निर्माता द्वारा फेंका PDOException को पकड़ने के लिए:

try { 
    $dbh = new PDO('mysql:host=localhost;dbname=DB;port=3306', 'USER', 
    'SECRET',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); 
} catch (PDOException $e) { 
    throw new Exception('Could not connect to database'); 
} 
+0

... जो एक त्रुटि संदेश के बिना डेवलपर को छोड़ रहा है जो अन्यथा उन्हें किसी समस्या को हल करने में मदद करेगा। –

+1

अपवाद प्राप्त हो रहा है "डेटाबेस से कनेक्ट नहीं हो सका" डेवलपर को कोई जानकारी नहीं है? मुझे नहीं लगता कि – Matthias

+3

आधार अवधारणा खराब है। किसी को किसी ऑब्जेक्ट में सादा पासवर्ड नहीं रखना चाहिए और इसे स्मृति में रखना चाहिए। सही समाधान पीडीओ कोड को बदलना होगा, न कि अपवाद के संदेश में सादा पासवर्ड डालना। मैं इसे पीडीओ में एक बग और सुरक्षा छेद के रूप में मानता हूं। – nagylzs

1

हम इनकोडिंग यूज़रनेम और पासवर्ड का उपयोग करें और पीडीओ निर्माता में उन लोगों को डिकोड, तो हम PDOException पकड़ने और पुराने के साथ एक नया PDOException फेंक इसका संदेश अपवाद करें, ताकि ट्रेस केवल एन्कोडेड उपयोगकर्ता नाम और पासवर्ड दिखाएगा।

PHP के लिए एक अच्छा एन्क्रिप्शन पुस्तकालय है: शांत/php-एन्क्रिप्शन

https://github.com/defuse/php-encryption

उदाहरण कोड:

<?php 
class myPDOWrapper extends PDO 
    { 

     public function __construct(string $dns, string $encodedUser, string $encodedPassword) 
     { 
      try { 
       parent::__construct($dns, $this->decodeFunction($encodedUser), $this->decodeFunction($encodedPassword), 
        [ 
         PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
        ] 
       ); 
      } 
      catch (PDOException $exception) { 
       throw new PDOException($exception->getMessage()); 
      } 
     } 

     private function decodeFunction(string $encoded): string 
     { 
      return \Defuse\Crypto\Crypto::decrypt($encoded, $this->decodeKey()); 
     } 

     private function decodeKey(): \Defuse\Crypto\Key 
     { 
      static $key = null; 

      if(null === $key) { 
       $key = \Defuse\Crypto\Key::loadFromAsciiSafeString(getenv('MY_PDO_DECODE_KEY')); 
      } 

      return $key; 
     } 
    } 
संबंधित मुद्दे