简体   繁体   中英

How to correct OverPosting in Spring Boot Rest Api with parameter @RequestBody Json request?

I have a driver that is not configured to restrict which attributes of the request are allowed to be mapped to the model, so the method could be used to perform OverPosting or UnderPosting attacks.

I do not want that in a crucial application I put parameters that I do not want to store or modify in BD.

In projects no REST I have seen that they solve with a method @InitBinder and is configured with "setDisallowedFields", "setAllowedFields" and "setRequiredFields", but when using a json @RequestBody parameter that is mapped to a DTO I can not do the restriction, plus I have several controllers that receive different attributes from the same DTO

DTO

    public class ImagenAyudaDTO implements Serializable {
         private static final long serialVersionUID = 1L;
         private Integer idImagenAyuda;
         private String urlImagen;
         private String estado;}

Controller

    @PostMapping(path = "/getdto")
        public ResponseEntity<ImagenAyudaDTO> getDto(
         @RequestBody(required = true) @Valid ImagenAyudaDTO i
            ) {
        Logger.info("getDto request " + i.toString());
        ImagenAyudaDTO im = new ImagenAyudaDTO();
        im.setEstado("D");
        im.setIdImagenAyuda(new Integer(2));
        im.setUrlImagen("https://start.spring.io/");
        Logger.info("getDto Response " + im.toString());
        return new ResponseEntity<ImagenAyudaDTO>(im, HttpStatus.OK);
    }

Binder

    @InitBinder
    public void filterGetdto(WebDataBinder dataBinder) {
        final String[] DISALLOWED_FIELDS = new String[] { "estado" };
        final String[] ALLOWED_FIELDS = new String[] { "idImagenAyuda", "urlImagen" };
        final String[] REQUIRED_FIELDS = new String[] { "idImagenAyuda", "urlImagen" };
        dataBinder.setDisallowedFields(DISALLOWED_FIELDS);
        dataBinder.setAllowedFields(ALLOWED_FIELDS);
        dataBinder.setRequiredFields(REQUIRED_FIELDS);
     }

Request from Postman:
邮递员的要求

What I hope is to have a binder type validation that disables me from the fields of the DTO that should not be used in the request, taking into account that in the same class I can have several controllers that use the same DTO

I'm bad for English, that's why GoogleTranslate.

Googling something, I found an option https://www.baeldung.com/javax-validation-groups , groups of javax validation, It works for when we need to apply constraints on a certain set of fields of the bean, and then we want to apply constraints on another set of fields of the same bean.

all javax validation constraints have a groups attribute, in this the name of the group to which the restriction belongs can be specified, specifying the name of the group interface.

  1. create the interfaces: These interfaces will be the names of the restriction groups (InformacionBasica, InformacionAvanzada).
  2. then use the interfaces on the bean.


    @Email(groups = InformacionBasica.class)
    private String email;
    @NotBlank(groups = InformacionBasica.class)
    private String telefono;

    @NotBlank(groups = {InformacionBasica.class, InformacionAvanzada.class})
    private String captcha;

    @NotBlank(groups = InformacionAvanzada.class)
    private String direccion;

and for example from a rest spring boot service:



    import javax.validation.Valid;
    import org.springframework.validation.annotation.Validated;

    @Validated
    public class PersonaRest{
    @PostMapping("/algoBasica")
            @Validated(InformacionBasica.class)
            public ResponseEntity hacerAlgo(@Valid @RequestBody PersonaTO p) {
                try {
                    personaServicio.hacerAlgo();
                    return new ResponseEntity(Boolean.TRUE, HttpStatus.OK);
                } catch (EmptyResultDataAccessException e) {
                    return new ResponseEntity(
                            "Informacion basica necesaria",
                            HttpStatus.BAD_REQUEST);
                }

            }

    @PostMapping("/algoAvanzada")
            @Validated(InformacionAvanzada.class)
            public ResponseEntity hacerAlgo(@Valid @RequestBody PersonaTO p) {
                try {
                    personaServicio.hacerAlgo();
                    return new ResponseEntity(Boolean.TRUE, HttpStatus.OK);
                } catch (EmptyResultDataAccessException e) {
                    return new ResponseEntity(
                            "Informacion avanzada necesaria",
                            HttpStatus.BAD_REQUEST);
                }

            }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM