Sonarqube คืออะไร? และใช้งานยังไง?
SonarQube ถือได้ว่าเป็นเครื่องมือที่หลายๆคนเลือกมาเป็นส่วนหนึ่งใน CI/CD pipeline ถือได้ว่าเป็นเครื่องมือที่ช่วยให้เราจัดการกับปัญหาที่รับมือได้ยากมากๆ นั่นคือ Code Quality
SonarQube คืออะไร?
SonarQube คือ Quality Management Tool หรือเครื่องมือที่ใช้ในการจัดการกับ Code Quality ซึ่งในช่วงหลัง SonarQube จะค่อนข้างโด่งดังในเรื่อง Security ส่วนใหญ่เราจะใช้ SonarQube Scan เพื่อหาช่องโหว่ใน source code แต่จริงๆแล้ว Sonarqube จะแยกปัญหาออกมาเป็น 4 กลุ่ม ดังนี้
-
Bug คือ rules ที่จะตรวจสอบ source code ที่น่าจะเขียนผิด เช่น
1 2 3 4 5 6 7 8 9
int? nullable = 42; // Noncompliant, จะเป็น false เสมอ bool comparison = nullable.GetType() == typeof(Nullable<int>); // Noncompliant, จะเป็น true เสมอ comparison = nullable.GetType() != typeof(Nullable<int>); nullable = null; // Noncompliant, การเรียก method .GetType ของตัวแปรที่เป็น null จะทำให้เกิด exception comparison = nullable.GetType() != typeof(Nullable<int>);
จาก rule ด้านบนเป็นภาษา c# การเปรียบเทียบประเภทของข้อมูลโดยใช้ method .GetType() function typeof ซึ่งค่าที่ได้จะไม่มีทางเท่ากัน เนื่องจาก .GetType() จะ return int เพราะเรากำหนดค่า 42 ให้กับตัวแปร nullable แล้ว แต่ในขณะที่เราใช้ typeof จะ return Nullable
กลับมา ดังนั้นมันจะไม่มีทางเท่ากัน สรุปง่ายๆคือ เราถาม type ตอนประกาศตัวแปรเราจะใช้ typeof ซึ่งได้คำตอบเป็น nullable type แต่ .GetType() เป็นการถามตอนที่สร้าง object ขึ้นมาแล้วดังนั้่นจะมี 2 ทางคือ
- ถ้าใช้ .GetType() ตอนเป็น null ก็จะเกิด exception ขึ้นเพราะ null ไม่มี method นี้
- ถ้าใช้ .GetType() ตอนเป็น int ก็จะได้คำตอบออกมาเป็น int
ดังนั้นไม่ว่าจะเป็นทางไหน ก็ไม่ได้ตอบเป็น nullable type ดังนั้น ในบรรทัดที่ 3 จึงเป็น false เสมอ
-
Code smell คือ rules ที่จะตรวจสอบ code ที่อ่านยากหรือแก้ไขได้ยาก เช่น
1 2 3 4 5 6 7 8
public class Program { // Non-Compliant, array 2 มิติ ไม่ได้บอกว่าต้องส่งอะไรเข้ามาบ้าง public void WriteMatrix(int[][] matrix) { ... } }
ใน c# จะไม่ให้ใช้ multidimention array เป็น parameter เพราะอ่านยาก ควรสร้างเป็น object หรือ array ของ object แล้วโยนเข้าไปจะทำให้อ่าน code แล้วเข้าใจได้ง่ายกว่า
1 2 3 4 5 6 7 8 9 10 11 12
public class Matrix { // ในนี้จะมี properties ที่บอกเราได้ว่าจะต้องส่งอะไรไปบ้าง } public class Program { public void WriteMatrix(Matrix matrix) // Compliant { ... } }
-
Vulnerability คือ rules ที่จะตรวจสอบ code ที่เขียนแล้วน่าจะมีช่องโหว่ เช่น
1 2 3 4 5 6 7 8 9 10 11 12
public class ExampleController : Controller { private readonly UserAccountContext Context; public IActionResult Authenticate(string user, string pass) { // Non-compliant, เอาตัวแปร user ไปต่อใน string ที่นำไป query จะทำให้เกิด sql injection var query = "SELECT * FROM users WHERE user = '" + user + "' AND pass = '" + pass + "'"; ... } }
เอาตัวแปรไปต่อกับ sql command โดยใช้เครื่องหมาย “+” ในการเชื่อม string จะทำให้เกิดช่องโหว่ที่ชื่อ SQL Injection
-
Security hotspot คือ rules ที่อาจเกิดเป็นช่องโหว่ได้ คล้่ายกับ vulnerability แต่ sonarqube ยังไม่แน่ใจจึงต้องการให้เราเข้าไป review เช่น
1 2 3 4 5 6
// Sensitive use of Random var random = new Random(); byte[] data = new byte[16]; random.NextBytes(data); // Check if this value is used for hashing or encryption return BitConverter.ToString(data);
ในตัวอย่างด้านบนเป็นปัญหาที่เกิดจากการใช้ function random ที่ไม่่ secure ซึ่งการใช้ random สามารถใช้ได้กับ business case ทั่วไป เช่น random การแสดงผลของ blog post แต่จะไม่สามาถใช้กับการ hashing หรือ excryption ที่ต้องการปกปิดความลับได้ เพราะฉะนั้นเราจึงต้อง review ว่าค่าที่ return ออกไปนี้เอาไปใช้ทำอะไร
ถ้าส่วนไหนที่ต้อง random แล้วนำไปใช้กับการ hashing และ encryption เราต้องใช้ Cryptographic function แบบนี้ ภาษาอื่นๆสามารถดูรายละเอียดเพิ่มเติมได้จาก recommended ของ OWASP
1 2 3 4 5 6
using System.Security.Cryptography; ... var randomGenerator = RandomNumberGenerator.Create(); // Compliant for security-sensitive use cases byte[] data = new byte[16]; randomGenerator.GetBytes(data); return BitConverter.ToString(data);
SonarQube ประกอบไปด้วย
การจะใช้งาน SonarQube จำเป็นต่้องมีสิ่งที่ต้องติดตั้ง 3 ส่วนหลักๆ ดังนี้
- Sonar Scanner คือเครื่องมือที่ใช้ในการ scan source code ดังนั้นต้องติดตั้งในเครื่องที่มี source code เช่นถ้า scan บนเครื่อง dev ก็ต้องติดตั้ง sonar scanner บนเครื่อง dev แต่ถ้า scan บนเครื่องที่ทำ CI/CD เราก็ต้องไปติดตั้ง sonar scanner ใน server ที่ run pipeline นี้
- SonarQube Server คือ server ที่จัดเก็บผลลัพธ์ที่ได้จากการ scan เป็นแกนหลักของการ scan source code ด้วย sonarqube
- Database Server เนื่องจาก sonarqube server นั้นทำการเก็บข้อมูลอยู่ใน memory เท่านั้น ดังนั้นเราเลยต้องทำการ link database เข้าไปเพื่ิอจะได้เก็บผลลัพธ์ที่ได้จากการ scan ให้คงอยู่ถาวร ซึ่ง database ที่ sonarqube support นั้นประกอบด้วย
- PostgreSql
- Microsoft SQL Server
- Orable
Default admin credentials
หลังจาก install sonarqube server เสร็จเรียบร้อย ระบบจะทำการสร้าง user ที่มีสิทธิเป็น Admin ให้โดยอัตโนมัติ เราสามารถ Login เข้าไปในระบบด้วย user นี้
Login: admin
Password: admin
วิธีใช้งาน SonarQube เบื้องต้น
การใช้งาน SonarQube จะมีอยู่ 3 ทางหลักๆ คือ
- run sonar-scanner ผ่านทาง command-line, maven หรือ gradle(manual)
- ติดตั้ง sonar lint ใน editor ที่เราใช้งานอยู่แล้ว config ให้ส่งผลลัพธ์ขึ้นไปบน server(auto)
- run sonar-scanner ผ่านทาง CI/CD pipeline(auto)
ซึ่งในตัวอย่างนี้จะเป็นการ scan ผ่านทาง command-line บน windows
Generate token บน SonarQube server
- login เข้าไปใน sonarqube server
- เลือก menu project
- กดปุ่ม create project
- เลือกการติดตั้งแบบ Manually
- ตั้ง project key(ใน server เดียวกันจะไม่สามารถใช้ key ซ้ำกันได้)
- ตั้งชื่อของ Token แล้วกดปุ่ม Generate Key แล้วก็ copy key นี้เอาไว้ใช้ในขั้นตอนถัดไป
Generate Token ใหม่โดยที่ไม่ได้ create project
เราสามารถเข้าไปจัดการกับ token ได้โดยที่ไม่ต้อง create project ซึ่งเราต้องเข้าไปที่
-
เปิด My Account
-
เลือก tab Security
-
ให้ตั้งชื่อ token ที่จำได้ง่ายว่าเอาไปใช้ทำอะไร
-
เลือก type เป็น Project analysis tokens
-
กำหนด Expires in ตามต้องการ(ยิ่งกำหนดให้นานเท่าไหร่ยิ่งไม่ปลอดภัย)
-
กดปุ่ม Generate แล้วก็ copy token ออกมาใช้งานได้เลย
Token ไหนไม่ใช้แล้วหรือมีความเสี่ยงที่จะโดนขโมยให้เราทำการ Revoke ออกทันที
วิธีการ scan ด้วย sonar-scanner
-
ติดตั้ง sonar-scanner โดย download sonar-scanner-cli ได้ตาม link นี้
-
เลือก windows-64 bits
-
สร้าง ไฟล์ sonar-project.properties(ไฟล์ที่กำหนด configuration) ไว้ที่เดียวกับ source code โดยใส่เนื้อหาดังนี้
# ต้องกำหนดตอนสร้าง project บน sonarqube server # project key ห้ามซ้ำกัน sonar.projectKey=my:project # --- optional properties --- # ชื่อ project ถ้าไม่กำหนด sonar-scanner จะใช้ project key แทนก sonar.projectName=My project # กำหนด version ของ source code ชุดนี้ # ควรจะ update version ไปเรื่อยๆ sonar.projectVersion=1.0 # ระบุว่า source code อยู่ใน folder ไหน # default จะเป็น . ซึ่งคือ directory ที่ไฟล์ sonar-project.properties อยู่ sonar.sources=. # ระบุว่า sonarqube server อยู่ที่ไหน sonar.host.url=http://localhost:9000 # เราต้องได้ Token จาก server ถึงจะสามาถส่งผลลัพธ์ขึ้นไปยัง Sonarqube Server ได้ # เราจะได้ token ตอน create project หรือเข้าไปใน user profile เพื่อ generate token ใหม่ sonar.login= [Token ที่ได้จาก Sonarqube Server] # รอผลลัพธ์จาก Sonarqube Server ว่าผ่านหรือไม่ผ่านเงื่อนไขที่เรากำหนดไว้ใน quality gate sonar.qualitygate.wait=true
-
สั่ง run command นี้ใน directory ที่มีไฟล์ sonar-project.properties
sonar-scanner
-
กลับไปดูผลลัพธ์บน SonarQube Server
คำศัพท์ที่ต้องรู้จักก่อนใช้ SonarQube
ก่อนจะใช้งาน sonarqube เราลองมาทำความเข้าใจศัพท์แต่ละตัวที่ต้องใช้ใน sonarqube กันก่อน
Rules
rules คือกฎต่างๆที่ sonarqube เขียนขึ้นมาและถูกเรียกใช้โดย default ซึ่ง rules ของ sonarqube นั้นจะชื่อว่า sonar-way แต่นอกจาก sonar-way แล้วเรายังสามารถ download ของค่ายอื่นๆ ผ่านทาง marketplace เพิ่มเติมได้อีกด้วย
Quality Profiles
Quality profiles จะเป็น set ของ rules เราสามารถ download Quality profile เพิ่มเติมได้จากหน้า marketplace หรืออาจ custom quality profiles ของเราได้โดยทำการ copy quality profile ออกมาแล้วก็เพิ่มหรือลด rule ได้ตามต้องการ
Quality Gate
เป็นเงื่อนไขที่เราสามารถกำหนดได้ว่า Quality ที่เราอยากได้นั้นอยู่ในระดับไหน เช่น จำนวน vulnerabilities ต้องไม่เกินเท่าไหร่ ซึ่งสิ่งที่เราต้องกำหนดมี 3 อย่างคือ
- Measure คือตัววัดต่างๆที่ sonarqube มีเช่น จำนวน vulnerability หรือจำนวน bug
- Comparison operator คือเครื่องหมายในการเปรียบเทียบทั่วไปเช่น มากกว่า, มากกว่าหรือเท่ากับ
- Error value คือค่าที่ต้องการกำหนดเช่น จำนวน bug ต้องไม่เกิน 10 การกำหนด value อาจใส่เป็นจำนวนหรือเป็นเปอร์เซ็นขึ้นอยุ่กับ measure ที่เราเลือก
Duplicate Code
Code ที่เขียนแล้วซ้ำกัน ซึ่ง sonarqube จะทำการค้นหา code ส่วนที่ซ้ำกันแล้วก็สรุปผลไว้ในหน้า dashboard ว่า code เรา duplicated กี่เปอร์เซ็น ดังรูป
เมื่อเราคลิกที่รูปแว่นขยายก็จะเข้าสู่หน้า report ดังรูป
สิ่งที่เราต้องสนใจจะอยู่ที่มุมซ้ายบน ซึ่งจะเป็นส่วนที่มี duplicated lines(จำนวนบรรทัดที่ซ้ำกัน) เยอะมากกว่าส่วนอื่น เมื่อเราคลิกเข้าไป sonarqube จะพาไปยัง source code ส่วนที่มีการซ้ำกัน และเรายังสามารถกดเข้าไปดูว่ามีไฟล์ไหนที่ใช้ code นี้บ้าง(ต้องกด ที่ bar สีเทาหนึ่งครั้งให้แสดงแถบ bar สีเทาหลายๆแถบก่อน) ดังรูป