如何修复 java 中的批量分配:不安全的活页夹配置(API 滥用,结构)
How to fix Mass Assignment: Insecure Binder Configuration (API Abuse, Structural) in java
我有一个 Controller class,它具有以下两种寻找医生的方法(上下文已更改)。获取
批量分配:不安全的活页夹配置(API 滥用,结构) 两种方法都出错。
@Controller
@RequestMapping(value = "/findDocSearch")
public class Controller {
@Autowired
private IFindDocService findDocService;
@RequestMapping(value = "/byName", method = RequestMethod.GET)
@ResponseBody
public List<FindDocDTO> findDocByName(FindDocBean bean) {
return findDocService.retrieveDocByName(bean.getName());
}
@RequestMapping(value = "/byLoc", method = RequestMethod.GET)
@ResponseBody
public List<FindDocDTO> findDocByLocation(FindDocBean bean) {
return findDocService.retrieveDocByZipCode(bean.getZipcode(),
bean.getDistance());
}
}
我的 Bean 是:
public class FindDocBean implements Serializable {
private static final long serialVersionUID = -1212xxxL;
private String name;
private String zipcode;
private int distance;
@Override
public String toString() {
return String.format("FindDocBean[name: %s, zipcode:%s, distance:%s]",
name, zipcode, distance);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
根据目前发现的所有建议,他们建议仅通过以下方式限制具有所需参数的 bean:
final String[] DISALLOWED_FIELDS = new String[]{"bean.name", "bean.zipcode", };
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(DISALLOWED_FIELDS);
但我的问题是 bean 的所有 3 个参数都将用在 Controller 上提供的任一方法中。
有人可以为此提出一些解决方案吗?提前致谢。
简单的问题 - 您的映射器如何实例化 bean? Here 是答案/例子。您可以通过 query parameter
或 header
传递该数据。但是,那会很奇怪。更好的方法是使用 @QueryParam
提供位置或名称的方法。这样会更容易保护您的应用程序。
附带说明一下,查询的长度有限,因此如果您的搜索表单又大又奇怪,@POST
可能是个好主意,这样您就可以传递所有数据。为此,简单的例子会有点矫枉过正。
这看起来像是一个不幸的误报。此错误背后的规则是为了避免对象中存在但不打算作为(未验证的)用户输入的属性 意外地 从 Web 请求中填充。例如 POST 请求创建资源。如果请求处理程序采用完整的资源对象并仅填充缺失的属性,则恶意用户可以填充她不应该能够编辑的字段。
然而,这种情况与方案不符。您只需使用相同的机制来捕获您的不同论点。甚至不会读取额外填充的属性。在
GET http://yourhost/findDocSearch/byName?name=Abuse&zipCode=11111
额外的邮政编码将被忽略。因此这里不存在假定的风险。
要修复 警告,您可以将其标记为误报(如果这在您的设置中可行)。如果那不可能,您也可以直接将查询参数映射到方法参数。由于您只有有限的参数,因此不会造成太大伤害。如果这也不是一个选项,您可能需要找出您的代码分析用来确定它将识别哪些检查的确切算法。不幸的是,大多数扫描器只能发现一组有限的输入验证方法。
InitBinder 可用于方法。你可以试试这个。
@InitBinder("findDocByName")
public void initBinderByName(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","zipcode"});
}
@InitBinder("findDocByLocation")
public void initBinderByZipCode(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","name"});
}
我遇到了同样的问题,然后我在同一个休息控制器中添加了下面的代码class:
@InitBinder
public void populateCustomerRequest(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{});
}
现在它对我来说工作正常,批量分配问题已解决。
我有一个 Controller class,它具有以下两种寻找医生的方法(上下文已更改)。获取 批量分配:不安全的活页夹配置(API 滥用,结构) 两种方法都出错。
@Controller
@RequestMapping(value = "/findDocSearch")
public class Controller {
@Autowired
private IFindDocService findDocService;
@RequestMapping(value = "/byName", method = RequestMethod.GET)
@ResponseBody
public List<FindDocDTO> findDocByName(FindDocBean bean) {
return findDocService.retrieveDocByName(bean.getName());
}
@RequestMapping(value = "/byLoc", method = RequestMethod.GET)
@ResponseBody
public List<FindDocDTO> findDocByLocation(FindDocBean bean) {
return findDocService.retrieveDocByZipCode(bean.getZipcode(),
bean.getDistance());
}
}
我的 Bean 是:
public class FindDocBean implements Serializable {
private static final long serialVersionUID = -1212xxxL;
private String name;
private String zipcode;
private int distance;
@Override
public String toString() {
return String.format("FindDocBean[name: %s, zipcode:%s, distance:%s]",
name, zipcode, distance);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
根据目前发现的所有建议,他们建议仅通过以下方式限制具有所需参数的 bean:
final String[] DISALLOWED_FIELDS = new String[]{"bean.name", "bean.zipcode", };
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(DISALLOWED_FIELDS);
但我的问题是 bean 的所有 3 个参数都将用在 Controller 上提供的任一方法中。
有人可以为此提出一些解决方案吗?提前致谢。
简单的问题 - 您的映射器如何实例化 bean? Here 是答案/例子。您可以通过 query parameter
或 header
传递该数据。但是,那会很奇怪。更好的方法是使用 @QueryParam
提供位置或名称的方法。这样会更容易保护您的应用程序。
附带说明一下,查询的长度有限,因此如果您的搜索表单又大又奇怪,@POST
可能是个好主意,这样您就可以传递所有数据。为此,简单的例子会有点矫枉过正。
这看起来像是一个不幸的误报。此错误背后的规则是为了避免对象中存在但不打算作为(未验证的)用户输入的属性 意外地 从 Web 请求中填充。例如 POST 请求创建资源。如果请求处理程序采用完整的资源对象并仅填充缺失的属性,则恶意用户可以填充她不应该能够编辑的字段。
然而,这种情况与方案不符。您只需使用相同的机制来捕获您的不同论点。甚至不会读取额外填充的属性。在
GET http://yourhost/findDocSearch/byName?name=Abuse&zipCode=11111
额外的邮政编码将被忽略。因此这里不存在假定的风险。
要修复 警告,您可以将其标记为误报(如果这在您的设置中可行)。如果那不可能,您也可以直接将查询参数映射到方法参数。由于您只有有限的参数,因此不会造成太大伤害。如果这也不是一个选项,您可能需要找出您的代码分析用来确定它将识别哪些检查的确切算法。不幸的是,大多数扫描器只能发现一组有限的输入验证方法。
InitBinder 可用于方法。你可以试试这个。
@InitBinder("findDocByName")
public void initBinderByName(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","zipcode"});
}
@InitBinder("findDocByLocation")
public void initBinderByZipCode(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"distance","name"});
}
我遇到了同样的问题,然后我在同一个休息控制器中添加了下面的代码class:
@InitBinder
public void populateCustomerRequest(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{});
}
现在它对我来说工作正常,批量分配问题已解决。