ซอร์สโค้ดที่ปลอดภัย

1. ภาพรวม

เทคนิคการรักษาความปลอดภัยของซอร์สโค้ดคือชุดแนวทางปฏิบัติที่สามารถใช้เพื่อปรับปรุงความปลอดภัยของซอร์สโค้ด เทคนิคเหล่านี้ช่วยระบุและแก้ไขช่องโหว่ในซอร์สโค้ด ป้องกันไม่ให้มีสิทธิ์เข้าถึงซอร์สโค้ดโดยไม่ได้รับอนุญาต และปกป้องซอร์สโค้ดจากการแก้ไข

เทคนิคทั่วไปที่พบบ่อยเกี่ยวกับซอร์สโค้ดที่ปลอดภัยมีดังนี้

  • การตรวจสอบโค้ด: การตรวจสอบโค้ดเป็นกระบวนการตรวจสอบซอร์สโค้ดเพื่อหาข้อผิดพลาดและปัญหาด้านรูปแบบ ซึ่งทำได้โดยใช้เครื่องมือ Lint ซึ่งเป็นโปรแกรมที่วิเคราะห์ซอร์สโค้ดและระบุปัญหาที่อาจเกิดขึ้น เครื่องมือ Lint ใช้เพื่อตรวจหาข้อผิดพลาดที่หลากหลายได้ ซึ่งรวมถึงข้อผิดพลาดทางไวยากรณ์ ข้อผิดพลาดด้านความหมาย ข้อผิดพลาดด้านรูปแบบ และช่องโหว่ด้านความปลอดภัย
  • การทดสอบความปลอดภัยของแอปพลิเคชันแบบคงที่ (SAST): SAST เป็นการทดสอบความปลอดภัยประเภทหนึ่งที่วิเคราะห์ซอร์สโค้ด โค้ดไบนารี หรือไบต์โค้ดเพื่อระบุช่องโหว่ด้านความปลอดภัย เครื่องมือ SAST ใช้ค้นหาช่องโหว่ในภาษาการเขียนโปรแกรมได้หลายภาษา เช่น Go, Java, Python, C++ และ C#
  • การสแกนใบอนุญาต: การสแกนใบอนุญาตคือกระบวนการระบุใบอนุญาตของคอมโพเนนต์ซอฟต์แวร์ของบุคคลที่สามที่ใช้ในแอปพลิเคชันซอฟต์แวร์ ซึ่งสำคัญเนื่องจากช่วยให้มั่นใจว่าแอปพลิเคชันเป็นไปตามข้อกำหนดของใบอนุญาต ซึ่งจะช่วยหลีกเลี่ยงปัญหาทางกฎหมายได้

เทคนิคเหล่านี้สามารถใช้เพื่อปรับปรุงความปลอดภัยของซอร์สโค้ดในทุกระยะของวงจรการพัฒนาซอฟต์แวร์ สามารถใช้การตรวจสอบโค้ดเพื่อระบุข้อผิดพลาดตั้งแต่เนิ่นๆ ในกระบวนการพัฒนาได้ ใช้ SAST เพื่อค้นหาช่องโหว่ก่อนที่โค้ดจะคอมไพล์หรือนำไปใช้งาน และสามารถใช้การสแกนใบอนุญาตเพื่อให้แน่ใจว่าแอปพลิเคชันเป็นไปตามข้อกำหนดของใบอนุญาต

การใช้เทคนิคเหล่านี้จะช่วยปรับปรุงความปลอดภัยของซอร์สโค้ดและลดความเสี่ยงของการละเมิดความปลอดภัย

สิ่งที่คุณจะได้เรียนรู้

ห้องทดลองนี้จะมุ่งเน้นที่เครื่องมือและเทคนิคในการรักษาความปลอดภัยให้กับซอร์สโค้ดของซอฟต์แวร์

  • การตรวจหาข้อบกพร่อง
  • การทดสอบความปลอดภัยของแอปพลิเคชันแบบคงที่
  • การสแกนใบอนุญาต

เครื่องมือและคำสั่งทั้งหมดที่ใช้ในแล็บนี้จะดำเนินการใน Cloud Shell

2. การตั้งค่าและข้อกําหนด

