WordPress की ज़्यादातर सुरक्षा समस्याएँ चालाक हमलावरों के WordPress को तोड़ने से नहीं आतीं। वे थीम और प्लगइन की छोटी-छोटी कमियों से आती हैं: ऐसा फ़ॉर्म जो जो कुछ भी सबमिट हो उस पर भरोसा कर ले, कोई वैल्यू जो सीधे पेज पर प्रिंट हो जाए, ऐसी सेटिंग स्क्रीन जहाँ कोई भी लॉग-इन यूज़र पहुँच जाए। हर कमी आम तौर पर एक छूटी हुई फ़ंक्शन कॉल होती है। डराने वाली बात यह है कि कोड कितना सामान्य दिखता है; राहत की बात यह है कि इनमें से ज़्यादातर को बंद करने के लिए कितने कम फ़ंक्शन चाहिए।
यह गाइड WordPress के उन गिने-चुने फ़ंक्शन को कवर करती है जो ज़्यादातर कमज़ोरियों को रोकते हैं, चार आसान आदतों में बाँटकर: जो अंदर आए उसे सैनिटाइज़ करें, जो बाहर जाए उसे एस्केप करें, नॉन्स से इरादे की पुष्टि करें, और अनुमतियाँ जाँचें। हर एक के साथ असली उदाहरण है।
सोचने का तरीक़ा: सीमा पार करने वाली किसी चीज़ पर भरोसा न करें
डेटा सीमाओं पर हाथ बदलता है: जब कोई विज़िटर फ़ॉर्म सबमिट करता है, जब कोई URL पैरामीटर पढ़ा जाता है, जब डेटाबेस की कोई वैल्यू HTML में प्रिंट होती है, जब कोई AJAX रिक्वेस्ट आती है। हर सीमा पर दो सवाल पूछें:
- अंदर आते समय: क्या यह डेटा वही है जिसकी मुझे उम्मीद है, और क्या इसे सेव करना सुरक्षित है?
- बाहर जाते समय: क्या यह डेटा उस HTML, JavaScript या URL को तोड़ सकता है जिसमें इसे रखा जा रहा है?
WordPress हर स्थिति के लिए एक फ़ंक्शन देता है। इन्हें लगातार इस्तेमाल करना ही ज़्यादातर काम है।
आदत 1: इनपुट सैनिटाइज़ करें
सैनिटाइज़ करना डेटा को आते ही, सेव या इस्तेमाल करने से पहले, साफ़ करता है। वह फ़ंक्शन चुनें जो वैल्यू के होने वाले रूप से मेल खाए:
| फ़ंक्शन | किसके लिए |
|---|---|
sanitize_text_field() | एक लाइन का टेक्स्ट, जैसे नाम और शीर्षक |
sanitize_textarea_field() | कई लाइनों का सादा टेक्स्ट |
sanitize_email() | ईमेल एड्रेस |
absint() | ID और दूसरी ग़ैर-ऋणात्मक पूर्ण संख्याएँ |
sanitize_key() | छोटे अक्षरों वाली key और slug |
esc_url_raw() | URL जिन्हें आप सेव करने वाले हैं |
wp_kses_post() | HTML जिसमें सिर्फ़ सुरक्षित पोस्ट फ़ॉर्मेटिंग की अनुमति हो |
$_POST और $_GET की वैल्यू में स्लैश हो सकते हैं, इसलिए पहले उन्हें अनस्लैश करें:
$name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
$email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
$post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;सैनिटाइज़ करना वैलिडेट करने जैसा नहीं है। साफ़ करने के बाद जाँचें कि वैल्यू का कोई मतलब बनता है: क्या is_email() के हिसाब से ईमेल एड्रेस मान्य है, क्या ID किसी मौजूद पोस्ट का है, क्या ऑप्शन अनुमत विकल्पों में से एक है?
आदत 2: आउटपुट एस्केप करें
एस्केपिंग उस पल होती है जब आप डेटा प्रिंट करते हैं, और यह इस पर निर्भर है कि डेटा कहाँ जा रहा है। यह क्रॉस-साइट स्क्रिप्टिंग (XSS) से बचाव है, जिसमें कोई नुक़सानदेह स्क्रिप्ट किसी और के ब्राउज़र में चल जाती है।
| फ़ंक्शन | जब इसमें प्रिंट कर रहे हों |
|---|---|
esc_html() | सामान्य HTML टेक्स्ट |
esc_attr() | HTML एट्रिब्यूट की वैल्यू |
esc_url() | कोई href या src |
esc_js() | इनलाइन JavaScript स्ट्रिंग |
wp_kses_post() | ऐसा कंटेंट जिसमें सुरक्षित HTML फ़ॉर्मेटिंग हो सकती है |
<a href="<?php echo esc_url( $link ); ?>" title="<?php echo esc_attr( $title ); ?>">
<?php echo esc_html( $title ); ?>
</a>सुनहरा नियम है देर से एस्केप करें: ठीक वहीं एस्केप करें जहाँ आप echo करते हैं, भले ही आपको लगे कि वैल्यू पहले सैनिटाइज़ हो चुकी है। कोड बदलता है, डेटा के स्रोत बदलते हैं, और देर से एस्केप करना हर आउटपुट को अपने-आप में सुरक्षित रखता है।
आदत 3: नॉन्स से इरादे की पुष्टि करें
नॉन्स एक टोकन है जो साबित करता है कि रिक्वेस्ट आपके अपने फ़ॉर्म से आई, और क्रॉस-साइट रिक्वेस्ट फ़ॉर्जरी (CSRF) से बचाता है, जिसमें कोई दूसरी वेबसाइट किसी लॉग-इन यूज़र के ब्राउज़र को धोखे से रिक्वेस्ट भेजने पर मजबूर करती है। कुछ भी बदलने वाले हर फ़ॉर्म में इसे जोड़ें:
<form method="post">
<?php wp_nonce_field( 'acme_save_settings', 'acme_nonce' ); ?>
<input type="text" name="acme_title">
<button type="submit">Save</button>
</form>और प्रोसेस करने से पहले इसे जाँचें:
if ( ! isset( $_POST['acme_nonce'] )
|| ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['acme_nonce'] ) ), 'acme_save_settings' ) ) {
wp_die( esc_html__( 'Security check failed.', 'acme' ) );
}AJAX के लिए wp_create_nonce() से नॉन्स बनाएँ, उसे रिक्वेस्ट के साथ भेजें, और check_ajax_referer() से जाँचें।
आदत 4: कैपेबिलिटी जाँचें
नॉन्स साबित करता है कि रिक्वेस्ट आपके फ़ॉर्म से आई। यह साबित नहीं करता कि व्यक्ति को वह काम करने की अनुमति है। इसके साथ हमेशा कैपेबिलिटी जाँच जोड़ें:
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have permission to do this.', 'acme' ) );
}काम से मेल खाने वाली कैपेबिलिटी चुनें: साइट सेटिंग के लिए manage_options, कंटेंट एडिटिंग के लिए edit_posts, किसी ख़ास पोस्ट के लिए ID के साथ edit_post। REST API रूट के लिए जाँच को permission_callback में रखें, और डेटा बदलने वाली किसी भी चीज़ के लिए कभी __return_true इस्तेमाल न करें।
सब एक साथ: एक सुरक्षित सेटिंग हैंडलर
function acme_handle_settings() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'Not allowed.', 'acme' ) );
}
check_admin_referer( 'acme_save_settings', 'acme_nonce' );
$title = isset( $_POST['acme_title'] )
? sanitize_text_field( wp_unslash( $_POST['acme_title'] ) )
: '';
update_option( 'acme_title', $title );
wp_safe_redirect( admin_url( 'options-general.php?page=acme&updated=1' ) );
exit;
}
add_action( 'admin_post_acme_save', 'acme_handle_settings' );यहाँ हर आदत दिखती है: अनुमति की जाँच, नॉन्स की जाँच, सैनिटाइज़ किया इनपुट, और सुरक्षित रीडायरेक्ट जिसके बाद exit है, जो भूलना आसान है और ज़रूरी है, क्योंकि रीडायरेक्ट सिर्फ़ एक हेडर भेजता है और वरना कोड चलता रहता।
डेटाबेस क्वेरी
WordPress के अपने फ़ंक्शन को प्राथमिकता दें, जैसे get_posts(), WP_Query और update_option(), जो आपके लिए सुरक्षा संभालते हैं। जब आपको सच में कस्टम SQL क्वेरी चाहिए, तो वेरिएबल सीधे क्वेरी में डालने के बजाय हमेशा प्लेसहोल्डर के साथ $wpdb->prepare() इस्तेमाल करें। यह एक आदत SQL इंजेक्शन रोकती है।
वे ग़लतियाँ जो रिव्यूअर बार-बार पकड़ते हैं
- आउटपुट के बजाय इनपुट पर एस्केप करना। डेटाबेस में
esc_html()से एनकोड किया टेक्स्ट सेव करने से बाद में कैरेक्टर दो बार एनकोड हो जाते हैं। अंदर आते समय सैनिटाइज़ करें, बाहर जाते समय एस्केप। - ग़लत एस्केपिंग फ़ंक्शन इस्तेमाल करना, जैसे किसी
hrefके अंदरesc_html()। URL कोesc_url()चाहिए, एट्रिब्यूट कोesc_attr()। - अपने ही डेटाबेस के डेटा पर भरोसा करना। अगर उसे कोई यूज़र लिख सकता था, तो प्रिंट करते समय उसे अविश्वसनीय मानें।
- नॉन्स जाँचना पर कैपेबिलिटी नहीं, या इसका उलटा। आपको लगभग हमेशा दोनों चाहिए।
- रीडायरेक्ट के बाद
exitभूल जाना, जिससे हैंडलर का बाक़ी हिस्सा फिर भी चलता है।
झटपट रेफ़रेंस
WordPress Functions Reference इस गाइड के मुख्य सुरक्षा फ़ंक्शन कवर करता है, जिनमें sanitize_text_field(), absint(), esc_html(), esc_attr(), esc_url(), wp_kses_post(), नॉन्स फ़ंक्शन और current_user_can() शामिल हैं, साथ में क्वेरी, हुक्स, एसेट, रजिस्ट्रेशन और कैशिंग के सबसे ज़्यादा इस्तेमाल होने वाले फ़ंक्शन, हर एक के छोटे चलते उदाहरण और उसके आधिकारिक डॉक्यूमेंटेशन के लिंक के साथ। सर्च बॉक्स पर जाने के लिए / दबाएँ और कोई काम टाइप करें, जैसे "nonce" या "escape"।
शुरुआत से ही शामिल करें
सुरक्षा को बाद में जोड़ने से कहीं आसान है उसे शुरू से बनाना। नया प्लगइन शुरू करते समय WordPress Plugin Generator प्रीफ़िक्स वाले नाम, एस्केप किए आउटपुट और Settings API पर बने सेटिंग पेज के साथ ढाँचा बनाता है, जो आपके लिए नॉन्स संभालता है। अपना पहला WordPress प्लगइन बनाने की हमारी गाइड इसे क़दम दर क़दम बताती है। लॉन्च से पहले WordPress Security Checker आपकी साइट के कॉन्फ़िगरेशन की आख़िरी समीक्षा के लिए काम का है।
अगर आप कोडिंग करते समय AI असिस्टेंट के साथ काम करते हैं, तो चैट में असली क्रेडेंशियल, key या ग्राहकों का डेटा पेस्ट करने से बचें; निजी डेटा शेयर किए बिना ChatGPT इस्तेमाल करने की हमारी गाइड एक सुरक्षित तरीक़ा बताती है।
चार आदतें, ज़्यादातर समस्याएँ हल
जो अंदर आए उसे सैनिटाइज़ करें। जो बाहर जाए उसे जितनी देर से हो सके, एस्केप करें। नॉन्स से इरादे की पुष्टि करें। हर बार अनुमतियाँ जाँचें। इनमें से कोई फ़ंक्शन जटिल नहीं है, और एक बार ये आदत बन जाएँ, तो आप दूसरों के कोड में भी कमियाँ पकड़ने लगेंगे, और अच्छे WordPress डेवलपर ठीक इसी तरह सोचते हैं।



