Limiting the page size on the backend

There are some components in Vaadin/Hilla that allow for automatic lazy loading, such as AutoGrid or even ComboBox (if configured properly). However, right now, it is possible to define a pagesize in the thousands, the backend (e.g. Browsercallable Services that implement “CountService” or “ListService” that take a Pageable and a Filter) does not limit the page size of the pageable. An evil party could intercept requests and always demand all rows of a table, which might be tens of thousands of rows large.

Setting these values

spring:
  data:
    web:
      pageable:
        max-page-size: 10
    rest:
      max-page-size: 10

does not work. One cannot trust the client to always send correct data, the server has to do further validation…

Any tips on how to configure this in a single place?

As the Hilla endpoints are not traditional rest endpoints, it doesn’t take the spring.data.web or rest properties into account by default, so an enhancement could be that the Hilla also respect them. A forged request without any limit is easy to fix by this.

But, the interesting question, is if a page request is forged and the limit is set to 10_000_000, how it should decide whether to ignore the limit from request?

At the moment, I don’t have a universal solution for this case that backend cannot trust the pageSize that is coming with a request. But, for the other case, Hilla either can take the spring.data.web properties into account, or let user to introduce a default page bean, as an alternative.

For now you could create your own base-classes that all ListService / CrudService implementations derive from and add a check there.

Added an enhancement issue for this: AutoCrud: add support for limiting the pageSize without deriving/overriding the Hilla services

@sissbruecker @Soroosh_Taefi The Vaadin internal class EndpointInvoker uses the validation framework to validate the parameters. I tried creating following custom validator, but it does not get called by Vaadin:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

@Component
public class PageableValidator implements Validator {

  @Value("${spring.data.web.pageable.max-page-size}")
  private int maxPageSize;

  /** This Validator validates only Pageable instances */
  public boolean supports(Class clazz) {
    return Pageable.class.equals(clazz);
  }

  public void validate(Object obj, Errors e) {
    Pageable p = (Pageable) obj;
    if (p.getPageSize() > maxPageSize) {
      e.rejectValue("pageSize", "toobig");
    }
  }
}

Do you guys know how I can register this validator so that EndpointInvoker validates parameters of type org.springframework.data.domain.Pageable automatically without me having to annotate my methods in the @BrowserCallable classes?

Did you try to introduce it as a bean? The following line shows that Hilla consider your Validator bean, and if a default one is not defined, then it creates a default one:

You could also try adding a custom ConstraintValidator to the Pageable parameter in the implementation. See also Defining Custom Constraints in the Hilla docs.

Also note that Hilla uses a jakarta.validation.Validator, while you implemented a org.springframework.validation.Validator.

You could try to implement the Jakarta one and add your check to the default set of checks.