Skip to content

2way-vtrc-api — Scorecard

Legend:

  • Critical = active security/data-loss/availability risk
  • High = correctness/maintainability hazard, real impact
  • Medium = friction/hygiene, ยังไม่เป็นอันตรายระดับ production-breaking ทันที

2way-vtrc-api (branch: prod) เป็น repo ที่มีความเสี่ยงสูงในกลุ่ม 2way Platform เพราะเป็น backend หลักของฝั่งพนักงานจริง (ยืนยันจาก 2way-meeting-backoffice) และมี auth bypass ที่ชัดเจน


Score summary

Severityจำนวน (ในตารางด้านล่าง)
Critical5
High7
Medium6

Security

IDSeverityคำอธิบายหลักฐาน (file:line)การแก้ไข
SEC-2WAYVTRC-01CriticalMaster bypass token แบบ static string "testnaja" ข้ามการยืนยันตัวตนของ checkBypassTokenMiddleWare — ใครที่อ่านซอร์สเรียก endpoint ที่ใช้ middleware นี้ได้ทันที (เช่น addNewIncident, list/update ส่วนใหญ่)middleware/checkbypasstoken.ts:24ลบเงื่อนไข token == "testnaja"; ตรวจ access log ย้อนหลัง; rotate token ที่อาจถูกใช้คู่กับ bypass
SEC-2WAYVTRC-01bCriticalMaster bypass "testnaja" ซ้ำใน checkBypassTokenLineMiddleWare — ข้าม LINE token verify ทั้งชุดของ LIFF endpointsmiddleware/checkByPassTokenLine.ts:30ลบเงื่อนไขเดียวกันฝั่ง LINE middleware
SEC-2WAYVTRC-02CriticalPOST /2way/getProfile ไม่มี middleware (auth ถูก comment ปิด) รับ lineID จาก body แล้วคืน identityCard, birthDate, และเติม fullName/tel จาก cu-central — PII ไม่มี session bindingroutes/TwoWayAPI/userLine/getProfile.ts:34-63, 79-133เปิด checkBypassTokenLineMiddleWare กลับ; ดึง lineID จาก verified LINE profile เท่านั้น ไม่รับจาก body
SEC-2WAYVTRC-02bCriticalPOST /2way/getProfile/cu พฤติกรรมเดียวกัน (auth comment ปิด)routes/TwoWayAPI/userLineCu/getProfile.ts:35-63แก้แบบเดียวกับ SEC-2WAYVTRC-02
SEC-2WAYVTRC-03CriticalCredential MongoDB production (username/password/host) commit ในซอร์ส — แม้ connection ถูก comment ปิดใน entrypoint credential ก็หลุดแล้วutil/mongo.config.ts:2-8rotate credential; ย้ายไป secret manager/env; ลบจาก git history ถ้า policy บังคับ
SEC-2WAYVTRC-03bCriticalCredential MSSQL (sa + password + host 10.188.128.61) hardcode ใน util/env.ts บล็อก Prod ที่ active — ไม่ได้อ่านจาก .envutil/env.ts:17-32ย้ายไป env/secret; rotate password ของ sa; หลีกเลี่ยงใช้ sa เป็น app user
SEC-2WAYVTRC-04HighJWT SECRET ใน util/jwt.config.ts เป็น string literal ไม่มี env override — คนละตัวจาก SECRET_JWT_TWOWAYutil/jwt.config.ts:2, เทียบ checkbypasstoken.ts:65รวม secret เหลือชุดที่ชัดเจน อ่านจาก env ทั้งหมด แล้ว rotate
SEC-2WAYVTRC-05HighSequelize encrypt: false — เชื่อม MSSQL แบบไม่เข้ารหัส TLSutil/db.config.ts:8-11เปิด encrypt: true พร้อม certificate ที่ถูกต้อง
SEC-2WAYVTRC-06MediumCORS ตั้ง Access-Control-Allow-Origin: * พร้อม Access-Control-Allow-Credentials: true พร้อมกัน — ขัดกับพฤติกรรมเบราว์เซอร์มาตรฐาน และสื่อเจตนาเปิดกว้างเกินจำเป็นapp.ts:87-99whitelist origin ที่ต้องการ; อย่าใช้ * กับ credentials
SEC-2WAYVTRC-07CriticalPOST /2way/updateIncident มีแค่ validatorUpdateIncidentไม่มี bypass/LINE middleware; อัปเดตสถานะ incident ได้โดยไม่ต้องมี tokenroutes/TwoWayAPI/incident/updateIncident.ts:23ใส่ checkBypassTokenMiddleWare (หรือ role ที่เหมาะสม) ก่อน handler
SEC-2WAYVTRC-08CriticalSSO integration credentials + AES key/IV hardcode ใน loginSSO.ts รวมถึง SSO_PASSWORD และ endpoint IP ภายในroutes/TwoWayAPI/sso/loginSSO.ts:21-27ย้ายไป env/secret; rotate SSO app password และ AES key; ตรวจว่า key เก่าถูกใช้ที่อื่นหรือไม่
SEC-2WAYVTRC-09Highpassport-jwt strategy เรียก done(null, true) เสมอ — ไม่ bind user จาก payload; การมี JWT ที่ sign ด้วย SECRET เท่ากับผ่านmiddleware/jwtpassport.ts:9-12validate payload (user id / claims) จริง; reject ถ้าไม่พบ user
SEC-2WAYVTRC-10MediumMiddleware log ทั้ง req.headers และ token ลง consolecheckbypasstoken.ts:16-17, checkByPassTokenLine.ts:19-20ลบหรือ redact; ใช้ structured logger ระดับที่เหมาะสม

