2way-line-service — Scorecard
Legend:
- Critical = active security/data-loss/availability risk
- High = correctness/maintainability hazard, real impact
- Medium = friction/hygiene, ยังไม่เป็นอันตรายระดับ production-breaking ทันที
2way-line-service (branch: master, 52 tracked files) เป็น thin gateway ไป LINE — business logic น้อย แต่เปิด HTTP surface ทั้งก้อนแบบไม่ยืนยันตัวตน และมี contract ไม่ตรงกับ caller ใน 2way-api
อย่าคัดลอกค่า secret / password / LINE token จริงลงเอกสาร — อ้างชื่อตัวแปรและ file:line
Score summary
| Severity | จำนวน |
|---|---|
| Critical | 1 |
| High | 3 |
| Medium | 5 |
Findings
| ID | Severity | คำอธิบาย | หลักฐาน (file:line) | การแก้ไข |
|---|---|---|---|---|
| SEC-2WAYLINE-01 | Critical | ทุก endpoint ของ LineController เป็น @Public() — ใครก็ push/multicast หรือสลับ rich menu ของ userId ใดก็ได้ถ้ารู้ URL | src/modules/line/line.controller.ts:13,19,25,31 | ใส่ service-to-service auth (shared secret / mTLS / allowlist network) แล้วเอา @Public() ออกจาก mutation |
| SEC-2WAYLINE-02 | High | .env.example และ lineText.text มีค่าที่ดูเหมือน secret จริง (SECRET_KEY, LINE_AUTH_TOKEN, DB_PASSWORD) commit ใน git | .env.example:9-12,17-18; lineText.text:4 | rotate token ทั้งหมด; แทนที่ example ด้วย placeholder; ลบ token ออกจาก scratch files |
| CORR-2WAYLINE-01 | High | Caller 2way-api ยิง path /api/v1/line/... (ตัวเล็ก) และส่ง richMenuId / ไม่ส่ง isChula — callee ใช้ /Line + hardcode menu จาก isChula | 2way-api/.../line.service.ts:72-86 (branch: prod); line.controller.ts:9; line.service.ts:78-86; dto/line.dto.ts:24-32 | ทำให้ path + DTO ตรงกันทั้งสองฝั่ง; ย้าย rich menu id ไป config |
| SEC-2WAYLINE-03 | High | 2way-api เรียก service นี้ผ่าน hardcoded IP 20.212.116.206:8200 ไม่มี TLS ใน URL | 2way-api/.../line.service.ts:76,86 | ใช้ internal DNS + TLS; อย่า commit IP |
| QUAL-2WAYLINE-01 | Medium | dependency TypeORM/MSSQL + entities/DTOs ค้าง แต่ AppModule ไม่มี TypeORM | app.module.ts:9-19; package.json:33,39,46 | ลบ dependency และไฟล์ที่ไม่ได้ใช้ |
| QUAL-2WAYLINE-02 | Medium | CENTRALIZE_SERVER ใน .env.example ไม่ถูกอ้างในซอร์ส | .env.example:16 | ลบตัวแปรที่ไม่ได้ใช้ |
| QUAL-2WAYLINE-03 | Medium | scratch files endpoint.txt, lineText.text commit ใน root | root ของ repo | ย้ายออกจาก repo โค้ด |
| LEG-2WAYLINE-01 | Medium | Dockerfile / runtime node:16-alpine (EOL) | Dockerfile:1,15 | อัปเกรด Node 18/20 LTS |
| QUAL-2WAYLINE-04 | Medium | Dockerfile EXPOSE 3000 แต่ compose/env/swagger ใช้ 8200 | Dockerfile:24; docker-compose.yml:8-9; .env.example:5; docs/document.config.ts:8 | ให้พอร์ตตรงกัน |
สิ่งที่ตรวจแล้ว vs ยังไม่ตรวจ
ตรวจแล้ว (branch master):
AppModule,main.ts,LineModule/ controller / service ทั้งไฟล์dto/line.dto.ts,configuration.ts,.env.example(ชื่อตัวแปร)Dockerfile,docker-compose.yml- เปรียบเทียบ caller ใน
2way-api(branch prod) สำหรับ next/previous - ไม่พบการใช้
CENTRALIZE_SERVERใน*.ts - ไม่มี TypeORM wiring
ยังไม่ตรวจ:
- ว่า production ยังชี้
20.212.116.206:8200อยู่หรือไม่ - พฤติกรรม path case บน reverse proxy จริง
- ว่า rich menu id ในโค้ดยัง active บน LINE OA หรือไม่
- ค่า secret จริงใน deployment (ต้อง rotate แยกจากเอกสาร)
สรุปเชิงภาพรวม
2way-line-service มีหน้าที่ชัดและโค้ดสั้น แต่เป็นจุดอ่อนด้าน auth ของกลุ่ม 2way — endpoint สาธารณะที่ควบคุม LINE push และ rich menu ได้โดยตรง รวมกับ hardcode IP จาก 2way-api และ DTO/path ที่ไม่ตรงกัน ควรปิด public surface และทำให้สัญญาเรียกระหว่าง service ตรงก่อนขยายฟีเจอร์