การตั้งค่าสภาพแวดล้อมด้วยตนเอง

  1. ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ โดยคุณจะอัปเดตได้ทุกเมื่อ
  • รหัสโปรเจ็กต์จะต้องไม่ซ้ำกันสำหรับโปรเจ็กต์ Google Cloud ทั้งหมดและจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) คอนโซล Cloud จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นจะเป็นอะไร ในโค้ดแล็บส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น PROJECT_ID) หากไม่ชอบรหัสที่สร้างขึ้น คุณก็สร้างรหัสอื่นแบบสุ่มได้ หรือจะลองใช้อุปกรณ์ของคุณเองเพื่อดูว่าฟีเจอร์นี้พร้อมใช้งานหรือไม่ก็ได้ คุณจะเปลี่ยนแปลงชื่อหลังจากขั้นตอนนี้ไม่ได้ และชื่อจะยังคงอยู่ตลอดระยะเวลาของโปรเจ็กต์
  • โปรดทราบว่ามีค่าที่ 3 ซึ่งเป็นหมายเลขโปรเจ็กต์ที่ API บางรายการใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 รายการนี้ได้ในเอกสารประกอบ
  1. ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การทำตามโค้ดแล็บนี้ไม่น่าจะเสียค่าใช้จ่ายมากนัก หากต้องการปิดใช้ทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินหลังจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่สร้างไว้หรือลบทั้งโปรเจ็กต์ได้ ผู้ใช้ใหม่ของ Google Cloud มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD

เริ่มเครื่องมือแก้ไข Cloud Shell

ห้องทดลองนี้ได้รับการออกแบบและทดสอบเพื่อใช้กับเครื่องมือแก้ไข Google Cloud Shell วิธีเข้าถึงเครื่องมือแก้ไข

  1. เข้าถึงโปรเจ็กต์ Google ได้ที่ https://console.cloud.google.com
  2. คลิกไอคอนเครื่องมือแก้ไข Cloud Shell ที่มุมขวาบน

8560cc8d45e8c112.png

  1. แผงใหม่จะเปิดขึ้นที่ด้านล่างของหน้าต่าง
  2. คลิกปุ่มเปิดเครื่องมือแก้ไข

