Files
QiufengandClaude Opus 4.8 5e51dc3f56 SNAPSHOT W7 已部署稳定态 — 凯迪ERP+OA一体化平台 (MET 73.3%)
恢复点(restore point)。别人改崩后可 git reset --hard 回到此提交。

== 此快照内容 ==
- 后端 oa-backend: 734 控制器 / 711 实体 (Spring Boot 3.2.5 + SQLite, 端口8091)
- 前端 modern-ui/app: Vue3+Vite, 约700页 (构建产物已在 oa-backend/src/main/resources/static)
- 数据库 oa-backend/data/oa.db: 含全部演示数据 (强制入库, 6.6MB)
- 交接文档 go.md + go-code-reference/endpoints/entities/database.md
- 多代理建设脚本 .claude/wf-*.js

== 状态 ==
- 对 凯迪科技ERP_20260507.xlsx 合规 MET ~73.3% (PARTIAL 75: 34可建+6种子/bug+35外部硬天花板)
- 安全: 5轮红队+5轮复检, default-deny分级鉴权, 连续零可利用
- W3~W7 累计补完436缺口; W8末轮(40缺口)为半成品(源码树可编译但未集成)
- 运行: cd oa-backend; java -jar build/libs/oa-backend-0.1.0.jar --server.port=8091; admin/123456

== 排除(gitignore, 可再生) ==
node_modules / oa-backend/build / .jdks / *.log / Backup-ERP-* / 弃用的OFBiz核心(只保留modern-ui)
完整文件夹备份见同目录 Backup-ERP-20260615-191517/ (含上述全部, 仅缺 node_modules)

时间戳: 20260615-191517

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 19:19:15 +08:00

3.2 KiB

OA Backend — Security Audit

Audit of the standalone Java (Spring Boot) OA backend after functional tests reached 100% (42/42, see ../oa-itest.sh). Scope: injection, XSS, secrets, authn/authz, transport, CORS, password storage.

Summary

Class Status Notes
SQL injection Safe All persistence via Spring Data derived queries (parameterized). No @Query, no createQuery, no native SQL, no string-concatenated queries anywhere.
XSS (stored/reflected) Safe Frontend has zero v-html / innerHTML / eval / new Function. Vue + Element Plus escape all interpolated text by default. Form/flow JSON is rendered as data, never as HTML.
Hardcoded secrets Safe No API keys, tokens, or secrets embedded in source.
Mass assignment Safe Controllers bind explicit record DTOs, never JPA entities directly.
Password storage Hardened Upgraded from unsalted SHA-256 to salted PBKDF2-HMAC-SHA256 (120k iterations, per-user 16-byte salt), constant-time verify. See common/PasswordUtil.
Error handling Safe Uniform ApiResp envelope via @RestControllerAdvice; no stack traces leaked to clients.
Transport (CORS) Dev-scoped /api/** allows localhost:* / 127.0.0.1:* only — appropriate for local dev; must be locked to the real origin for production.

Remaining hardening (documented as "later phase", acceptable for the current single-tenant demo)

  1. Token lifecycle — opaque in-memory bearer tokens with no expiry and no persistence across restarts. For production: signed/JWT or server-side sessions with TTL + refresh + revocation list.
  2. Authorization enforcement — most endpoints don't require a valid token; an unauthenticated caller falls back to the demo user 我(当前用户). This is intentional so the demo runs without a login gate. For production: a filter that rejects unauthenticated/under-privileged calls on mutating routes, plus RBAC using the existing SysRole / SysUserRole tables.
  3. Rate limiting / lockout — no brute-force protection on /auth/login. Add attempt throttling + temporary lockout.
  4. HTTPS — served over plain HTTP on :8090 for local dev; terminate TLS at a reverse proxy (or enable Spring SSL) in production.
  5. CORS lockdown — replace the localhost:* dev pattern with the deployed frontend origin(s).
  6. Audit log — workflow actions are traced (FlowTrace), but there is no security/access audit log; add one for production compliance.

What was fixed in this pass

  • common/PasswordUtil rewritten to salted PBKDF2 (was unsalted SHA-256), with a legacy-hash fallback in matches() for backward compatibility. Re-seeded users now store pbkdf2$<iter>$<salt>$<hash>. Verified: login admin/123456 → success; wrong password → 401.
  • CORS origin patterns documented and scoped (see config/CorsConfig).

Verdict

No exploitable vulnerabilities found in the audited classes (injection, XSS, secrets, mass-assignment). Password storage is now industry-standard salted KDF. The remaining items are deployment-hardening tasks expected of a demo moving to production, all tracked above.