fix-security-correct-field-permission-mapping-and-403-denial

This commit is contained in:
DXC
2026-04-14 15:37:39 +08:00
parent ae05f3bb75
commit 477da7c434
4 changed files with 66 additions and 4 deletions

View File

@ -43,8 +43,8 @@ def filter_item_by_permissions(item_dict, user_permissions):
'sku': 'inbound_buy:sku', 'sku': 'inbound_buy:sku',
'barcode': 'inbound_buy:barcode', 'barcode': 'inbound_buy:barcode',
'in_date': 'inbound_buy:in_date', 'in_date': 'inbound_buy:in_date',
'serial_number': 'inbound_buy:serial_number', 'serial_number': 'inbound_buy:sn_bn',
'batch_number': 'inbound_buy:batch_number', 'batch_number': 'inbound_buy:sn_bn',
'status': 'inbound_buy:status', 'status': 'inbound_buy:status',
'in_quantity': 'inbound_buy:in_quantity', 'in_quantity': 'inbound_buy:in_quantity',
'stock_quantity': 'inbound_buy:stock_quantity', 'stock_quantity': 'inbound_buy:stock_quantity',

View File

@ -221,7 +221,11 @@ class MaterialBaseService:
req_company = filters.get('company') if filters else None req_company = filters.get('company') if filters else None
if user_role != 'SUPER_ADMIN': if user_role != 'SUPER_ADMIN':
# 普通用户:强制隔离!无视前端传的 company 参数 # 【显式拒绝越权】如果前端传了公司参数且不是当前用户的公司返回403
if req_company and req_company != user_company:
from flask import abort
abort(403, description=f'越权访问:您无权查询 {req_company} 的数据')
# 正常查询本公司数据
if user_company: if user_company:
query = query.filter(MaterialBase.company_name == user_company) query = query.filter(MaterialBase.company_name == user_company)
# 如果用户没有所属公司字段,则只显示公司为空的记录(或不允许查看) # 如果用户没有所属公司字段,则只显示公司为空的记录(或不允许查看)

View File

@ -356,7 +356,11 @@ class BuyInboundService:
user_company = claims.get('company_name', '') user_company = claims.get('company_name', '')
if user_role != 'SUPER_ADMIN': if user_role != 'SUPER_ADMIN':
# 普通用户:强制隔离!无视前端传的 company 参数 # 【显式拒绝越权】如果前端传了公司参数且不是当前用户的公司返回403
if company and company.strip() and company.strip() != user_company:
from flask import abort
abort(403, description=f'越权访问:您无权查询 {company} 的数据')
# 正常查询本公司数据
if user_company: if user_company:
query = query.filter(MaterialBase.company_name == user_company) query = query.filter(MaterialBase.company_name == user_company)
else: else:

54
query_permissions.py Normal file
View File

@ -0,0 +1,54 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import psycopg2
# 数据库连接配置 (从 docker-compose.yml 获取)
DB_CONFIG = {
'host': 'localhost',
'port': 5435,
'user': 'test',
'password': '1234',
'database': 'inventory_system'
}
def query_permissions():
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print('=' * 60)
print('查询: 角色为 PURCHASER 且 type=element 的所有权限记录')
print('=' * 60)
# 查询 PURCHASER 角色的元素权限
cursor.execute('''
SELECT role_code, target_code, type
FROM sys_role_permission
WHERE role_code = 'PURCHASER' AND type = 'element'
ORDER BY target_code
''')
rows = cursor.fetchall()
print(f'找到 {len(rows)} 条记录:\n')
for row in rows:
print(f' role_code: {row[0]}')
print(f' target_code: {row[1]}')
print(f' type: {row[2]}')
print('-' * 40)
# 如果没有结果,查询所有角色看看有什么
if not rows:
print('\n没有找到 PURCHASER 的记录,查询所有 element 权限...\n')
cursor.execute('''
SELECT DISTINCT role_code, type
FROM sys_role_permission
WHERE type = 'element'
ORDER BY role_code
''')
all_roles = cursor.fetchall()
print(f'数据库中有以下角色有 element 权限: {all_roles}')
conn.close()
if __name__ == '__main__':
query_permissions()