fix: 修复2个支付安全漏洞-未经认证的payment_success确认+未禁用mock_confirm
This commit is contained in:
@@ -910,16 +910,13 @@ fn format_error_html(msg: &str, order_no: &str) -> String {
|
||||
|
||||
#[get("/payment/success")]
|
||||
pub async fn payment_success(
|
||||
pool: web::Data<PgPool>,
|
||||
_pool: web::Data<PgPool>,
|
||||
query: web::Query<AlipaySuccessQuery>,
|
||||
) -> HttpResponse {
|
||||
let order_no = query.order_no.as_deref().unwrap_or("");
|
||||
|
||||
// 同步确认订单(幂等:已确认的订单会跳过)
|
||||
if !order_no.is_empty()
|
||||
&& let Err(e) = db::confirm_payment_order_by_orderno(pool.get_ref(), order_no).await {
|
||||
tracing::warn!("支付成功页同步确认失败(可能是异步回调已处理): {}", e);
|
||||
}
|
||||
// 不再在此处确认订单(安全原因: 此端点无认证, 任何人知道 order_no 即可激活会员)。
|
||||
// Mock 支付由 mock_confirm 在跳转前确认, 真实支付宝由 notify 异步回调确认。
|
||||
|
||||
let html = build_success_html(order_no);
|
||||
HttpResponse::Ok()
|
||||
@@ -1028,6 +1025,7 @@ pub async fn create_order(
|
||||
}
|
||||
|
||||
/// POST /api/payment/mock-confirm
|
||||
/// 仅在未配置支付宝时可用(否则用户可绕过真实支付)
|
||||
#[post("/api/payment/mock-confirm")]
|
||||
pub async fn mock_confirm(
|
||||
pool: web::Data<PgPool>,
|
||||
@@ -1035,8 +1033,13 @@ pub async fn mock_confirm(
|
||||
body: web::Json<MockConfirmRequest>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
check_payment_maintenance()?;
|
||||
let user_id = claims.user_id;
|
||||
|
||||
// 安全守卫:已配置支付宝时禁用 Mock 支付,防止绕过
|
||||
if AlipayConfig::from_env().is_some() {
|
||||
return Err(AppError::BadRequest("真实支付已启用,Mock 支付不可用".to_string()));
|
||||
}
|
||||
|
||||
let user_id = claims.user_id;
|
||||
let expires_at =
|
||||
db::confirm_payment_order(pool.get_ref(), &body.order_id, user_id).await?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user