Correctness / data integrity

IDSeverityคำอธิบายหลักฐานการแก้ไข
CORR-2WAYVTRC-01HighcreateIncident insert หลายตาราง (RemarkIncidentRunningIncidentAttachment) โดยไม่มี sequelize.transaction() — fail กลางทางเหลือ orphancreateIncident.ts:38-151 (ไม่พบ transaction)ครอบด้วย transaction + rollback
CORR-2WAYVTRC-01bHighAttachment loop ใช้ .map(async ...) โดยไม่ await รวม — response Success อาจกลับก่อนไฟล์ถูก insertcreateIncident.ts:104-127ใช้ await Promise.all(...) หรือ for-loop await
CORR-2WAYVTRC-02HighMongo connection ถูก comment ปิดใน app.ts แต่ socket chat ยังเขียนผ่าน Mongoose schemaapp.ts:10 เทียบ lib/Socket.func.ts + app.ts:277-282ยืนยันว่า chat ยังใช้จริง; เปิด connection หรือถอด socket/chat code
CORR-2WAYVTRC-03HighjwtExpiration: 60 / jwtRefreshExpiration: 120 ถูก comment ว่า for test แต่ยังเป็นค่าที่ export จริง — token อายุสั้นผิดปกติสำหรับ production login flows ที่ใช้ jwt.configutil/jwt.config.ts:6-8ตั้งค่า production ที่สมเหตุสมผลผ่าน env
CORR-2WAYVTRC-04MediumsetRunningNo นับจาก Incident.count แล้ววนเช็คซ้ำ — concurrent create อาจชนกันก่อน unique constraint (ถ้ามี)createIncident.ts:243-269ใช้ sequence/transaction isolation หรือ DB constraint + retry
CORR-2WAYVTRC-05MediumBusiness error หลายจุดส่ง HTTP 200 พร้อม status.code ไม่ใช่ 4xx/5xx — client ที่เช็คแค่ HTTP status จะเข้าใจผิดว่าสำเร็จcreateIncident.ts:30-34, loginSSO.ts:37-42แยก HTTP status ให้ตรงกับผล; คง envelope เดิมถ้าต้อง backward compatible

Quality / legacy / ops

IDSeverityคำอธิบายหลักฐานการแก้ไข
QUAL-2WAYVTRC-01MediumMock routers สไตล์ JSONPlaceholder ยัง mount ที่ /2way/TwoWayAPI และ /2way/MeetingAPI — ตอบข้อมูลปลอม/Success โดยไม่แตะ DBapp.ts:110-113, routes/TwoWayAPI/index.ts:196-259, routes/MeetingAPI/user.tsลบ mount และไฟล์ mock ถ้ายืนยันว่าไม่มี consumer
QUAL-2WAYVTRC-02Mediumชื่อ package "express" version 1.0.0 ไม่ตรง repopackage.json:2-3เปลี่ยน name/version ให้ตรง
QUAL-2WAYVTRC-03MediumSwagger title/description ยังเป็น JSONPlaceholder tutorial; server URL localhost:8001app.ts:20-42เขียน metadata จริงของ 2way-vtrc-api
QUAL-2WAYVTRC-04MediumDockerfile EXPOSE 3000 แต่แอป listen 8001 และ compose map 8001:8001Dockerfile:13, app.ts:8, docker-compose.yml:11-12แก้ EXPOSE ให้ตรง 8001
LEG-2WAYVTRC-01Mediumรัน ts-node app.ts ใน production — ไม่มี compile step; ช้าและพลาด type error ตอน buildpackage.json:7เพิ่ม tsc แล้วรัน node dist/app.js
LEG-2WAYVTRC-02MediumDependencies ค้าง: mysql/mysql2 ทั้งที่ dialect เป็น mssql; request (deprecated); tslint คู่กับ eslintpackage.json:40-41,47,70ลบของที่ไม่ใช้; แทนที่ request
OBS-2WAYVTRC-01MediumSentry tracesSampleRate: 1.0 และ DSN hardcode — cost/noise สูง; สลับ env ยากapp.ts:53-67อ่าน DSN จาก env; ลด sample rate ใน production
OBS-2WAYVTRC-02MediumSentry errorHandler ลงทะเบียนก่อน route mounts — ต่างจากลำดับที่ Sentry แนะนำapp.ts:74-77 vs mounts ที่ 101+ย้าย errorHandler ไปหลัง routes; คง captureException ใน catch ที่จำเป็น

