You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

方法安全防护的最佳实践是什么?是否所有方法都需做输入校验?

方法安全防护最佳实践问题解答

核心结论是不需要所有方法都做全量防护,是否要给insert加空列表校验,取决于你这个方法的公开范围和团队约定:

两种适配场景的选择

  • 如果Service类属于当前业务模块私有组件,且团队有明确约定insert方法仅能由Endpoint的create方法调用,完全可以保留现有写法,但需要补充两个前置保障:
    1. 在insert方法的注释里明确标注前置约束:调用方必须保证传入的List非空,空列表调用会抛出未捕获异常
    2. 有条件的话优先用类型系统替代运行时校验,比如把参数类型从List[Item]改成NonEmptyList[Item],从编译层面就杜绝空列表传入的可能,既没有多余的样板代码,也避免后续有人误调用。
  • 如果Service是公共基础组件、后续会开放给其他业务模块调用、或者团队人员流动性大没有强约束,必须加校验。你现在省了几行校验代码,后续其他人不知道要做前置校验直接传空列表,出故障的排查和修复成本远高于你写校验的成本,属于典型的捡芝麻丢西瓜。

关于样板代码冗余的顾虑

  • 边界层(比如你示例里的Endpoint,属于对外暴露的请求入口)必须做全量的输入合法性校验,内部方法可以靠信任链传递校验结果,不用重复做相同的校验逻辑,避免样板代码爆炸。
  • 注意区分安全防护和普通参数校验:涉及权限校验、防注入、防数据篡改这类安全规则,不管是哪层的方法都要做;普通的参数格式、非空这类校验,只要在最外层做一次即可,内部靠约定或者类型约束保障。

针对你给出的示例的具体建议

// 最优方案:用类型约束从编译层解决问题,不需要重复校验
class Endpoint {
  def create(list: List[Item]): Response = 
    list match {
      case Nil => BadRequest("Empty list")
      case nonEmptyList: NonEmptyList[Item] => service.insert(nonEmptyList)
    }
}

class Service {
  // 参数是NonEmptyList,编译层面就不允许空列表传入
  def insert(list: NonEmptyList[Item]) = list.head
  ...
}

如果不方便改参数类型,要么给insert方法加1行校验抛出明确的业务异常,比默认的集合空访问异常更容易排查问题:

def insert(list: List[Item]) = {
  if(list.isEmpty) throw new IllegalArgumentException("insert method requires non-empty list")
  list.head
}

要么就把insert方法改成模块私有,从访问权限上限制调用方,避免无关人员误调用。

内容的提问来源于stack exchange,提问作者Veidt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 06:24:03