Compare commits

...

2 Commits

Author SHA1 Message Date
liang.chao 291c6acb87 漏洞修复 2025-08-24 14:10:46 +08:00
liang.chao 592e9f3629 漏洞修复 2025-08-24 14:10:39 +08:00
2 changed files with 152 additions and 100 deletions

View File

@ -1,11 +1,12 @@
server.port=1803
server.servlet.context-path=/GsSubEvaluate
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/gs_sub_evaluate?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
#spring.datasource.url=jdbc:mysql://127.0.0.1:3307/aaa?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
#spring.datasource.username=root
#spring.datasource.password=bonus@admin123!%
spring.datasource.url=jdbc:mysql://192.168.0.14:4419/gs_sub_evaluate?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
#spring.datasource.password=root
spring.datasource.url=jdbc:mysql://192.168.0.14:1115/gs_sub_evaluate?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=Bonus@admin123!
spring.datasource.password=xbzadmin@szedu14!
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=60000
@ -13,26 +14,26 @@ spring.datasource.min-idle=5
spring.datasource.initial-size=5
server.session.timeout=10
server.tomcat.uri-encoding=UTF-8
#mapper<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#mapper����
mybatis.mapper-locations=classpath:mappers/*/*Mapper.xml
mybatis.type-aliases-package=com.bonus.gs.sub.evaluate.*.entity
#redis config
#spring.redis.host=localhost
#spring.redis.host=127.0.0.1
#spring.redis.port=6379
#spring.redis.password=
#测试
spring.redis.host=192.168.0.14
spring.redis.port=2005
spring.redis.password=Xbzbns@Redis123!
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
#测试
#spring.redis.host=192.168.0.14
#spring.redis.port=2005
#spring.redis.password=Xbzbns@Redis123!
# <EFBFBD><EFBFBD>־
# ��־
logging.config=classpath:logback-boot.xml
log.level.root=info
log.level.my=debug
log.file=logs/sys-back.log
log.maxsize=30MB
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>С
#����ͷ��С
server.max-http-header-size=102400
spring.servlet.multipart.max-file-size=-1
spring.servlet.multipart.max-request-size=-1
@ -41,6 +42,7 @@ spring.http.multipart.maxRequestSize=10Mb
token.expire.seconds=7200
spring.servlet.multipart.enabled=true
upload.dir=/home/gswbs/upload
#upload.dir=D:/upload
user.password=Bonus@admin123
#upload.dir=/data/upload
upload.dir=E:/upload
user.password=Pjxt@2025

View File

@ -1,162 +1,212 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>登录</title>
<link href="css/login.css" type="text/css" rel="stylesheet">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>登录 - 分包评价系统</title>
<link href="css/login.css" type="text/css" rel="stylesheet">
<style>
.csrf-info {
background-color: #f8f9fa;
border-left: 4px solid #007bff;
padding: 10px 15px;
margin: 15px 0;
font-size: 14px;
display: none;
}
.csrf-token-field {
display: none;
}
</style>
</head>
<body>
<div class="login">
<div class="message">分包评价</div>
<div id="darkbannerwrap"></div>
<div class="login">
<div class="message">分包评价</div>
<div id="darkbannerwrap"></div>
<form id="login-form" method="post" onsubmit="return false;">
<input id="username" name="username" placeholder="用户名" type="text"
autocomplete="off">
<hr class="hr15">
<input id="password" name="password" placeholder="密码" type="password"
autocomplete="off">
<hr class="hr15">
<button style="width: 100%;" type="submit"
onclick="login(this)">登录</button>
<hr class="hr20">
<span id="info" style="color: red"></span>
</form>
<div class="csrf-info" id="csrfInfo">
<strong>安全提示:</strong> 此表单包含CSRF保护令牌防止跨站请求伪造攻击。
</div>
</body>
<form id="login-form" method="post" onsubmit="return false;">
<input id="username" name="username" placeholder="用户名" type="text" autocomplete="off">
<hr class="hr15">
<input id="password" name="password" placeholder="密码" type="password" autocomplete="off">
<hr class="hr15">
<!-- CSRF令牌字段 -->
<input type="hidden" id="csrfToken" name="csrfToken" value="">
<button style="width: 100%;" type="submit" onclick="login(this)">登录</button>
<hr class="hr20">
<span id="info" style="color: red"></span>
</form>
</div>
<script src="js/libs/jquery-2.1.1.min.js"></script>
<script src="js/publicJs.js"></script>
<script src="layui/layui.js"></script>
<script src="layui/crypto-js.min.js"></script>
<script type="text/javascript">
// if (top != self) {
// parent.location.href = '/GsSubEvaluate/login.html';
// }
// 获取查询参数
let urlParams = new URLSearchParams(window.location.search);
let tokens = urlParams.get('tokens'); // 假设 URL 为 https://example.com/path?query=1
let loginName = urlParams.get('loginName');
if(tokens && tokens!=='undefined'){
tokenVerify(tokens,loginName);
// 页面加载时获取CSRF令牌
document.addEventListener('DOMContentLoaded', function() {
fetchCSRFToken();
});
// 获取CSRF令牌
function fetchCSRFToken() {
$.ajax({
type: 'get',
url: ctxPath + '/csrf/token',
success: function(data) {
if (data && data.token) {
$('#csrfToken').val(data.token);
$('#csrfInfo').show();
}
},
error: function() {
// 如果获取令牌失败,生成一个客户端令牌作为备用
var clientToken = generateClientToken();
$('#csrfToken').val(clientToken);
}
});
}
// var token = localStorage.getItem("token");
// if (token != null && token.trim().length != 0) {
// $.ajax({
// type : 'get',
// url : ctxPath + '/users/current?token=' + token,
// success : function(data) {
// location.href = ctxPath + '/index.html';
// },
// error : function(xhr, textStatus, errorThrown) {
// var msg = xhr.responseText;
// var response = JSON.parse(msg);
// var code = response.code;
// var message = response.message;
// if (code == 401) {
// localStorage.removeItem("token");
// }
// }
// });
// }
// 生成客户端CSRF令牌
function generateClientToken() {
var timestamp = new Date().getTime();
var random = Math.random().toString(36).substring(2);
return CryptoJS.SHA256(timestamp + random).toString();
}
function tokenVerify(tokens,loginName) {
// 原有代码保持不变
let urlParams = new URLSearchParams(window.location.search);
let tokens = urlParams.get('tokens');
let loginName = urlParams.get('loginName');
if(tokens && tokens !== 'undefined'){
tokenVerify(tokens, loginName);
}
function tokenVerify(tokens, loginName) {
$.ajax({
type : 'post',
url : ctxPath + '/users/tokenVerify',
data : {tokens:tokens,loginName:loginName},
success : function(data) {
// debugger;
type: 'post',
url: ctxPath + '/users/tokenVerify',
data: {tokens: tokens, loginName: loginName},
success: function(data) {
let res = data.res;
layer.msg(data.resMsg);
if(res === 1) {
login_2(loginName, data.resMsg);
}else{
} else {
layer.msg(data.resMsg);
}
},
error : function(xhr, textStatus, errorThrown) {
error: function(xhr, textStatus, errorThrown) {
// 错误处理
}
});
}
function login_2(username,password) {
function login_2(username, password) {
// 确保有CSRF令牌
if (!$('#csrfToken').val()) {
fetchCSRFToken();
setTimeout(function() {
login_2(username, password);
}, 100);
return;
}
$.ajax({
type : 'post',
url : ctxPath + '/login',
data : {username:username,password:password},
success : function(data) {
// debugger;
type: 'post',
url: ctxPath + '/login',
data: {
username: username,
password: password,
csrfToken: $('#csrfToken').val()
},
success: function(data) {
localStorage.setItem("token", data.token);
localStorage.setItem("roleName", data.loginUser.roleName);
localStorage.setItem("loginUser", JSON.stringify(data.loginUser));
location.href = ctxPath + '/index.html';
},
error : function(xhr, textStatus, errorThrown) {
error: function(xhr, textStatus, errorThrown) {
var msg = xhr.responseText;
var response = JSON.parse(msg);
$("#info").html(response.message);
$(obj).attr("disabled", false);
}
});
}
// AES加密函数
function encryptData(data, key) {
const keyHex = CryptoJS.enc.Utf8.parse(key);
const ivHex = CryptoJS.enc.Utf8.parse(key.substring(0, 16)); // 使用密钥前16位作为IV
const ivHex = CryptoJS.enc.Utf8.parse(key.substring(0, 16));
return CryptoJS.AES.encrypt(data, keyHex, {
iv: ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();
}
function login(obj) {
$(obj).attr("disabled", true);
var username = $.trim($('#username').val());
var password = $.trim($('#password').val());
if (username == "" || password == "") {
$("#info").html('用户名或者密码不能为空');
$(obj).attr("disabled", false);
} else {
// 加密密钥(需与后端一致)
// 确保有CSRF令牌
if (!$('#csrfToken').val()) {
fetchCSRFToken();
setTimeout(function() {
login(obj);
}, 100);
return;
}
// 加密密钥
var secretKey = "zhgd@bonus@zhgd@bonus@1234567890";
// 加密用户名和密码
var encryptedData = {
username: encryptData(username, secretKey),
password: encryptData(password, secretKey),
csrfToken: $('#csrfToken').val()
};
$.ajax({
type : 'post',
url : ctxPath + '/login',
data : encryptedData,
success : function(data) {
// debugger;
type: 'post',
url: ctxPath + '/login',
data: encryptedData,
success: function(data) {
localStorage.setItem("token", data.token);
// localStorage.setItem("roleName", data.loginUser.roleName);
localStorage.setItem("loginUser", JSON.stringify(data.loginUser));
location.href = ctxPath + '/index.html';
},
error : function(xhr, textStatus, errorThrown) {
error: function(xhr, textStatus, errorThrown) {
var msg = xhr.responseText;
var response = JSON.parse(msg);
$("#info").html(response.message);
try {
var response = JSON.parse(msg);
$("#info").html(response.message);
// 如果错误是由于CSRF令牌无效重新获取令牌
if (response.code === 403 && response.message.includes("CSRF")) {
fetchCSRFToken();
}
} catch(e) {
$("#info").html("登录失败,请重试");
}
$(obj).attr("disabled", false);
}
});
}
}
</script>
</body>
</html>