fix(security): 修复网安扫描相关严重/高危/中危漏洞并加固学生密码重置

关闭工作流 SpEL 命令执行与社团活动 SQL 注入,补齐越权、调试接口、登录喷洒和异常回显等问题;学生密码改为随机临时密码,Web/移动端支持复制。

Constraint: 流程发起/办理接口保持仅登录校验,避免影响请假审批
Rejected: 开启验证码 | Web/移动端登录页均未实现,开启会导致无法登录
Confidence: high
Scope-risk: broad
Not-tested: 生产环境与社团社长/指导老师视角
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
“wuzhen”andCursor committed 2026-10-26 13:44:51 +08:00
1 parent 845c7fd942
commit da8d332fac
79 files changed
+1156 -547

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ export const queryStudentForPwdReset = (studentNo) => {
};
/**
* 按学号重置学生登录密码为固定默认值
* 按学号重置学生登录密码为随机临时密码,data 为临时密码
* @param {string} studentNo 学号
*/
export const resetStudentPassword = (studentNo) => {
@@ -103,6 +103,36 @@ export default {
this.queryLoading = false;
}
},
copyPassword(pwd) {
if (!pwd) {
uni.showToast({ title: '没有可复制的密码', icon: 'none' });
return;
}
uni.setClipboardData({
data: pwd,
success: () => {
uni.showToast({ title: '密码已复制', icon: 'success' });
},
fail: () => {
uni.showToast({ title: '复制失败,请手动复制', icon: 'none' });
}
});
},
showResetResult(tempPwd) {
uni.showModal({
title: '密码已重置',
content: `临时密码:${tempPwd}\n请告知学生登录后立即修改密码,此密码仅显示一次。`,
showCancel: true,
cancelText: '复制密码',
confirmText: '我已记录',
success: (modalRes) => {
if (modalRes.cancel) {
this.copyPassword(tempPwd);
this.showResetResult(tempPwd);
}
}
});
},
handleReset() {
if (!this.student || !this.student.studentNo) {
uni.showToast({ title: '请先查询学生', icon: 'none' });
@@ -112,7 +142,7 @@ export default {
const no = this.student.studentNo;
uni.showModal({
title: '重置密码确认',
content: `确认将学号「${no}」(${name})的登录密码重置为系统默认密码?`,
content: `确认将学号「${no}」(${name})的登录密码重置为随机临时密码?重置后该学生需重新登录。`,
confirmText: '确定',
cancelText: '取消',
success: async (modalRes) => {
@@ -121,8 +151,8 @@ export default {
}
this.resetLoading = true;
try {
await resetStudentPassword(no);
uni.showToast({ title: '密码已重置为默认密码', icon: 'success' });
const res = await resetStudentPassword(no);
this.showResetResult(String((res && res.data) || ''));
} catch (e) {
// 错误提示由 request 拦截器处理
} finally {