Bezpieczny kod źródłowy

1. Omówienie

Techniki bezpiecznego kodu źródłowego to zestaw metod, które można stosować w celu zwiększenia bezpieczeństwa kodu źródłowego. Te techniki mogą pomóc w identyfikowaniu i naprawianiu luk w zabezpieczeniach w kodzie źródłowym, zapobieganiu nieautoryzowanemu dostępowi do tego kodu oraz ochronie go przed modyfikacjami.

Oto kilka typowych technik bezpiecznego kodowania źródłowego:

  • Linting: linting to proces sprawdzania kodu źródłowego pod kątem błędów i problemów ze stylistyką. Jest to możliwe dzięki narzędziu lint, które analizuje kod źródłowy i identyfikuje potencjalne problemy. Narzędzia lint służą do sprawdzania różnych błędów, w tym błędów składni, błędów semantycznych, błędów stylu i luk w zabezpieczeniach.
  • Testowanie bezpieczeństwa aplikacji statycznych (SAST): SAST to rodzaj testowania bezpieczeństwa, który analizuje kod źródłowy, kod binarny lub kod bajtowy w celu wykrycia luk w zabezpieczeniach. Narzędzi SAST można używać do znajdowania luk w zabezpieczeniach w różnych językach programowania, takich jak Go, Java, Python, C++ i C#.
  • Skanowanie licencji: skanowanie licencji to proces identyfikowania licencji komponentów oprogramowania innych firm używanych w aplikacji. Jest to ważne, ponieważ pomaga zapewnić zgodność aplikacji z warunkami licencji, co może pomóc w uniknięciu problemów prawnych.

Można ich używać do zwiększania bezpieczeństwa kodu źródłowego na wszystkich etapach cyklu życia oprogramowania. Linting pozwala wykrywać błędy we wczesnej fazie procesu tworzenia, SAST pozwala znajdować luki w zabezpieczeniach przed skompilowaniem lub wdrożeniem kodu, a skanowanie licencji pozwala sprawdzić, czy aplikacja jest zgodna z warunkami licencji.

Stosowanie tych technik może pomóc w zwiększeniu bezpieczeństwa kodu źródłowego i zmniejszeniu ryzyka naruszenia zabezpieczeń.

Czego się nauczysz

W tym laboratorium skupimy się na narzędziach i metodach zabezpieczania kodu źródłowego oprogramowania.

  • Lintowanie
  • Statyczne testowanie bezpieczeństwa aplikacji
  • Skanowanie licencji

Wszystkie narzędzia i polecenia używane w tym laboratorium będą wykonywane w Cloud Shell.

2. Konfiguracja i wymagania

Konfigurowanie środowiska we własnym tempie

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, którego nie używają interfejsy API Google. Możesz ją zaktualizować w dowolnym momencie.
  • Identyfikator projektu jest niepowtarzalny w ramach wszystkich projektów Google Cloud i nie można go zmienić (po ustawieniu). Cloud Console automatycznie generuje unikalny ciąg znaków. Zwykle nie ma znaczenia, jaki to ciąg. W większości laboratoriów z kodem musisz odwoływać się do identyfikatora projektu (zazwyczaj jest to PROJECT_ID). Jeśli nie podoba Ci się wygenerowany identyfikator, możesz wygenerować inny losowy. Możesz też spróbować użyć własnego adresu e-mail i sprawdzić, czy jest on dostępny. Po tym kroku nie można go zmienić. Pozostanie ona niezmieniona przez cały czas trwania projektu.
  • Informacyjnie: istnieje jeszcze 3 wartość, numer projektu, którego używają niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć rozliczenia w konsoli Cloud, aby korzystać z zasobów i interfejsów API Cloud. Przejście przez ten moduł Codelab nie powinno wiązać się z wielkimi kosztami, jeśli w ogóle z nimi będzie. Aby wyłączyć zasoby, aby nie generować opłat po zakończeniu samouczka, możesz usunąć utworzone zasoby lub cały projekt. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.

Uruchamianie edytora Cloud Shell

Ten moduł praktyczny został zaprojektowany i przetestowany pod kątem korzystania z edytora Google Cloud Shell. Aby uzyskać dostęp do edytora:

  1. Otwórz swój projekt Google na stronie https://console.cloud.google.com.
  2. W prawym górnym rogu kliknij ikonę edytora powłoki chmury.

8560cc8d45e8c112.png

  1. Nowy panel otworzy się u dołu okna.
  2. Kliknij przycisk Otwórz edytor.

