Analisis Statis dan Audit dengan ShellCheck
Integrasikan ShellCheck ke dalam gerbang keamanan dan tafsirkan temuannya untuk memperkuat setiap skrip.
Analisis Statis dan Audit dengan ShellCheck adalah pelajaran Linux Command Line & Bash Scripting Mastery gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Linux Command Line & Bash Scripting Mastery, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Linux Command Line & Bash Scripting Mastery mencakup 4 pelajaran total.
Apa Itu ShellCheck dan Mengapa Penting
ShellCheck adalah alat analisis statis sumber terbuka untuk skrip shell. Alat ini mengurai sumber Bash (serta POSIX sh, dash, dan ksh) tanpa menjalankannya, lalu melaporkan bug, konstruksi yang tidak aman, masalah portabilitas, dan masalah gaya—masing-masing diberi kode aturan unik seperti SC2086.
Dalam alur yang diperkuat keamanannya, ShellCheck bertindak sebagai gerbang wajib: tidak ada skrip yang dikirim sebelum lolos pemeriksaan. Hal ini penting karena:
- Banyak kerentanan shell (pemisahan kata, injeksi, perluasan tanpa tanda kutip) tidak terlihat saat pengujian jalur normal, tetapi muncul saat menerima input yang dikendalikan penyerang.
- ShellCheck menangkap kelas bug ini sebelum waktu eksekusi, tanpa biaya.
- ShellCheck mendokumentasikan mengapa setiap pola berbahaya, sehingga kesadaran tim Anda meningkat seiring waktu.
Pasang alat ini di sistem apa pun:
# Debian / Ubuntu
sudo apt-get install shellcheck
# macOS (Homebrew)
brew install shellcheck
# From source via Cabal (any platform)
cabal update && cabal install ShellCheck
# Verify
shellcheck --versionMenjalankan ShellCheck untuk Pertama Kalinya
Pemanggilan paling sederhana adalah shellcheck <script>. ShellCheck membaca baris shebang untuk menentukan dialek shell, lalu mengeluarkan temuan ke stdout.
Setiap temuan mencakup:
- Nomor berkas dan baris—lokasi yang tepat
- Tingkat keparahan—
error,warning,info, ataustyle - Kode SC—pengenal aturan yang stabil dan dapat Anda cari atau nonaktifkan
- Penjelasan untuk manusia—memberi tahu Anda apa yang salah dan sering kali cara memperbaikinya
Jalankan skrip di bawah ini dan amati keluaran yang akan dihasilkan ShellCheck:
#!/usr/bin/env bash
# demo_bad.sh — intentionally flawed for ShellCheck demonstration
FILE=$1
if [ $FILE == '' ]; then
echo "No file given"
fi
cat $FILE | grep 'error' | wc -lMenafsirkan Keluaran ShellCheck dan Kode SC
Untuk skrip pada adegan sebelumnya, ShellCheck akan mengeluarkan temuan seperti berikut:
SC2086(warning)—Gunakan tanda kutip ganda untuk mencegah globbing dan pemisahan kata—pada$FILEdi[ $FILE == '' ]dan dicat $FILE.SC2039/SC3010(info)—== di [ ] adalah bashisme; gunakan = untuk POSIX.SC2002(style)—Cat tidak berguna. Pertimbangkan cmd < file sebagai pengganti cat file | cmd.
Setiap kode SC dipetakan ke halaman wiki di https://www.shellcheck.net/wiki/SCxxxx yang berisi alasan dan contoh yang telah diperbaiki.
Versi skrip yang telah diperbaiki:
#!/usr/bin/env bash
# demo_fixed.sh — ShellCheck-clean
FILE="$1"
if [ -z "$FILE" ]; then
echo "No file given" >&2
exit 1
fi
grep -c 'error' "$FILE"Tingkat Keparahan dan Tindakan yang Harus Dilakukan
ShellCheck mengklasifikasikan setiap temuan berdasarkan tingkat keparahan. Dalam gerbang keamanan, tangani temuan tersebut sebagai berikut:
- error—Hampir pasti merupakan bug atau celah keamanan. Hentikan pembuatan. Perbaiki segera. Contoh:
SC2148tanpa shebang,SC2070$?tanpa tanda kutip. - warning—Pola berisiko tinggi yang sering dapat dieksploitasi. Hentikan pembuatan. Perbaiki atau berikan alasan penonaktifan secara eksplisit. Contoh:
SC2086variabel tanpa tanda kutip. - info—Kemungkinan benar saat ini, tetapi rapuh atau tidak portabel. Perbaiki dalam PR yang sama kecuali dinyatakan di luar cakupan.
- style—Preferensi kosmetik / POSIX. Disarankan, tetapi opsional dalam basis kode Bash murni.
Gunakan --severity=warning agar keluar dengan status bukan nol hanya untuk warning dan tingkat di atasnya—ambang gerbang keamanan standar:
#!/usr/bin/env bash
# gate.sh — fail CI on errors and warnings only
shellcheck --severity=warning scripts/*.sh
echo "ShellCheck exit code: $?"Mengintegrasikan ShellCheck sebagai Gerbang Keamanan CI
Gerbang keamanan hanya berguna jika bersifat wajib dan otomatis. Pola di bawah ini membungkus ShellCheck dalam langkah CI yang:
- Menemukan setiap berkas
.shdi repositori. - Menjalankan ShellCheck dengan
--severity=warningdan keluaran JSON yang dapat dibaca mesin. - Menggagalkan alur (
exit 1) jika ada temuan. - Mencetak ringkasan agar teknisi dapat menindaklanjuti temuan tanpa meninggalkan log CI.
Letakkan berkas ini di repositori Anda dan panggil dari alur CI Anda (GitHub Actions, Jenkins, GitLab CI, dan sebagainya):
#!/usr/bin/env bash
# ci/shellcheck_gate.sh
set -euo pipefail
SCRIPTS=$(find . -name '*.sh' -not -path './.git/*')
FAILED=0
for script in $SCRIPTS; do
echo "==> Checking: $script"
if ! shellcheck --severity=warning --format=tty "$script"; then
FAILED=1
fi
done
if [ "$FAILED" -eq 1 ]; then
echo "[GATE] ShellCheck found warnings or errors. Build blocked." >&2
exit 1
fi
echo "[GATE] All scripts passed ShellCheck."Keluarga SC2086: Perluasan Variabel Tanpa Tanda Kutip
SC2086 adalah temuan ShellCheck yang paling umum dan salah satu kerentanan shell yang paling sering dieksploitasi: perluasan variabel tanpa tanda kutip.
Jika variabel tidak diberi tanda kutip ganda, shell melakukan pemisahan kata (memisahkan berdasarkan IFS) dan perluasan glob pada nilainya. Penyerang yang mengendalikan variabel tersebut dapat menyisipkan argumen tambahan, memicu penelusuran lintas sistem berkas, atau menyebabkan perintah menerima operan yang tidak terduga.
Pola berbahaya yang klasik:
#!/usr/bin/env bash
# Attacker sets: FILENAME="important.txt /etc/passwd"
FILENAME="$1"
# UNSAFE — word splitting turns this into two args
rm $FILENAME
# SAFE — double quotes prevent splitting
rm "$FILENAME"
# Arrays are the right tool for lists
FILES=("$@")
rm -- "${FILES[@]}"Mendeteksi Risiko Injeksi Perintah dengan SC2046 dan SC2035
Dua aturan yang kurang dikenal tetapi penting menangani injeksi perintah melalui keluaran subshell:
SC2046—Berikan tanda kutip pada ini untuk mencegah pemisahan kata / glob di dalam$(…). Jika keluaran subshell digunakan tanpa tanda kutip, spasi atau karakter glob apa pun dalam keluaran tersebut menjadi token shell.SC2035—Gunakan./*.shsebagai pengganti*.shuntuk mencegah nama berkas yang diawali-ditafsirkan sebagai opsi (vektor injeksi argumen klasik).
Skenario eksploitasi dan perbaikan konkret:
#!/usr/bin/env bash
# SC2046 example — output of find fed unquoted to chmod
# If a filename contains spaces, extra arguments appear
# UNSAFE
chmod 600 $(find /secrets -name '*.key')
# SAFE — use a while-read loop or xargs with -0
find /secrets -name '*.key' -print0 \
| xargs -0 chmod 600
# SC2035 example
# UNSAFE — a file named '-rf' would be passed as an option
rm *.sh
# SAFE
rm -- ./*.shMenggunakan Format Keluaran JSON untuk Otomatisasi
ShellCheck mendukung beberapa format keluaran melalui --format:
tty(bawaan)—keluaran terminal yang mudah dibaca manusiajson—dapat dibaca mesin; ideal untuk dasbor, pemblokir khusus, atau pengunggahan ke platform SASTgcc—kompatibel dengan alat yang mengurai format kesalahan GCC (IDE, Vim/Emacs)checkstyle—format XML yang digunakan oleh plugin Checkstyle Jenkins
Format JSON memungkinkan Anda menulis kebijakan otomatis, misalnya memblokir hanya kode SC tertentu atau menggabungkan temuan dari basis kode besar menjadi laporan keamanan.
#!/usr/bin/env bash
# Emit JSON and filter for only error-severity findings using jq
shellcheck --format=json scripts/deploy.sh \
| jq '[.[] | select(.level == "error")]'
# Count distinct SC codes across all scripts
find . -name '*.sh' -print0 \
| xargs -0 shellcheck --format=json 2>/dev/null \
| jq '[.[] | .code] | group_by(.) | map({code: .[0], count: length}) | sort_by(-.count)'Menonaktifkan Positif Palsu dengan Benar
Menonaktifkan ShellCheck secara menyeluruh menggagalkan tujuannya. Pendekatan yang benar adalah penonaktifan terarah dan terdokumentasi yang hanya memengaruhi baris atau blok tepat tempat temuan tersebut memang tidak berlaku.
Tiga mekanisme penonaktifan:
- Penonaktifan sebaris—
# shellcheck disable=SC2086pada baris di atas kode yang bermasalah. Hanya memengaruhi baris tersebut. - Penonaktifan/pengaktifan blok—bungkus suatu bagian dengan
# shellcheck disable=…dan# shellcheck enable=…. - Direktif tingkat berkas—letakkan
# shellcheck disable=…di bagian atas berkas (jarang dapat dibenarkan; dokumentasikan alasannya).
Setiap penonaktifan harus menyertakan komentar yang menjelaskan mengapa temuan tersebut merupakan positif palsu:
#!/usr/bin/env bash
# deploy.sh
# Legitimate suppression: $DEPLOY_ARGS is intentionally word-split
# because it is a pre-validated list of flags from a trusted config file.
# shellcheck disable=SC2086
exec deploy-tool $DEPLOY_ARGS
# Block suppression for a section that generates dynamic code
# shellcheck disable=SC2016
VARS='$HOME $PATH $USER'
echo "Unexpanded vars: $VARS"
# shellcheck enable=SC2016Mengonfigurasi ShellCheck melalui .shellcheckrc
Untuk pengaturan seluruh proyek, ShellCheck membaca .shellcheckrc dari direktori skrip ke atas hingga /. Dengan demikian, Anda tidak perlu mengulangi bendera pada setiap pemanggilan dan skrip gerbang tetap sederhana.
Direktif yang berguna dalam .shellcheckrc:
shell=bash—menimpa deteksi dialek (berguna untuk berkas tanpa shebang)enable=all—mengaktifkan pemeriksaan opsional (misalnya,avoid-nullary-conditions,require-variable-braces)disable=SC2059—penonaktifan seluruh proyek untuk pengecualian yang memiliki alasanexternal-sources=true—mengikuti dan memeriksa direktifsource/.
# .shellcheckrc — project root
shell=bash
enable=all
external-sources=true
# SC2312: consider invoking this command separately to avoid masking its
# return value — suppressed project-wide because we use set -e.
# Rationale: errexit already aborts on failure; masking risk is mitigated.
disable=SC2312Skrip Diperkuat Menyeluruh: Sebelum dan Sesudah
Cara paling efektif untuk memahami temuan ShellCheck adalah memfaktorkan ulang skrip realistis dari kondisi gagal menjadi skrip yang bersih dan diperkuat. Skrip di bawah ini mencadangkan sebuah direktori dan ditulis tanpa mempertimbangkan keamanan. Skrip tersebut gagal dalam setidaknya lima aturan berbeda di ShellCheck.
Pelajari kedua versinya. Versi sesudah lolos dari shellcheck --severity=warning tanpa direktif penonaktifan dan jauh lebih aman saat menerima input yang dikendalikan penyerang:
#!/usr/bin/env bash
# BEFORE — multiple ShellCheck violations
DEST=$1
SRC=$2
DATE=`date +%Y%m%d`
if [ ! -d $DEST ]; then
mkdir $DEST
fi
cp -r $SRC $DEST/$DATE
echo Done
#!/usr/bin/env bash
# AFTER — ShellCheck-clean and hardened
set -euo pipefail
DEST="${1:?Usage: backup.sh <dest> <src>}"
SRC="${2:?Usage: backup.sh <dest> <src>}"
DATE=$(date +%Y%m%d)
if [ ! -d "$DEST" ]; then
mkdir -p -- "$DEST"
fi
cp -r -- "$SRC" "$DEST/$DATE"
echo 'Done' >&2Uji Pengetahuan: ShellCheck dalam Gerbang Keamanan
Uji pemahaman Anda tentang peran ShellCheck sebagai gerbang keamanan.
Rangkuman: Analisis Statis sebagai Gerbang Keamanan
Dalam pelajaran ini, Anda mempelajari cara menjadikan ShellCheck sebagai gerbang keamanan wajib dalam alur kerja Bash Anda:
- ShellCheck melakukan analisis statis tanpa menjalankan skrip Anda, sehingga dapat menangkap kesalahan penggunaan tanda kutip, risiko injeksi, dan pola tidak aman sebelum waktu eksekusi.
- Setiap temuan memiliki kode SC (misalnya,
SC2086) yang terhubung ke dokumentasi terperinci dan panduan perbaikan. - Jenjang tingkat keparahan—
error,warning,info,style—memungkinkan Anda menyesuaikan gerbang:--severity=warningadalah ambang keamanan yang disarankan. - Gunakan keluaran yang dapat dibaca mesin (
--format=json) untuk mengotomatisasi pelaporan, pelacakan tren, dan integrasi SAST. - Lakukan penonaktifan seperlunya: selalu targetkan satu baris, selalu dokumentasikan alasannya dalam komentar, dan jangan pernah menonaktifkan secara global kecuali dibenarkan oleh
.shellcheckrc. - Padukan ShellCheck dengan
set -euo pipefail, penggunaan tanda kutip secara eksplisit, terminator-- argument, dan validasi input sebagai pertahanan berlapis.
Skrip yang lolos ShellCheck tidak otomatis aman—tetapi skrip yang gagal dalam ShellCheck tidak boleh mencapai produksi.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Analisis Statis dan Audit dengan ShellCheck” gratis?
Ya — teks lengkap “Analisis Statis dan Audit dengan ShellCheck” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Linux Command Line & Bash Scripting Mastery, upgrade ke CoddyKit PRO. Kursus Linux Command Line & Bash Scripting Mastery mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Analisis Statis dan Audit dengan ShellCheck”?
Integrasikan ShellCheck ke dalam gerbang keamanan dan tafsirkan temuannya untuk memperkuat setiap skrip. Kamu berlatih Linux Command Line & Bash Scripting Mastery dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Linux Command Line & Bash Scripting Mastery?
Tidak diperlukan pengalaman sebelumnya. Linux Command Line & Bash Scripting Mastery di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Analisis Statis dan Audit dengan ShellCheck” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Linux Command Line & Bash Scripting Mastery ini?
Ya. Setiap pelajaran Linux Command Line & Bash Scripting Mastery menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Mencegah Injeksi Perintah dan Argumen
- Penanganan Rahasia yang Aman dan Kebersihan Environment
- Eksekusi dengan Hak Minimum dan Disiplin sudo
- Analisis Statis dan Audit dengan ShellCheck