9e504cb98a6a8005.png

  1. เครื่องมือแก้ไขจะเปิดขึ้นโดยจะมีโปรแกรมสำรวจทางด้านขวาและเครื่องมือแก้ไขอยู่ตรงกลาง
  2. แผงเทอร์มินัลควรปรากฏที่ด้านล่างของหน้าจอด้วย
  3. หากเทอร์มินัลไม่เปิดอยู่ ให้ใช้แป้นพิมพ์ลัด `ctrl+`` เพื่อเปิดหน้าต่างเทอร์มินัลใหม่

การตั้งค่าสภาพแวดล้อม

ตั้งค่า GOPATH เป็นไดเรกทอรีเดียวเพื่อให้ใช้คำสั่งในแล็บนี้ได้ง่ายขึ้น

export GOPATH=$HOME/gopath

สร้างไดเรกทอรีสำหรับเก็บงาน

mkdir -p workspace
cd workspace

โคลนที่เก็บซอร์สโค้ด

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

3. การตรวจหาข้อบกพร่อง

การตรวจไวยากรณ์ (Linting) ใช้เพื่อตรวจหาข้อผิดพลาดหรือข้อบกพร่องทั่วไปเกี่ยวกับรูปแบบที่เกี่ยวข้องกับไวยากรณ์ การตรวจไวยากรณ์ช่วยรักษาความปลอดภัยด้วยการกำหนดรูปแบบไวยากรณ์ทั่วไปสำหรับหลายทีม ซึ่งทำให้การตรวจสอบโค้ด การแชร์ความรู้ และโค้ดที่ชัดเจนเร็วขึ้น

นอกจากนี้ เครื่องมือตรวจสอบไวยากรณ์จะระบุข้อผิดพลาดทางไวยากรณ์ที่พบบ่อยซึ่งอาจนำไปสู่ช่องโหว่ที่พบบ่อย เช่น การใช้ไลบรารีหรือ API หลักอย่างไม่เหมาะสมหรือมีประสิทธิภาพต่ำ

ติดตั้งเครื่องมือลิงก์ staticcheck

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

เรียกใช้ Go Linter (staticcheck) ในไดเรกทอรีรูทของโปรเจ็กต์

 staticcheck

ตรวจสอบเอาต์พุต

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

คุณได้รับข้อผิดพลาดเนื่องจาก http.ListenAndServe() ยอมรับสตริง และโค้ดปัจจุบันใช้ Sprintf โดยไม่ส่งตัวแปรไปยังสตริง

ตรวจสอบสถานะการออกของคําสั่ง

echo $?

ในกรณีนี้ เนื่องจากคําสั่งทําให้เกิดข้อผิดพลาด สถานะการออกจะเป็น 1 ขึ้นไป วิธีนี้เป็นวิธีหนึ่งที่ใช้ในไปป์ไลน์ CI/CD เพื่อพิจารณาความสําเร็จ/ความล้มเหลวของเครื่องมือ

แก้ไขไฟล์ main.go และแก้ไขโค้ด

  • ใส่เครื่องหมายกำกับความคิดเห็นในบรรทัดด้านล่าง LINTING - Step 1 ภายในเมธอด main() โดยเพิ่มเครื่องหมายทับขึ้นต้น(//)
  • ยกเลิกการคอมเมนต์ 2 บรรทัดใต้ LINTING - Step 2 ภายในเมธอด main() โดยนำเครื่องหมายทับขึ้นต้นออก

เรียกใช้ staticcheck อีกครั้งในไดเรกทอรีรูทของโปรเจ็กต์

staticcheck

คำสั่งไม่ควรแสดงผลลัพธ์ใดๆ (เช่น บรรทัดว่าง)

ตรวจสอบสถานะการออกของคําสั่ง

  echo $?

ในกรณีนี้ สถานะการออกจะเป็น 0 เนื่องจากคำสั่งไม่ทำให้เกิดข้อผิดพลาด

4. การทดสอบความปลอดภัยของแอปพลิเคชันแบบคงที่

AST/Static security testing - ให้บริการวิเคราะห์โค้ดแบบคงที่เพื่อหาจุดอ่อนและช่องโหว่ที่พบได้ทั่วไป ( CWEs)

ติดตั้งเครื่องมือ 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}

เรียกใช้ gosec ด้วยไฟล์นโยบายกับซอร์สโค้ด

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

เอาต์พุตควรมีลักษณะคล้ายกับตัวอย่างนี้

{
    "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
    }
}

เครื่องมือตรวจพบปัญหาที่อาจเกิดขึ้น Potential hardcoded credentials

5. การสแกนใบอนุญาต

ใบอนุญาตมีความสำคัญต่อความปลอดภัยเนื่องจากกฎหมายอาจกำหนดให้คุณเปิดเผยซอร์สโค้ดที่คุณอาจไม่ต้องการเปิดเผย แนวคิดนี้เรียกว่าใบอนุญาต "copyleft" ซึ่งกำหนดให้คุณเปิดเผยซอร์สโค้ดหากใช้ทรัพยากรที่มีใบอนุญาตเหล่านั้น

ติดตั้ง 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

สร้างไฟล์ไบนารี

go build

เรียกใช้การตรวจสอบใบอนุญาตด้วยไฟล์นโยบายปัจจุบันที่ไม่อนุญาตให้ใช้ใบอนุญาต "BSD-3-Clause"

golicense policies/license-policy.hcl hello-world

หมายเหตุ: การดำเนินการนี้ควรดำเนินการไม่สำเร็จพร้อมแสดงผลลัพธ์ที่คล้ายกัน

 🚫 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

แก้ไขไฟล์นโยบาย policies/license-policy.hcl เพื่อย้าย "BSD-3-Clause" จากรายการ deny ไปยังรายการ allow

เรียกใช้การตรวจสอบใบอนุญาตอีกครั้ง

golicense policies/license-policy.hcl hello-world

หมายเหตุ: การดำเนินการนี้ควรสำเร็จโดยมีเอาต์พุตที่คล้ายกัน

    ✅ 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. ขอแสดงความยินดี

ยินดีด้วย คุณทำ Codelab เสร็จแล้ว

สิ่งที่คุณได้เรียนรู้

  • เครื่องมือและเทคนิคในการรักษาความปลอดภัยให้กับซอร์สโค้ด

อัปเดตล่าสุด: 23/3/23