Auth surface matrix (สรุปเพื่อจัดลำดับแก้)

กลุ่ม endpointAuth จริงความเสี่ยงหลัก
ส่วนใหญ่ของ incident/feedback/survey/faqs/announcement (admin)checkBypassTokenMiddleWareถูกบายพาสด้วย "testnaja"
Line variants (*Line, *ByUserID, accept/read)checkBypassTokenLineMiddleWareถูกบายพาสด้วย "testnaja"
getProfile, getProfile/cuไม่มีPII leak
updateIncidentไม่มี (มีแค่ validator)แก้สถานะได้โดยไม่ต้อง login
SSO (loginSSO, verify OTP non-emp, …)ไม่มีบน route (login-style)credential SSO hardcode ในซอร์ส
Mock /2way/TwoWayAPI, /2way/MeetingAPIไม่มี / ไม่สำคัญข้อมูลปลอมหลอก consumer
WebHook LINELINE platform → webhookตรวจ signature แยก (ไล่เพิ่มถ้า audit webhook เต็ม)
Chat HTTPmount ปิด
Chat socketไม่มี auth ใน Socket.func ที่อ่านได้ใคร connect socket ได้ส่ง sendMessage

ลำดับ remediation ที่แนะนำ (จากความรุนแรง + ผลกระทบผู้ใช้)

  1. ลบ "testnaja" ทั้งสอง middleware (SEC-01 / 01b) และใส่ auth ให้ updateIncident (SEC-07)
  2. ปิด/แก้ getProfile + getProfile/cu (SEC-02 / 02b)
  3. Rotate และย้าย MSSQL / Mongo / SSO / JWT secrets ออกจากซอร์ส (SEC-03 / 03b / 08 / 04)
  4. ใส่ transaction ให้ createIncident (CORR-01)
  5. ตัดสินใจเรื่อง chat: เปิด Mongo หรือถอด socket (CORR-02)
  6. ถอด mock routers (QUAL-01)
  7. จัด Dockerfile port + ts-node → compiled JS (QUAL-04 / LEG-01)

สิ่งที่ตรวจแล้ว vs ยังไม่ตรวจ

ตรวจแล้วจากซอร์สบน branch prod:

  • entrypoint mounts ใน app.ts
  • middleware bypass ทั้งสองไฟล์
  • createIncident, getProfile, getProfile/cu, updateIncident, loginSSO
  • db.config.ts / env.ts / mongo.config.ts / jwt.config.ts
  • socket chat + comment mongo require
  • .env.prod keys (ไม่ยืนยันว่า runtime โหลดไฟล์นี้โดยตรง — boot อ่าน .env)

ยังไม่ตรวจในเอกสารชุดนี้:

  • ทุกบรรทัดใน routes/TwoWayAPI/index.ts (~1849 บรรทัด) ทีละ mock handler
  • webhook signature validation แบบครบทุก event type
  • ว่า frontend ตัวใดยังเรียก /2way/TwoWayAPI/* จริง
  • penetration test บน network ของ IP ใน env.ts

สรุปเชิงภาพรวม

2way-vtrc-api คือจุดที่มี debt ด้าน auth และ secret management หนาแน่นในกลุ่ม 2way Platform และเป็น backend ที่ฝั่งพนักงานพึ่งพาจริงมากกว่า 2way-api — ลำดับแก้ที่เร่งด่วนที่สุดคือ master bypass token, unauthenticated profile/PII, unauthenticated updateIncident, และ credential ที่ commit ในซอร์ส