การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์
ใส่เครื่องหมายคำพูด ตรวจสอบ และส่งอินพุตที่ไม่น่าเชื่อถือผ่านอาร์เรย์ เพื่อกำจัดการแยกคำและการแทรกผ่าน eval
การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์ เป็นบทเรียน DevOps Bootcamp ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน DevOps Bootcamp และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 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_targetการทำให้อินพุตปลอดภัยสำหรับ SQL และเครื่องมือภายนอก
เมื่อสคริปต์ Bash เรียกใช้เครื่องมือบรรทัดคำสั่งของฐานข้อมูล (psql, mysql) เรียกใช้ curl พร้อม URL ที่ผู้ใช้ระบุ หรือเรียกใช้เครื่องมือที่คล้ายกัน จะมีชั้นการป้องกันเพิ่มเติมสองประการ:
- คิวรีแบบมีพารามิเตอร์: อย่าแทรกข้อมูลผู้ใช้ลงในสตริง SQL โดยตรง ให้ส่งค่าผ่าน
-vในpsqlหรือ--data-urlencodeในcurl - แยกข้อมูลออกจากโค้ด: ใช้
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 สำหรับช่องโหว่ประเภทการฉีดคำสั่งได้จนเกือบเป็นศูนย์
คำถามที่พบบ่อย
บทเรียน “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส DevOps Bootcamp ให้อัปเกรดเป็น CoddyKit PRO คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์”
ใส่เครื่องหมายคำพูด ตรวจสอบ และส่งอินพุตที่ไม่น่าเชื่อถือผ่านอาร์เรย์ เพื่อกำจัดการแยกคำและการแทรกผ่าน eval คุณปฏิบัติ DevOps Bootcamp ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน DevOps Bootcamp หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน DevOps Bootcamp บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน DevOps Bootcamp นี้ได้ไหม
ได้ บทเรียน DevOps Bootcamp ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การป้องกันการแทรกคำสั่งและอาร์กิวเมนต์
- การจัดการความลับอย่างปลอดภัยและสุขอนามัยของสภาพแวดล้อม
- การทำงานด้วยสิทธิ์น้อยที่สุดและวินัยในการใช้ sudo
- การวิเคราะห์แบบสถิตและการตรวจสอบด้วย ShellCheck