12.3 · Critical findings summary
ตารางนี้รวมทุก finding ที่ถูก mark เป็น Critical/🔴 จากการอ่าน *scorecard*.md/*-debt.md ทั้ง 27 ไฟล์ของ Volume 3-9 — รวมทั้งหมด 48 finding จาก 21 repo (repo ที่เหลือใน 25 repo ไม่มี Critical finding เลย หรือเป็น placeholder ที่ยังไม่มีโค้ด)
ID คงรูปแบบเดิมตามที่ต้นทางกำหนด (ส่วนใหญ่ prefix SEC-, centralize-api ใช้ CRIT- แยกจากกัน) — ไม่มีการ renumber
Volume 3 · Legacy Core (14 finding)
| ID | Repo | file:line | คำอธิบาย |
|---|---|---|---|
SEC-VTRC-API-01 | vtrc-api | routes.js:73,120,227,277,355 | Command injection ผ่าน execSync ใน PDF pipeline (qpdf) — 5 call site active |
SEC-VTRC-API-02 | vtrc-api | config.js:12 | Default JWT_SECRET = 'secret' — forge token ได้ถ้า env ไม่ override |
SEC-VTRC-API-03 | vtrc-api | routes.js:975-984 | /webdeployment รัน shell binary โดยไม่มี auth |
SEC-VTRC-API-04 | vtrc-api | routes.js:464 | /file/:id/download ไม่มี apiKey check |
SEC-CU-01 | cu-central-api | config.js, jwtToken.js | JWT_SECRET default เป็น empty string — jsonwebtoken@8.5.1 ยอม sign ด้วย empty string โดยไม่ throw |
SEC-CU-02 | cu-central-api | lib/auth/auth.controller.js | apiKeys hardcoded ในโค้ด (2 keys) |
SEC-CU-03 | cu-central-api | repo root (.env.develop-test) | .env.develop-test (UAT secrets) commit อยู่ในโค้ด |
SEC-CU-04 | cu-central-api | routes.js | /auth/signinbypass — passwordless signin ที่ live ใน production |
SEC-CU-05 | cu-central-api | directives/auth.js, searchProfile.js | ignoreAuth bypass ที่ apiKey อย่างเดียวพอ |
SEC-CU-06 | cu-central-api | activeDirectory.connector.js | rejectUnauthorized: false ใน LDAP connection |
CRIT-01 | centralize-api | .env:1-15 | .env committed มี plaintext DB password + internal IP |
CRIT-02 | centralize-api | .env:15 | SECRET_KEY เป็น SSH public key fragment ไม่ใช่ random secret |
CRIT-03 | centralize-api | ทุก controller | Auth bypass 100% — @Public() ทุก route (17/17 endpoint) |
CRIT-04 | centralize-api | ทุก endpoint ที่ return PII | PII exposure ไม่มี auth — ละเมิด PDPA มาตรา 26 |
Volume 4 · Web Frontends (4 finding)
| ID | Repo | file:line | คำอธิบาย |
|---|---|---|---|
SEC-BONEW-01 | vtrc-backoffice-new | src/pages/Login/index.js:93-103 | login flow ส่ง access token + refresh token เป็น path segment ของ URL ข้ามorigin |
C1 | vtrc-rc-backoffice | .env (6 บรรทัด, ไม่อยู่ใน .gitignore) | .env committed ลง git มี secret จริง (REACT_APP_PRIVATE_KEY, REACT_APP_STIMUL_CONN_STRING, ฯลฯ) |
C2 | vtrc-rc-backoffice | build bundle (CRA inline REACT_APP_*) | REACT_APP_STIMUL_CONN_STRING (MSSQL connection string) ฝังใน bundle ส่งให้ browser |
C3 | vtrc-rc-backoffice | containers/App/index.js:24 | SSO bypass /pathLogin/:token/:refreshToken รับ token ใน URL |
vtrc-backoffice และ vtrc-web ไม่มี finding ที่ mark เป็น Critical อย่างชัดเจนในสองบทนี้ (สูงสุดคือ High)
Volume 5 · 2way Platform (8 finding)
| ID | Repo | file:line | คำอธิบาย |
|---|---|---|---|
SEC-2WAYAPI-01 | 2way-api | src/modules/auth/auth.service.ts:184-240 | Backdoor login hardcode username/password (i3admin/aA123456!) ออก JWT อายุ 48 ชม. |
SEC-2WAYAPI-02 | 2way-api | src/modules/auth/auth.service.ts:20-26 | SSO/JWT secret มี default fallback ฝังในซอร์สโค้ด |
SEC-2WAYAPI-03 | 2way-api | src/modules/announces/announces.service.ts:164-296,297-463 (+ surveys.service.ts, complaints.service.ts) | SQL injection จาก string interpolation ใน raw SQL WHERE clause |
SEC-2WAYAPI-04 | 2way-api | src/modules/announces/announces.controller.ts:45,56,79,85, src/modules/line/line.controller.ts | Global JwtAuthGuard bypass ด้วย @Public() บนแทบทุก write endpoint |
SEC-2WAYLINE-01 | 2way-line-service | src/modules/line/line.controller.ts:13,19,25,31 | ทุก endpoint ของ LineController เป็น @Public() |
SEC-2WAYVTRC-01 | 2way-vtrc-api | middleware/checkbypasstoken.ts:24 | Master bypass token static string "testnaja" |
SEC-2WAYVTRC-02 | 2way-vtrc-api | routes/TwoWayAPI/userLine/getProfile.ts:34-63,79-134 | POST /2way/getProfile ไม่มี middleware ป้องกัน — คืน PII (idCard, birthDate, phone) จาก lineID |
SEC-2WAYVTRC-03 | 2way-vtrc-api | util/mongo.config.ts:8 | Credential MongoDB production commit ตรงในซอร์ส |
2way-batch และ 2way-meeting-backoffice ไม่มี Critical finding
Volume 6 · Domain Microservices (15 finding)
| ID | Repo | file:line | คำอธิบาย |
|---|---|---|---|
SEC-BENEFIT-01 | benefit-api | .env:18,25,32,64, exportpaymentreport.service.ts:5271,5824,6151 | Production credential หลุดเข้า git — MSSQL password ×3, JWT secret, SFTP password hardcode ในโค้ด |
SEC-BENEFIT-02 | benefit-api | payments.service.ts:415-573,640-720,1032-1183,1185-1435, approvedisaster.service.ts:415-417 | Raw SQL string interpolation ข้าม 2 database (schema vtrc) — SQL injection surface ขนาดใหญ่ |
SEC-RECRUIT-01 | recruitment-api | .env:11,18,25,32,44,45,52,55, vtrc-gcp-sa-key.json | Production credential หลุดเข้า git — MSSQL, JWT ×2, SMTP, reCAPTCHA, GCP key |
SEC-RECRUIT-02 | recruitment-api | candidate.repositories.ts:1324-1338 | SQL injection ผ่าน dynamic EXEC stored procedure string (connection ai) |
SEC-AIRECRUIT-01 | ai-recruitment-api | .env:2,5,7,9-10,11 | Production credential + OpenAI/remove.bg/HCTI API key ที่มีค่าใช้จ่ายจริง หลุดเข้า git |
SEC-AIRECRUIT-02 | ai-recruitment-api | middleware/verifyJWT.js:7-40 | ไม่มี authorization ระดับ role/scope — ทุกคนที่มี JWT (จาก secret ที่ share) เรียก AI generation ได้ไม่จำกัด |
SEC-PMS-01 | pms-api | src/modules/budget/budget.controller.ts:49-53 | GET /budget/getEmployeeSalary เป็น @Public() — คืนเงินเดือนพนักงานไม่ต้อง login |
SEC-PMS-02 | pms-api | .env:12,19,26,33,41,45, vtrc-gcp-sa-key.json | Credential (UAT) + JWT secret ที่ share กับ prod ของ 3 service อื่น หลุดเข้า git |
SEC-CHAT-01 | chat-center-api | src/modules/chat/chat.service.ts:103-157, src/modules/tags/tags.service.ts:55-61 | Raw SQL string interpolation จาก query param ผู้ใช้ — SQL injection |
SEC-CHAT-04 | chat-center-api | .env:10-11,26,28-29 | .env commit เข้า git — MSSQL sa (h@ckm3SA?), MongoDB, LINE channel secret/token |
SEC-JOBSCHED-01 | job-scheduler-api | .env:9-11,18 | .env commit เข้า git — MSSQL sa password + RSA-format secret key ร่วมกับหลาย repo |
SEC-COMMON-01 | vtrc-common | file.controller.ts:18,24, address.controller.ts:14,20,26,32,38,44, bank.controller.ts:13,19, .env:12 | ทุก endpoint จริงเข้าถึงได้แบบไม่ auth จริง (@Public() หรือ secret ที่ commit ทำให้ forge JWT ได้) |
SEC-COMMON-03 | vtrc-common | .env:11,17 | .env commit — MSSQL sa password + SECRET_KEY (RSA format) ร่วมกับ chat-center-api/job-scheduler-api |
SEC-WORKFLOW-01 | workflow-api | src/main.ts:9-82, src/common/auth/jwt-actor.util.ts:1-4,33-47, src/modules/ipd/ipd-user.util.ts:20-65 | ไม่มี JWT guard ระดับ global/module ใดในทั้ง repo — role อนุมานจาก payload ที่ไม่ verify signature |
SEC-WORKFLOW-02 | workflow-api | .env.example:11,31,44 | .env.example มีรหัสผ่านจริง — AI_ROUTER_API_KEY, DB_PMS_PASSWORD, MSSQL sa |
sso-api ไม่มี Critical finding (สูงสุดคือ High — CORR-SSO-01)
Volume 7 · Meeting Platform (2 finding)
| ID | Repo | file:line | คำอธิบาย |
|---|---|---|---|
SEC-MTVTRC-01 | meeting-vtrc-api | .envprod:1-9 (และ .envdev/.envuat) | .envdev/.envuat/.envprod commit เข้า git plaintext — API_KEY, SECRET_JWT_MEETING, MAIL_PASS |
SEC-MTVTRC-02 | meeting-vtrc-api | routes/mockdelatlast/mockuser.ts:29-60, mount app.ts:209-210 | /meeting/mockuser/one ไม่มี auth — คืน PII จริง (ชื่อ, อีเมล, เบอร์โทร) hardcode ในซอร์ส |
meeting-backoffice และ meeting-backoffice-new ไม่มี Critical finding
Volume 8 · Mobile (3 finding)
| ID | Repo | file:line | คำอธิบาย |
|---|---|---|---|
SEC-MOBILE-01 | vtrc-mobile | src/utils/login.js:16-42 | RSA private key (PEM เต็ม) hardcode ในซอร์สที่ compile เข้า JS bundle |
SEC-MOBILE-02 | vtrc-mobile | android/app/build.gradle:174-179 | Android release keystore path + storePassword/keyPassword/keyAlias plaintext commit |
SEC-NEW-01 | new-vtrc-mobile | src/constants/RSAKey.ts:11-38 | RSA private key เดียวกับ vtrc-mobile ถูก copy มา hardcode ซ้ำ |
vtrc-application-front ไม่มี Critical finding
Volume 9 · OCR & Auxiliary (2 finding)
| ID | Repo | file:line | คำอธิบาย |
|---|---|---|---|
SEC-RCWEB-01 | recruitment-web | .env:2,9, .env.uat:2,7, src/utils/cryptoJs.js:1-32 | .env/.env.dev/.env.uat tracked ใน git — REACT_APP_SECRET_KEY/REACT_APP_PRIVATE_KEY เข้ารหัส PII ผู้สมัครงานฝังอยู่ในทั้ง git history และ bundle |
SEC-REPORTLOG-01 | report-log | request_2023-02-17.log (และ -18, -19 เป็นอย่างน้อย จากทั้งหมด 50 ไฟล์) | ไฟล์ request_*.log มี citizenId/birthDate/empCode จริงของผู้ใช้ในรูปแบบ plaintext commit เข้า git |
vtrc-ocr-api ไม่มี Critical finding
สรุปจำนวนต่อ repo
| Repo | จำนวน Critical |
|---|---|
vtrc-api | 4 |
cu-central-api | 6 |
centralize-api | 4 |
vtrc-backoffice-new | 1 |
vtrc-rc-backoffice | 3 |
2way-api | 4 |
2way-line-service | 1 |
2way-vtrc-api | 3 |
benefit-api | 2 |
recruitment-api | 2 |
ai-recruitment-api | 2 |
pms-api | 2 |
chat-center-api | 2 |
job-scheduler-api | 1 |
vtrc-common | 2 |
workflow-api | 2 |
meeting-vtrc-api | 2 |
vtrc-mobile | 2 |
new-vtrc-mobile | 1 |
recruitment-web | 1 |
report-log | 1 |
| รวม | 48 |
หมายเหตุความคลาดเคลื่อนที่พบระหว่างสังเคราะห์ — Volume 6 index.md รายงานยอดรวม Critical ของกลุ่ม Domain Microservices ไว้ที่ 16 (ระบุ benefit-api = 3) แต่การอ่าน benefit-api/06-scorecard.md ตรงพบว่ามีเพียง 2 finding ที่ mark หัวข้อ "Severity: Critical" จริง (SEC-BENEFIT-01, SEC-BENEFIT-02 — SEC-BENEFIT-03 อยู่ใต้หัวข้อ "Severity: High") ตารางในบทนี้ยึดตาม scorecard รายไฟล์เป็นหลัก (2 สำหรับ benefit-api) ทำให้ยอดรวม Volume 6 ที่ถูกต้องคือ 15 ไม่ใช่ 16 — ควรแก้ตัวเลขใน Volume 6 index.md ให้ตรงกับ scorecard ต้นทาง (ดู 12.4 สำหรับ debt ID ของความคลาดเคลื่อนเชิง documentation นี้)
Repo ที่ไม่มี Critical finding เลย
vtrc-backoffice, vtrc-web, 2way-batch, 2way-meeting-backoffice, sso-api, meeting-backoffice, meeting-backoffice-new, vtrc-application-front, vtrc-ocr-api — ไม่ได้แปลว่าไม่มีความเสี่ยงเลย (หลายตัวมี High finding ที่ควรแก้เช่นกัน) แต่ไม่ถึงระดับที่ scorecard ต้นทาง mark เป็น Critical
Pattern เชิงระบบที่ทำให้เกิด 48 finding นี้ ดู 12.4 Scorecard →