feat: 新增崗位描述與清單整合功能 v2.1

主要功能更新:
- 崗位描述保存功能:保存後資料寫入資料庫
- 崗位清單自動刷新:切換模組時自動載入最新資料
- 崗位清單檢視功能:點擊「檢視」按鈕載入對應描述
- 管理者頁面擴充:新增崗位資料管理與匯出功能
- CSV 批次匯入:支援崗位與職務資料批次匯入

後端 API 新增:
- Position Description CRUD APIs
- Position List Query & Export APIs
- CSV Template Download & Import APIs

文件更新:
- SDD.md 更新至版本 2.1
- README.md 更新功能說明與版本歷史

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-04 12:46:36 +08:00
parent d17af39bf4
commit b2584772c4
31 changed files with 6795 additions and 365 deletions

247
Check.md Normal file
View File

@@ -0,0 +1,247 @@
# HR Position Management System - 資安檢核報告
**專案名稱**: HR Position Management System
**檢核日期**: 2024-12-04
**版本**: v2.1
---
## 一、專案結構與依賴檢查
### 1. 入口檔案
- ✅ 有 `start_server.py` 作為主要入口檔案
- ✅ 有 `index.html` 作為前端入口
### 2. 專案結構
- ⚠️ 無明確的資料夾結構app、routes、static、templates 等)
- ❌ 所有檔案皆放在根目錄,缺乏模組化架構
- **建議**: 建立標準專案結構如 `/static``/templates``/routes``/config`
### 3. 依賴檔案
- ✅ 有 `requirements.txt`
- ❌ 無 `package.json`(前端無使用 Node.js 打包工具)
### 4. 使用框架
- ✅ 後端使用 **Flask** 框架
- ✅ 使用 **flask_cors** 處理跨域
- ✅ 使用 **python-dotenv** 讀取環境變數
### 5. README.md
- ✅ 有 `README.md` 檔案
- ✅ 包含安裝與啟動說明
- ✅ 包含 API 端點說明
### 6. 依賴套件安全性
- ⚠️ 未指定套件版本號碼,可能造成相容性問題
- **建議**: 在 requirements.txt 中指定明確版本號
### 7. 監聽位址與端口
- ⚠️ **start_server.py:286** - `app.run(host='0.0.0.0', port=5000, debug=True)`
-**host='0.0.0.0'** 會監聽所有網路介面,存在安全風險
-**debug=True** 在生產環境中不應開啟
- **建議**:
- 開發環境使用 `host='127.0.0.1'`
- 生產環境從環境變數讀取 host/port
- 移除或設定 `debug=False`
---
## 二、安全性與環境變數檢核
### 1. 環境變數檔案
- ✅ 存在 `.env` 檔案
- ❌ 無 `.env.example` 範本檔案供其他開發者參考
- **建議**: 建立 `.env.example`,內含變數名稱但無實際值
### 2. .gitignore 設定
- ✅ 有 `.gitignore` 檔案
- ✅ 排除 `.env`
- ✅ 排除 `__pycache__`
- ✅ 排除 `*.log`
- ✅ 排除 `node_modules`
- ✅ 排除備份檔案 `*.backup`
- ✅ 設定排除 `.gitignore` 本身
### 3. 資料庫連線設定
- ✅ 有 MySQL 資料庫設定DB_HOST、DB_PORT、DB_NAME、DB_USER、DB_PASSWORD
- ⚠️ 目前使用記憶體模擬資料庫,未實際連接 MySQL
### 4. 敏感資訊硬編碼檢查
-**嚴重問題** - `.env` 檔案中包含實際敏感資訊:
- `DB_PASSWORD=Bb123456` - 資料庫密碼
- `GITEA_PASSWORD=!QAZ2wsx` - Gitea 密碼
- `GITEA_TOKEN=9e0a888d1a25bde9cf2ad5dff2bb7ee6d68d6ff0` - Gitea Token
- `GEMINI_API_KEY=AIzaSy...` - Google API Key
-`SECRET_KEY=your_secret_key_here_change_in_production` - Flask 密鑰使用預設值
- **建議**:
1. 立即更換所有已洩露的密碼和 Token
2. 確保 `.env` 永不提交到版本控制
3. 使用環境變數或密鑰管理服務
### 5. SQL Injection / XSS 防護
- ⚠️ **SQL Injection**: 目前使用記憶體字典,未使用 ORM 或參數化查詢
- ⚠️ **XSS 防護**: 前端直接將 API 回傳資料插入 DOM存在潛在 XSS 風險
- **建議**:
1. 使用 SQLAlchemy ORM 進行資料庫操作
2. 前端使用 `textContent` 替代 `innerHTML`
3. 對使用者輸入進行驗證和消毒
### 6. 其他安全疑慮
-**CORS 設定過於寬鬆**: `CORS(app)` 允許所有來源
-**無身分驗證機制**: API 端點無需認證即可存取
-**無速率限制**: 未防範暴力攻擊或 DDoS
-**無 HTTPS**: 敏感資料可能以明文傳輸
-**無 CSRF 保護**: 表單未使用 CSRF Token
- **建議**:
1. 設定 CORS 允許的特定來源
2. 實作 JWT 或 Session 認證
3. 加入 rate limiting
4. 生產環境強制使用 HTTPS
5. 實作 CSRF 保護
---
## 三、程式品質與可維護性
### 1. 錯誤處理
-**start_server.py** 有 try/except 錯誤處理
- ✅ 有全域錯誤處理器 (`@app.errorhandler(404)`, `@app.errorhandler(500)`)
-**llm_config.py** 有完整的錯誤處理
- ⚠️ 前端錯誤處理可改進,部分情況直接使用 console.log
### 2. 程式碼品質
- ⚠️ 程式碼未遵循 PEP8 完整規範
- ⚠️ 缺少單元測試
- **建議**: 加入 pytest 單元測試
---
## 四、檢核結果總覽
| 類別 | 項目 | 狀態 |
|------|------|------|
| **專案結構** | 入口檔案 | ✅ |
| | 專案結構 | ⚠️ |
| | requirements.txt | ✅ |
| | 框架識別 | ✅ |
| | README.md | ✅ |
| | 依賴安全性 | ⚠️ |
| | 監聽位址 | ❌ |
| **安全性** | .env 檔案 | ✅ |
| | .gitignore | ✅ |
| | DB 連線設定 | ⚠️ |
| | 敏感資訊硬編碼 | ❌ |
| | SQL Injection 防護 | ⚠️ |
| | XSS 防護 | ⚠️ |
| | CORS 設定 | ❌ |
| | 身分驗證 | ❌ |
| | CSRF 保護 | ❌ |
| **程式品質** | 錯誤處理 | ✅ |
| | 程式碼品質 | ⚠️ |
---
## 五、評分
| 評分項目 | 滿分 | 得分 | 說明 |
|----------|------|------|------|
| 專案結構與依賴 | 20 | 14 | 缺乏模組化架構、監聽設定不安全 |
| 環境變數管理 | 15 | 10 | 有 .env 但包含實際敏感資訊 |
| .gitignore 設定 | 10 | 10 | 設定完整 |
| 資料庫安全 | 15 | 8 | 未使用 ORM、無參數化查詢 |
| API 安全性 | 20 | 5 | 無認證、CORS 過寬、無速率限制 |
| XSS/CSRF 防護 | 10 | 4 | 缺乏完整防護 |
| 錯誤處理 | 10 | 8 | 大致完整,前端可改進 |
### **總分: 59 / 100**
---
## 六、修改建議優先順序
### 🔴 高優先(立即處理)
1. **更換所有已洩露的憑證**
- 更換 DB_PASSWORD
- 更換 GITEA_PASSWORD 和 GITEA_TOKEN
- 重新產生 GEMINI_API_KEY
- 設定強度足夠的 SECRET_KEY
2. **修改伺服器監聽設定**
```python
# start_server.py
if __name__ == '__main__':
host = os.getenv('FLASK_HOST', '127.0.0.1')
port = int(os.getenv('FLASK_PORT', 5000))
debug = os.getenv('FLASK_DEBUG', 'false').lower() == 'true'
app.run(host=host, port=port, debug=debug)
```
3. **建立 .env.example**
```env
DB_HOST=your_db_host
DB_PORT=3306
DB_NAME=your_db_name
DB_USER=your_db_user
DB_PASSWORD=your_db_password
GEMINI_API_KEY=your_api_key
SECRET_KEY=generate_a_secure_random_key
```
### 🟡 中優先(儘快處理)
4. **限制 CORS 來源**
```python
CORS(app, origins=['http://localhost:5000', 'https://your-domain.com'])
```
5. **實作基本身分驗證**
- 使用 Flask-Login 或 JWT
- 保護敏感 API 端點
6. **使用 ORM 防止 SQL Injection**
```python
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
```
### 🟢 低優先(計畫性改進)
7. **建立標準專案結構**
```
hr-position-system/
├── app/
│ ├── __init__.py
│ ├── routes/
│ ├── models/
│ └── utils/
├── static/
├── templates/
├── config.py
└── run.py
```
8. **加入單元測試**
9. **實作 CSRF 保護**
```python
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
```
10. **加入速率限制**
```python
from flask_limiter import Limiter
limiter = Limiter(app, key_func=get_remote_address)
```
---
## 七、結論
此專案目前處於**開發階段**,具備基本功能但存在多項安全隱患。**最緊急的問題是敏感資訊外洩風險**,需立即處理。建議在部署到生產環境前,完成所有高優先和中優先的修改項目。
---
**檢核人員**: Claude Code
**檢核日期**: 2024-12-04