Linux-komentorivin ja Bash-komentosarjojen hallinta · Oppitunti

Staattinen analyysi ja tarkastus ShellCheckilla

Integroi ShellCheck tietoturvaportiksi ja tulkitse sen havainnot jokaisen skriptin vahvistamiseksi.

Oppitunti 4/413 vaihetta

Staattinen analyysi ja tarkastus ShellCheckilla on ilmainen Linux-komentorivin ja Bash-komentosarjojen hallinta-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Linux-komentorivin ja Bash-komentosarjojen hallinta-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Linux-komentorivin ja Bash-komentosarjojen hallinta-kurssilla on yhteensä 4 oppituntia.

Mikä ShellCheck on ja miksi sillä on merkitystä

ShellCheck on shell-komentosarjojen avoimen lähdekoodin staattisen analyysin työkalu. Se jäsentää Bash- (sekä POSIX sh-, dash- ja ksh-) lähdekoodin suorittamatta sitä ja raportoi virheistä, vaarallisista rakenteista, siirrettävyysongelmista ja tyyliin liittyvistä ongelmista — jokaiselle havainnolle annetaan yksilöllinen sääntökoodi, kuten SC2086.

Turvallisuutta vahvistavassa putkessa ShellCheck toimii pakollisena tarkistuspisteenä: yhtäkään komentosarjaa ei julkaista ennen kuin se läpäisee tarkistuksen. Tämä on tärkeää, koska:

  • Monet shell-haavoittuvuudet (sanojen jakaminen, injektiot ja lainaamattomat laajennukset) eivät näy onnistuneen suorituksen testeissä, mutta laukeavat hyökkääjän hallitsemalla syötteellä.
  • ShellCheck havaitsee nämä virheluokat ennen suoritusta, ilman lisäkustannuksia.
  • Se dokumentoi, miksi kukin rakenne on vaarallinen, ja lisää siten tiimin tietoisuutta ajan mittaan.

Asentakaa se mihin tahansa järjestelmään:

# 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 --version

ShellCheckin suorittaminen ensimmäistä kertaa

Yksinkertaisin kutsu on shellcheck <script>. ShellCheck lukee shebang-rivin määrittääkseen käytettävän shell-murteiden ja tulostaa sitten havainnot vakiotulosteeseen.

Jokainen havainto sisältää:

  • Tiedoston ja rivin numeron — tarkan sijainnin
  • Vakavuuden — error, warning, info tai style
  • SC-koodin — pysyvän sääntötunnisteen, jonka voi etsiä dokumentaatiosta tai jonka voi vaimentaa
  • Selkokielisen selityksen — kertoo, mikä on vialla ja usein myös, miten se korjataan

Suorittakaa alla oleva komentosarja ja tarkastelkaa tulostetta, jonka ShellCheck tuottaisi:

#!/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 -l

ShellCheckin tulosteen ja SC-koodien tulkitseminen

Edellisen näkymän komentosarjasta ShellCheck tuottaisi esimerkiksi seuraavia havaintoja:

  • SC2086 (warning) — Käyttäkää lainausmerkkejä estääksenne jokerimerkkien käsittelyn ja sanojen jakamisen — kohdassa $FILE lausekkeessa [ $FILE == '' ] sekä komennossa cat $FILE.
  • SC2039 / SC3010 (info) — == kohdassa [ ] on bashism; käyttäkää POSIX-yhteensopivaa =-merkkiä.
  • SC2002 (style) — Tarpeeton cat. Harkitkaa muotoa cmd < file komennon cat file | cmd sijaan.

Jokaista SC-koodia vastaavalla sivulla osoitteessa https://www.shellcheck.net/wiki/SCxxxx on perustelut ja korjattu esimerkki.

Kyseisen komentosarjan korjattu versio:

#!/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"

Vakavuustasot ja toimia edellyttävät havainnot

ShellCheck luokittelee jokaisen havainnon vakavuuden mukaan. Turvallisuustarkistuksessa niitä kannattaa käsitellä seuraavasti:

  • error — lähes varmasti virhe tai tietoturva-aukko. Estäkää koonti. Korjatkaa välittömästi. Esimerkkejä: puuttuva shebang SC2148 ja lainaamaton $? SC2070.
  • warning — suuren riskin rakenne, jota voidaan usein hyödyntää. Estäkää koonti. Korjatkaa havainto tai perustelkaa vaimennus erikseen. Esimerkki: lainaamaton muuttuja SC2086.
  • info — todennäköisesti tällä hetkellä oikein, mutta hauras tai ei-siirrettävä. Korjatkaa samassa PR:ssä, ellei asiaa ole rajattu työn ulkopuolelle.
  • style — ulkoasuun tai POSIX-tyyliin liittyvä suositus. Suositeltava, mutta valinnaista puhtaassa Bash-koodikannassa.

