fix: Fail-Closed 字段级安全加固 — 堵住15+端点价格泄露
## stock.py
- _make_price_stripper(): 工厂函数,选单前缀自动剥离所有价格/成本字段
- _do_get_stock_list(permission_prefix): 每个item.to_dict()后剥离价格
- /all 端点: 非AI模式自动剥离价格字段
- /list 端点: permission_prefix='outbound_selection' 传递
## outbound.py
- /bom-match-stock: 返回前按stock_type剥离全部价格/成本字段
- /scan: result.pop('price', None)
## scrap.py
- /scan: result.pop('price', None)
- /records: 每条记录剥离 cost_at_scrap, total_loss
## transactions.py
- filter_item_by_permissions: 从空字典恢复完整20字段映射
- /borrow/stock-list: permission_prefix='op_borrow_apply' 传递
## buy.py / semi.py / product.py
- submit 成功响应剥离所有价格/成本字段(不泄露给前端)
## bom.py
- /base/list: 剥离 referencePrice
This commit is contained in:
@ -86,6 +86,8 @@ def scan_barcode():
|
||||
result = OutboundService.get_stock_by_barcode(barcode)
|
||||
|
||||
if result:
|
||||
# ★ Fail-Closed: 扫码响应剥离价格字段
|
||||
result.pop('price', None)
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'msg': '扫描成功',
|
||||
@ -279,6 +281,22 @@ def bom_match_stock():
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# ★ Fail-Closed: 剥离所有价格成本字段(BOM 匹配用于出库选单,无需价格)
|
||||
for d in all_items:
|
||||
stype = d.get('stock_type', '')
|
||||
if stype == 'material':
|
||||
for k in ('unit_price', 'post_tax_unit_price', 'total_price',
|
||||
'tax_rate', 'currency', 'exchange_rate'):
|
||||
d.pop(k, None)
|
||||
elif stype == 'semi':
|
||||
for k in ('raw_material_cost', 'manual_cost', 'unit_total_cost',
|
||||
'total_price', 'unit_price'):
|
||||
d.pop(k, None)
|
||||
elif stype == 'product':
|
||||
for k in ('raw_material_cost', 'manual_cost', 'unit_total_cost',
|
||||
'sale_price', 'unit_price'):
|
||||
d.pop(k, None)
|
||||
|
||||
return jsonify({'code': 200, 'msg': 'success', 'data': {'items': all_items}})
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user