कमांड और तर्क इंजेक्शन रोकना
अविश्वसनीय इनपुट को उद्धृत, मान्य और ऐरे के रूप में पास करें, ताकि शब्द-विभाजन और eval-आधारित इंजेक्शन समाप्त हो जाएँ।
कमांड और तर्क इंजेक्शन रोकना, CoddyKit पर DevOps बूटकैंप का एक निःशुल्क पाठ है। यह 4 में से 1वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह DevOps बूटकैंप सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। DevOps बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
Bash में इंजेक्शन हमले क्यों होते हैं
Bash एक शक्तिशाली जोड़ने वाली भाषा है — यह पाठ को सीधे कर्नेल, अन्य प्रोग्रामों और उप-शेलों तक पहुँचाती है। जैसे ही अविश्वसनीय इनपुट बिना मान्यकरण या उद्धरण के किसी कमांड तक पहुँचता है, यही शक्ति एक जोखिम बन जाती है।
लगभग हर Bash इंजेक्शन के पीछे दो मूल कारण होते हैं:
- शब्द विभाजन: बिना उद्धरण वाले चर रिक्त स्थान पर (
IFS) विभाजित हो जाते हैं और एक तार्किक मान को कई शेल टोकनों में बदल देते हैं। - ग्लॉब विस्तार:
*,?और[जैसे वर्ण कमांड चलने से पहले ही शेल द्वारा विस्तारित कर दिए जाते हैं।
किसी फ़ाइलनाम, उपयोगकर्ता नाम, URL पैरामीटर या पर्यावरण चर को नियंत्रित करने वाला हमलावर इन दोनों का दुरुपयोग करके मनमाने कमांड चला सकता है, फ़ाइलें पढ़ सकता है या विशेषाधिकार बढ़ा सकता है।
यह पाठ ठीक-ठीक दिखाता है कि ये कमजोरियाँ कैसे दिखाई देती हैं और — इससे भी महत्वपूर्ण बात — सही उद्धरण, इनपुट मान्यकरण और सारणी-आधारित तर्क पास करने से इन्हें कैसे समाप्त किया जाए।
शब्द विभाजन: मौन खतरा
जब Bash को बिना उद्धरण वाला चर दिखाई देता है, तो वह उसके मान को $IFS में दिए गए किसी भी वर्ण (डिफ़ॉल्ट: स्पेस, टैब, नई पंक्ति) पर विभाजित कर देता है। जो एक तर्क जैसा दिखता है, वह कई तर्क बन जाता है।
नीचे दी गई लिपि चलाएँ और देखें कि स्पेस वाले फ़ाइलनाम को rm के लिए दो अलग-अलग तर्कों में कैसे बदल दिया जाता है।
#!/usr/bin/env bash
# Dangerous: unquoted variable
FILE='important file.txt'
# Create the file so the demo is self-contained
touch "$FILE"
echo "Files before:"
ls
# BUG: rm sees TWO arguments: 'important' and 'file.txt'
# If 'important' does not exist, rm prints an error but continues.
rm $FILE # <-- unquoted, word-split happens here
echo "Files after (unquoted rm):"
lsहमेशा उद्धरण लगाएँ: सुरक्षित Bash का पहला नियम
शब्द विभाजन से बचाव का सबसे सरल और प्रभावी तरीका है कि चर के विस्तारों पर हमेशा दोहरे उद्धरण लगाएँ।
"$var"— ठीक एक टोकन में विस्तारित होता है और स्पेस, टैब तथा नई पंक्तियों को सुरक्षित रखता है।'literal'— एकल उद्धरण: कोई भी विस्तार नहीं होता, इसलिए स्थिर स्ट्रिंग के लिए उपयोगी है।$varका बिना उद्धरण उपयोग कभी न करें, जब तक आपको स्पष्ट रूप से शब्द विभाजन और ग्लॉब विस्तार की आवश्यकता न हो।
नीचे दी गई लिपि पिछले उदाहरण का सुरक्षित रूप दिखाती है।
#!/usr/bin/env bash
set -euo pipefail
FILE='important file.txt'
touch "$FILE"
echo 'Files before:'
ls
# SAFE: double-quotes keep the filename as one token
rm "$FILE"
echo 'Files after (quoted rm):'
lsग्लॉब इंजेक्शन: जब * एक हथियार बन जाता है
बिना उद्धरण वाले चर पथनाम विस्तार (ग्लॉबिंग) के भी अधीन होते हैं। यदि उपयोगकर्ता-नियंत्रित इनपुट में * या ? हो, तो कमांड चलने से पहले Bash उसे फ़ाइल सिस्टम के अनुसार विस्तारित कर देता है।
एक पारंपरिक हमला: कोई वेब फ़ॉर्म PATTERN=* सेट करता है और लिपि cp $PATTERN /tmp/leak/ चलाती है — जिससे वर्तमान निर्देशिका की हर फ़ाइल कॉपी हो जाती है।
समाधान वही है: चर पर दोहरे उद्धरण लगाएँ। उद्धृत "$PATTERN" अक्षरशः पास किया जाता है; शेल उस पर ग्लॉब विस्तार नहीं करता।
#!/usr/bin/env bash
set -euo pipefail
# Simulate attacker-supplied input
PATTERN='*'
mkdir -p /tmp/safe_demo_src /tmp/safe_demo_dst
touch /tmp/safe_demo_src/secret1.txt /tmp/safe_demo_src/secret2.txt
cd /tmp/safe_demo_src
# UNSAFE: glob expands, copies every file
# cp $PATTERN /tmp/safe_demo_dst/
# SAFE: pattern is treated as a literal filename
cp "$PATTERN" /tmp/safe_demo_dst/ 2>&1 || echo 'No file named literally "*" — attack neutralised'
rm -rf /tmp/safe_demo_src /tmp/safe_demo_dstबिना उद्धरण वाले स्थितीय पैरामीटरों से तर्क इंजेक्शन
कॉल करने वाले से तर्क स्वीकार करने वाली लिपियाँ इंजेक्शन का प्रमुख लक्ष्य होती हैं। प्रत्येक स्थितीय पैरामीटर ($1, $2, ...) जहाँ भी उपयोग हो, वहाँ उस पर उद्धरण लगाना चाहिए।
विशेष रूप से खतरनाक तरीका है $@ या $* को बिना उद्धरण के किसी अन्य कमांड तक पहुँचाना:
"$@"— प्रत्येक स्थितीय पैरामीटर को अलग, व्यक्तिगत रूप से उद्धृत शब्द के रूप में विस्तारित करता है। हमेशा इसी रूप का उपयोग करें।$@या$*का बिना उद्धरण उपयोग — शब्द विभाजन और ग्लॉबिंग के अधीन होता है।"$*"— सभी पैरामीटरों को एक शब्द में जोड़ देता है (आमतौर पर आप ऐसा नहीं चाहते)।
#!/usr/bin/env bash
set -euo pipefail
# Safe wrapper: forward all arguments quoted
grep_wrapper() {
local pattern="$1"
shift
# "$@" preserves each file argument as one token
grep -rn "$pattern" "$@"
}
# Usage: ./script 'error msg' /var/log/syslog '/path with spaces/app.log'
echo 'Searching current script for "safe":'
grep_wrapper 'safe' "$0"eval और अमान्यीकृत इनपुट से कमांड इंजेक्शन
eval अपने तर्क को शेल कोड के रूप में फिर से पार्स करता है। eval तक पहुँचने वाला कोई भी अविश्वसनीय डेटा मनमाने कमांड चला सकता है।
खतरनाक आम तरीके:
eval "$user_input"eval echo \$$var(अप्रत्यक्ष चर खोज)- उपयोगकर्ता डेटा को
bash -c "$input"के माध्यम से पास करना
नियम: अविश्वसनीय इनपुट को कभी भी eval या bash -c तक न पहुँचाएँ। सुरक्षित Bash विकल्पों का उपयोग करें:
- अप्रत्यक्ष विस्तार:
${!varname},eval echo \$$varnameके स्थान पर - गतिशील कुंजी-मान खोज के लिए संबद्ध सारणियाँ
- तैयार किए गए कमांड स्ट्रिंगों के स्थान पर फ़ंक्शन
#!/usr/bin/env bash
set -euo pipefail
# Simulated attacker-supplied variable name
VARNAME='PATH; echo INJECTED'
# UNSAFE: eval lets attacker run 'echo INJECTED'
# eval "echo \$$VARNAME"
# SAFE: indirect expansion only resolves valid variable names
# First validate that VARNAME is a legal identifier
if [[ "$VARNAME" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
echo "Value: ${!VARNAME}"
else
echo "ERROR: invalid variable name: '$VARNAME'" >&2
exit 1
fiइनपुट मान्यकरण: अस्वीकृति-सूची के बजाय अनुमति-सूची
ज्ञात-खराब वर्णों को अस्वीकार करना (अस्वीकृति-सूची) नाज़ुक तरीका है — हमलावर ऐसे एन्कोडिंग या वर्ण खोज लेते हैं जिन्हें आपने शामिल नहीं किया। इसके बजाय अनुमति-सूची बनाएँ: केवल उन्हीं वर्णों को स्वीकार करें जिन्हें आप सुरक्षित जानते हैं।
Bash में अनुमति-सूची की रणनीतियाँ:
- रेगेक्स मिलान:
[[ "$input" =~ ^[A-Za-z0-9_-]+$ ]] - प्रतिरूप मिलान:
case "$input" in [A-Za-z0-9]*) ... ;; esac - एनम जाँच: निश्चित वैध मानों के समूह से तुलना करें
सीमा पर — अर्थात इनपुट के लिपि में प्रवेश करते ही — किसी भी कमांड तक पहुँचने से पहले मान्यकरण करें।
#!/usr/bin/env bash
set -euo pipefail
validate_username() {
local name="$1"
# Allowlist: only lowercase letters, digits, underscore, hyphen; 1-32 chars
if [[ ! "$name" =~ ^[a-z0-9_-]{1,32}$ ]]; then
echo "ERROR: invalid username '${name}'" >&2
return 1
fi
echo "Username accepted: $name"
}
validate_username 'alice' # OK
validate_username 'bob_smith-2' # OK
validate_username 'root; rm -rf /' # REJECTED
validate_username '../etc/passwd' # REJECTEDतर्क सुरक्षित रूप से पास करने के लिए सारणियों का उपयोग
जब आपको किसी कमांड को गतिशील रूप से बनाना हो — जैसे सशर्त रूप से फ़्लैग जोड़ना या इनपुट पर दोहराना — तो स्ट्रिंग जोड़ने के बजाय Bash सारणी का उपयोग करें।
स्ट्रिंग जोड़ने से पूरी संरचना समाप्त हो जाती है; Bash सारणी प्रत्येक तर्क को एक अलग तत्व के रूप में सुरक्षित रखती है और शेल द्वारा उसे दोबारा पार्स नहीं किया जाता।
- घोषित करें:
args=() - जोड़ें:
args+=(--flag "$value") - चलाएँ:
command "${args[@]}"
"${args[@]}" प्रत्येक तत्व को अलग, व्यक्तिगत रूप से उद्धृत शब्द के रूप में विस्तारित करता है — ठीक "$@" की तरह।
#!/usr/bin/env bash
set -euo pipefail
# Build a find command safely with an array
BASEDIR='/tmp'
USER_PATTERN='*.log' # could come from user input (validate first!)
MAX_DAYS=7
cmd=(find "$BASEDIR" -type f -name "$USER_PATTERN" -mtime "+${MAX_DAYS}")
# Optionally add -delete only when requested
DELETE=false
if [[ "$DELETE" == 'true' ]]; then
cmd+=(-delete)
fi
echo "Running: ${cmd[*]}"
"${cmd[@]}"-- विभाजक: फ़्लैग इंजेक्शन से सुरक्षा
सही ढंग से उद्धृत तर्क को भी विकल्प फ़्लैग समझ लिया जा सकता है, यदि वह - से शुरू होता हो। rm "$file" पर विचार करें, जहाँ file='-rf .' है: उद्धरण शब्द विभाजन से बचाते हैं, लेकिन rm फिर भी -rf को फ़्लैग के रूप में समझता है।
POSIX परंपरा में -- अधिकांश GNU/BSD उपयोगिताओं को विकल्पों की समाप्ति का संकेत देता है। -- के बाद की हर चीज़ को स्थितीय तर्क माना जाता है, फ़्लैग नहीं।
#!/usr/bin/env bash
set -euo pipefail
# Simulate a dangerous filename supplied by the user
FILENAME='-rf /tmp/safe_demo_target'
mkdir -p /tmp/safe_demo_target
touch /tmp/safe_demo_target/keep_me.txt
echo 'Files before:'
ls /tmp/safe_demo_target/
# UNSAFE (flag injection — do NOT uncomment in real systems):
# rm "$FILENAME"
# SAFE: -- ends option processing; filename is treated literally
rm -- "$FILENAME" 2>&1 || echo "No such file (attack neutralised): $FILENAME"
echo 'Files after:'
ls /tmp/safe_demo_target/
rm -rf /tmp/safe_demo_targetSQL और बाहरी उपकरणों के लिए इनपुट का स्वच्छीकरण
जब Bash लिपियाँ डेटाबेस CLI (psql, mysql), उपयोगकर्ता-प्रदत्त URL वाले curl या ऐसे ही उपकरण चलाती हैं, तो दो अतिरिक्त स्तर लागू होते हैं:
- पैरामीटरयुक्त क्वेरी: उपयोगकर्ता डेटा को SQL स्ट्रिंग में कभी न मिलाएँ। मानों को
psqlमें-vयाcurlमें--data-urlencodeके माध्यम से पास करें। - डेटा को कोड से अलग रखें: शाब्दिक प्रारूप स्ट्रिंग के साथ
printfका उपयोग करें; उपयोगकर्ता इनपुट को कभी भी प्रारूप स्ट्रिंग न बनने दें।
नीचे दिया उदाहरण PostgreSQL से सुरक्षित रूप से क्वेरी करता है और उपयोगकर्ता-प्रदत्त मान को SQL पाठ से पूरी तरह बाहर रखता है।
#!/usr/bin/env bash
set -euo pipefail
# Validate first: only allow alphanumeric usernames
USERNAME="${1:-alice}"
if [[ ! "$USERNAME" =~ ^[a-z0-9_]{1,32}$ ]]; then
echo 'ERROR: invalid username' >&2
exit 1
fi
# UNSAFE:
# psql -c "SELECT * FROM users WHERE name = '$USERNAME';"
# SAFE: pass value as a psql variable, never inside the SQL text
# psql -v username="$USERNAME" -c 'SELECT * FROM users WHERE name = :username;'
# Demonstrate the principle with printf (safe format string usage)
printf 'Query would use username: %s\n' "$USERNAME"सुरक्षा सुदृढ़ीकरण जाँच-सूची: सब कुछ एक साथ लागू करना
उत्पादन-स्तर की सुरक्षित Bash लिपि इस पाठ की हर तकनीक को एक सुसंगत, परतदार सुरक्षा में जोड़ती है। यहाँ एक न्यूनतम लेकिन पूर्ण रूप से सुदृढ़ नमूना है:
set -euo pipefail— त्रुटि होने पर बाहर निकलें, अनिर्धारित चरों को त्रुटि मानें और पाइप की विफलताएँ आगे पहुँचाएँ।- प्रवेश पर मान्यकरण करें — किसी भी बाहरी इनपुट के किसी कमांड तक पहुँचने से पहले उसकी अनुमति-सूची जाँचें।
- हर चीज़ पर उद्धरण लगाएँ —
"$var","$@","${array[@]}"— विभाजन की आवश्यकता होने के अलावा कोई अपवाद नहीं। - गतिशील कमांड बनाने के लिए सारणियों का उपयोग करें।
- उपयोगकर्ता-प्रदत्त फ़ाइलनाम या स्ट्रिंग पास करते समय तर्कों के आगे
--लगाएँ। - अविश्वसनीय डेटा के साथ
evalका कभी उपयोग न करें; अप्रत्यक्ष खोज के लिए${!var}को प्राथमिकता दें। - अनुमतियाँ सीमित रखें — लिपियाँ चलाने के लिए न्यूनतम आवश्यक विशेषाधिकारों का उपयोग करें; उपयोगकर्ता इनपुट स्वीकार करने वाली लिपियों में
sudoका उपयोग न करें।
#!/usr/bin/env bash
# Hardened template — safe argument injection prevention
set -euo pipefail
IFS=$'\n\t'
#--- 1. Validate inputs at the boundary ---
SEARCH_DIR="${1:-}"
PATTERN="${2:-}"
[[ -z "$SEARCH_DIR" || -z "$PATTERN" ]] && { echo 'Usage: script <dir> <pattern>' >&2; exit 1; }
[[ ! "$SEARCH_DIR" =~ ^[A-Za-z0-9/_.-]+$ ]] && { echo 'ERROR: unsafe directory path' >&2; exit 1; }
[[ ! "$PATTERN" =~ ^[A-Za-z0-9._-]+$ ]] && { echo 'ERROR: unsafe pattern' >&2; exit 1; }
#--- 2. Build command with an array ---
cmd=(find -- "$SEARCH_DIR" -type f -name "$PATTERN")
#--- 3. Execute — no string interpolation, no eval ---
echo "Executing: ${cmd[*]}"
"${cmd[@]}"ज्ञान जाँच: उद्धरण और इंजेक्शन की रोकथाम
इस पाठ की मुख्य अवधारणाओं की अपनी समझ जाँचें।
पाठ का पुनरावलोकन: कमांड और तर्क इंजेक्शन की रोकथाम
आपने सुरक्षित Bash इनपुट प्रबंधन के लिए संपूर्ण रक्षात्मक साधन-संग्रह पढ़ लिया है:
- शब्द विभाजन और ग्लॉब विस्तार वे मूल प्रक्रियाएँ हैं जो असुरक्षित चरों को इंजेक्शन के साधनों में बदल देती हैं।
- दोनों खतरों को रोकने के लिए हर चर पर दोहरे उद्धरण लगाएँ (
"$var","$@","${arr[@]}")। - तर्क आगे भेजते समय
"$@"का उपयोग करें —$@या$*का बिना उद्धरण उपयोग कभी न करें। - फ़्लैग इंजेक्शन रोकने के लिए उपयोगकर्ता-प्रदत्त फ़ाइलनामों के आगे
--लगाएँ। - किसी भी कमांड तक पहुँचने से पहले रेगेक्स सुरक्षा-जाँच (
[[ $v =~ ^pattern$ ]]) से सभी बाहरी इनपुट के लिए अनुमति-सूची बनाएँ। - सारणियों से गतिशील कमांड बनाएँ (
cmd+=()→"${cmd[@]}"), स्ट्रिंग जोड़कर कभी नहीं। evalऔरbash -c "$input"को हटाएँ; सुरक्षित अप्रत्यक्ष विस्तार के लिए${!varname}का उपयोग करें।- सुदृढ़ आधार के लिए लिपियों की शुरुआत हमेशा
set -euo pipefailऔरIFS=$'\n\t'से करें।
हर लिपि की पहली पंक्ति से इन तरीकों को लगातार लागू करने पर इंजेक्शन-श्रेणी की कमजोरियों के लिए Bash की हमले की सतह लगभग शून्य हो जाती है।
एआई शिक्षक के साथ DevOps बूटकैंप सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 142
- पाठ
- 568
अक्सर पूछे जाने वाले प्रश्न
क्या “कमांड और तर्क इंजेक्शन रोकना” पाठ निःशुल्क है?
हाँ — DevOps बूटकैंप अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “कमांड और तर्क इंजेक्शन रोकना” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। DevOps बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“कमांड और तर्क इंजेक्शन रोकना” में मैं क्या सीखूँगा?
अविश्वसनीय इनपुट को उद्धृत, मान्य और ऐरे के रूप में पास करें, ताकि शब्द-विभाजन और eval-आधारित इंजेक्शन समाप्त हो जाएँ। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ DevOps बूटकैंप का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या DevOps बूटकैंप शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर DevOps बूटकैंप शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 1वाँ पाठ है।
“कमांड और तर्क इंजेक्शन रोकना” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस DevOps बूटकैंप पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर DevOps बूटकैंप पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- कमांड और तर्क इंजेक्शन रोकना
- गोपनीय जानकारी का सुरक्षित प्रबंधन और परिवेश की स्वच्छता
- न्यूनतम-अधिकार निष्पादन और sudo अनुशासन
- ShellCheck से स्थैतिक विश्लेषण और ऑडिट