Käyttäkää asetusta --severity=warning, jotta komento palauttaa nollasta poikkeavan poistumiskoodin vain varoituksista ja vakavammista havainnoista — tämä on vakiintunut turvallisuustarkistuksen kynnys:

#!/usr/bin/env bash
# gate.sh — fail CI on errors and warnings only
shellcheck --severity=warning scripts/*.sh
echo "ShellCheck exit code: $?"

ShellCheckin integroiminen CI-turvallisuustarkistukseen

Turvallisuustarkistus on hyödyllinen vain, kun se on pakollinen ja automaattinen. Alla oleva malli käärii ShellCheckin CI-vaiheeseen, joka:

  • etsii repositoriosta kaikki .sh-tiedostot
  • suorittaa ShellCheckin asetuksilla --severity=warning ja koneellisesti luettavalla JSON-tulosteella
  • keskeyttää putken (exit 1), jos yksikin havainto löytyy
  • tulostaa yhteenvedon, jotta kehittäjät voivat käsitellä havainnot poistumatta CI-lokista

Lisätkää tämä tiedosto repositorioonne ja kutsukaa sitä CI-putkesta (GitHub Actions, Jenkins, GitLab CI jne.):

#!/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."

SC2086-perhe: lainaamattomat muuttujalaajennukset

SC2086 on yleisin ShellCheck-havainto ja yksi hyödynnetyimmistä shell-haavoittuvuuksista: lainaamattomat muuttujalaajennukset.

Kun muuttujaa ei ympäröidä kaksoislainausmerkeillä, shell suorittaa sen arvolle sanojen jakamisen (jakaa arvon IFS-muuttujan perusteella) ja jokerimerkkien laajennuksen. Muuttujaa hallitseva hyökkääjä voi syöttää ylimääräisiä argumentteja, käynnistää tiedostojärjestelmän läpikäynnin tai saada komennot vastaanottamaan odottamattomia operandeja.

Klassinen vaarallinen rakenne:

#!/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[@]}"

Komennon injektioriskin havaitseminen koodeilla SC2046 ja SC2035

Kaksi vähemmän tunnettua mutta tärkeää sääntöä käsittelee komennon injektiota alikuoren tulosteen kautta:

  • SC2046 — Ympäröikää tämä lainausmerkeillä estääksenne sanojen jakamisen ja jokerimerkkien käsittelyn kohdassa $(…). Jos alikuoren tulostetta käytetään ilman lainausmerkkejä, tulosteen välilyönneistä tai jokerimerkeistä tulee shellin tunnuksia.
  • SC2035 — Käyttäkää muotoa ./*.sh muodon *.sh sijaan, jotta merkillä - alkavia tiedostonimiä ei tulkita valitsimiksi (klassinen argumenttien injektiovektori).

Konkreettinen hyväksikäyttötilanne ja korjaus:

#!/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 -- ./*.sh

JSON-tulostemuodon käyttäminen automaatiossa

ShellCheck tukee useita tulostemuotoja asetuksella --format:

  • tty (oletus) — ihmiselle luettava päätetuloste
  • json — koneellisesti luettava; ihanteellinen koontinäytöille, mukautetuille estäjille tai SAST-alustoille lataamista varten
  • gcc — yhteensopiva GCC-virhemuotoa jäsentävien työkalujen (IDE:t, Vim/Emacs) kanssa
  • checkstyle — Jenkinsin Checkstyle-lisäosan käyttämä XML-muoto

JSON-muodon avulla voitte laatia automaattisia käytäntöjä, esimerkiksi estää suorituksen vain tiettyjen SC-koodien perusteella tai koostaa suuren koodikannan havainnot tietoturvaraportiksi.

#!/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)'

Väärien positiivisten havaintojen oikea vaimentaminen

ShellCheckin yleinen käytöstä poistaminen vesittää sen tarkoituksen. Oikea lähestymistapa on kohdennettu ja dokumentoitu vaimennus, joka vaikuttaa vain tarkkaan riviin tai lohkoon, jossa havainto ei aidosti päde.

Kolme vaimennusmekanismia:

  • Rivin sisäinen käytöstäpoisto — # shellcheck disable=SC2086 kyseistä koodia edeltävällä rivillä. Vaikuttaa vain kyseiseen riviin.
  • Lohkon käytöstäpoisto ja käyttöönotto — ympäröikää osio komennoilla # shellcheck disable=… ja # shellcheck enable=….
  • Tiedostotason direktiivi — sijoittakaa # shellcheck disable=… tiedoston alkuun (harvoin perusteltua; dokumentoikaa syy).

Jokaiseen vaimennukseen on sisällyttävä kommentti, joka selittää, miksi kyseessä on väärä positiivinen havainto:

#!/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=SC2016

ShellCheckin määrittäminen .shellcheckrc-tiedoston avulla

Projektinlaajuisia asetuksia varten ShellCheck lukee .shellcheckrc-tiedoston komentosarjan hakemistosta ylöspäin hakemistoon / asti. Näin samoja valitsimia ei tarvitse toistaa jokaisessa kutsussa ja tarkistusskriptit pysyvät yksinkertaisina.

Hyödyllisiä direktiivejä tiedostossa .shellcheckrc:

  • shell=bash — ohittaa murteen tunnistuksen (hyödyllinen tiedostoille, joista shebang puuttuu)
  • enable=all — ottaa valinnaiset tarkistukset käyttöön (esim. avoid-nullary-conditions, require-variable-braces)
  • disable=SC2059 — projektinlaajuinen vaimennus perustellulle poikkeukselle
  • external-sources=true — seuraa ja tarkistaa source- ja .-direktiivit
# .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=SC2312

Vahvistettu komentosarja alusta loppuun: ennen ja jälkeen

Tehokkain tapa sisäistää ShellCheckin havainnot on muokata realistinen komentosarja virheellisestä tilasta puhtaaksi ja vahvistetuksi versioksi. Alla oleva komentosarja varmuuskopioi hakemiston, eikä sitä ole kirjoitettu turvallisuusnäkökohdat huomioiden. Se rikkoo vähintään viittä erillistä ShellCheck-sääntöä.

Tutkikaa molemmat versiot. Jälkimmäinen versio läpäisee komennon shellcheck --severity=warning ilman vaimennusdirektiivejä ja on huomattavasti turvallisempi hyökkääjän hallitsemalla syötteellä:

#!/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' >&2

Tietotesti: ShellCheck turvallisuustarkistuksessa

Testatkaa ymmärrystänne ShellCheckin roolista turvallisuustarkistuksena.

Kertaus: staattinen analyysi turvallisuustarkistuksena

Tässä oppitunnissa opitte tekemään ShellCheckistä pakollisen turvallisuustarkistuksen Bash-työnkulussanne:

  • ShellCheck suorittaa staattisen analyysin suorittamatta komentosarjoja ja havaitsee lainausvirheet, injektioriskit ja vaaralliset rakenteet ennen suoritusta.
  • Jokaisella havainnolla on SC-koodi (esimerkiksi SC2086), joka linkittyy yksityiskohtaiseen dokumentaatioon ja korjausohjeisiin.
  • Vakavuusasteikko — error, warning, info, style — mahdollistaa tarkistuksen säätämisen: --severity=warning on suositeltu turvallisuuskynnys.
  • Käyttäkää koneellisesti luettavaa tulostetta (--format=json) raportoinnin, trendien seurannan ja SAST-integraation automatisointiin.
  • Vaimennuksia tulee käyttää säästeliäästi: kohdistakaa ne aina yhteen riviin, dokumentoikaa syy aina kommentissa ja älkää koskaan vaimentako tarkistuksia yleisesti, ellei sitä perustella .shellcheckrc-tiedostolla.
  • Yhdistäkää ShellCheck asetuksiin set -euo pipefail, eksplisiittisiin lainausmerkkeihin, -- argument -lopetusmerkkeihin ja syötteen tarkistukseen syvällisen puolustuksen toteuttamiseksi.

ShellCheckin läpäisevä komentosarja ei ole automaattisesti turvallinen — mutta ShellCheckin hylkäämän komentosarjan ei pitäisi koskaan päätyä tuotantoon.

Aloita maksutta

Opi Bash tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
22
Oppitunnit
88

Usein kysytyt kysymykset

Onko oppitunti ”Staattinen analyysi ja tarkastus ShellCheckilla” ilmainen?

Kyllä – oppitunnin ”Staattinen analyysi ja tarkastus ShellCheckilla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Linux-komentorivin ja Bash-komentosarjojen hallinta-kurssin, päivitä CoddyKit PROhon. Linux-komentorivin ja Bash-komentosarjojen hallinta-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Staattinen analyysi ja tarkastus ShellCheckilla”?

Integroi ShellCheck tietoturvaportiksi ja tulkitse sen havainnot jokaisen skriptin vahvistamiseksi. Harjoittelet Linux-komentorivin ja Bash-komentosarjojen hallinta-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Linux-komentorivin ja Bash-komentosarjojen hallinta-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Linux-komentorivin ja Bash-komentosarjojen hallinta-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Staattinen analyysi ja tarkastus ShellCheckilla”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Linux-komentorivin ja Bash-komentosarjojen hallinta-oppitunnilla?

Kyllä. Jokainen Linux-komentorivin ja Bash-komentosarjojen hallinta-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Komento- ja argumentti-injektioiden estäminen
  2. Salaisten tietojen turvallinen käsittely ja ympäristön siisteys
  3. Vähimpien oikeuksien suoritus ja sudo-kuri
  4. Staattinen analyysi ja tarkastus ShellCheckilla
← Takaisin: Linux-komentorivin ja Bash-komentosarjojen hallinta