9e504cb98a6a8005.png

  1. Otworzy się edytor z eksploratorem po prawej stronie i edytorem w centralnej części.
  2. U dołu ekranu powinna być też dostępna karta terminala.
  3. Jeśli terminal NIE jest otwarty, użyj kombinacji klawiszy `ctrl+``, aby otworzyć nowe okno terminala.

Konfiguracja środowiska

Aby uprościć polecenia używane w tym module, ustaw GOPATH na jeden katalog.

export GOPATH=$HOME/gopath

Utwórz katalog na potrzeby swojej pracy.

mkdir -p workspace
cd workspace

Klonowanie repozytorium kodu źródłowego

git clone https://gitlab.com/gcp-solutions-public/shift-left-security-workshop/source-code-lab.git
cd source-code-lab
export WORKDIR=$(pwd)

3. Lintowanie

Linting służy do sprawdzania typowych błędów związanych ze stylem lub błędów składniowych. Linting pomaga zwiększać bezpieczeństwo, ponieważ zapewnia wspólny wzór składni dla wielu zespołów, co prowadzi do szybszego przeglądania kodu, dzielenia się wiedzą i czytelności kodu.

Linting wykrywa też typowe błędy składni, które mogą prowadzić do częstych luk w zabezpieczeniach, takich jak nieprawidłowe lub mniej wydajne korzystanie z bibliotek czy podstawowych interfejsów API.

Instalowanie narzędzia do łączenia staticcheck

 go get honnef.co/go/tools/cmd/staticcheck@latest

Uruchom Go Linter (staticcheck) w katalogu głównym projektu.

 staticcheck

Sprawdzanie danych wyjściowych

main.go:42:29: unnecessary use of fmt.Sprintf (S1039)

Ten błąd występuje, ponieważ funkcja http.ListenAndServe() przyjmuje ciąg znaków, a obecny kod używa funkcji Sprintf bez przekazywania zmiennych do ciągu znaków.

Sprawdź stan zakończenia działania polecenia.

echo $?

W tym przypadku, ponieważ polecenie spowodowało błąd, stan wyjściowy będzie 1 lub większy. Jest to jedna z metod, które można stosować w potoku CI/CD do określania powodzenia lub niepowodzenia narzędzia.

Zmień plik main.go i napraw kod:

  • Zmień w komentarzu wiersz pod wierszem LINTING - Step 1 w metodie main(), dodając ukośniki(//).
  • Usuń znaczniki komentarza z 2 wierszy bezpośrednio pod metodą LINTING - Step 2, usuwając ukośniki na początku.main()

Ponownie uruchom staticcheck w katalogu głównym projektu.

staticcheck

Polecenie nie powinno zwracać żadnych wyników (czyli pustej linii).

Sprawdź stan zakończenia działania polecenia.

  echo $?

W tym przypadku, ponieważ polecenie nie spowodowało błędu, stan wyjściowy będzie zero.

4. Statyczne testowanie bezpieczeństwa aplikacji

AST/statyczne testy bezpieczeństwa – zapewnia analizę statycznych kodów pod kątem typowych luk i luk w zabezpieczeniach ( CWEs).

Zainstaluj narzędzie AST (gosec)

    export GOSEC_VERSION="2.15.0"
    curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | \
          sh -s -- -b $(go env GOPATH)/bin v${GOSEC_VERSION}

Uruchom gosec z plikiem zasad na kodzie źródłowym

gosec -conf policies/gosec-policy.json -fmt=json ./...

Dane wyjściowe powinny wyglądać tak:

{
    "Golang errors": {},
    "Issues": [
        {
            "severity": "HIGH",
            "confidence": "LOW",
            "cwe": {
                "ID": "798",
                "URL": "https://cwe.mitre.org/data/definitions/798.html"
            },
            "rule_id": "G101",
            "details": "Potential hardcoded credentials",
            "file": "/home/random-user-here/shift-left-security-workshop/labs/source-code-lab/main.go",
            "code": "31: \t// STEP 2: Change this and the reference below to something different (ie, not \"pawsword\" or \"password\")\n32: \tvar pawsword = \"im-a-cute-puppy\"\n33: \tfmt.Println(\"Something a puppy would use: \", username, pawsword)\n",
            "line": "32",
            "column": "6"
        }
    ],
    "Stats": {
        "files": 1,
        "lines": 89,
        "nosec": 0,
        "found": 1
    }
}

Narzędzie wykryło potencjalny problem: Potential hardcoded credentials

5. Skanowanie licencji

Licencje są ważne dla bezpieczeństwa, ponieważ mogą wymagać udostępnienia kodu źródłowego, którego nie chcesz udostępniać. Koncepcja ta nosi nazwę licencji copyleft, które wymagają udostępnienia kodu źródłowego, jeśli używasz zależności z tymi licencjami.

Zainstaluj aplikację golicense

mkdir -p /tmp/golicense
wget -O /tmp/golicense/golicense.tar.gz https://github.com/mitchellh/golicense/releases/download/v0.2.0/golicense_0.2.0_linux_x86_64.tar.gz
pushd /tmp/golicense
tar -xzf golicense.tar.gz
chmod +x golicense
mv golicense $(go env GOPATH)/bin/golicense
popd

Kompilowanie pliku binarnego

go build

Przeprowadź sprawdzanie licencji za pomocą bieżącego pliku zasad, który nie zezwala na licencje „BSD-3-Clause”

golicense policies/license-policy.hcl hello-world

UWAGA: ta operacja powinna zakończyć się niepowodzeniem z podobnymi wynikami:

 🚫 rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
 🚫 rsc.io/quote      BSD 3-Clause "New" or "Revised" License
 🚫 golang.org/x/text BSD 3-Clause "New" or "Revised" License

Zmodyfikuj plik zasad policies/license-policy.hcl, aby przenieść zasadę „BSD-3-Clause” z listy deny na listę allow.

Ponownie uruchom kontrolę licencji

golicense policies/license-policy.hcl hello-world

UWAGA: powinno to się udać, a dane wyjściowe powinny być podobne do tych:

    ✅ rsc.io/quote      BSD 3-Clause "New" or "Revised" License
    ✅ rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
    ✅ golang.org/x/text BSD 3-Clause "New" or "Revised" License

6. Gratulacje

Gratulacje! Masz ukończone zajęcia.

Czego się nauczysz

  • Narzędzia i techniki zabezpieczające kod źródłowy

Ostatnia aktualizacja: 23.03.23