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:
yueli
2026-07-16 11:26:05 +08:00
parent 128985af17
commit c07f25b646
8 changed files with 127 additions and 27 deletions

View File

@ -49,6 +49,8 @@ def scan_barcode():
try:
result = ScrapService.get_stock_by_barcode(barcode)
if result:
# ★ Fail-Closed: 扫码响应剥离价格字段
result.pop('price', None)
return jsonify({'code': 200, 'msg': '扫描成功', 'data': result})
else:
return jsonify({'code': 404, 'msg': '未找到对应的库存记录'}), 404
@ -124,6 +126,10 @@ def get_scrap_records():
start_date=start_date,
end_date=end_date
)
# ★ Fail-Closed: 报废记录剥离成本字段
for item in (result.get('list') or []):
for k in ('cost_at_scrap', 'total_loss'):
item.pop(k, None)
return jsonify({'code': 200, 'msg': 'success', 'data': result})
except Exception as e:
traceback.print_exc()