0

Following up on this GWT-RPC question (and answer #1) re. field size checking, I would like to know the right way to check pre-deserialization for max data size sent to server, something like if request data size > X then abort the request. Valuing simplicity and based on answer on aforementioned question/answer, I am inclined to believe checking for max overall request size would suffice, finer grained checks (i.e., field level checks) could be deferred to post-deserialization, but I am open to any best-practice suggestion.

Tech stack of interest: GWT-RPC client-server communication with Apache-Tomcat front-end web-server.

I suppose a first step would be to globally limit the size of any request (LimitRequestBody in httpd.conf or/and others?).
Are there finer-grained checks like something that can be set per RPC request? If so where, how? How much security value do finer grain checks bring over one global setting?

To frame the question more specifically with an example, let's suppose we have the two following RPC request signatures on the same servlet:

public void rpc1(A a, B b) throws MyException;
public void rpc2(C c, D d) throws MyException;

Suppose I approximately know the following max sizes:

  • a: 10 kB
  • b: 40 kB
  • c: 1 M B
  • d: 1 kB

Then I expect the following max sizes:

  • rpc1: 50 kB
  • rpc2: 1 MB

In the context of this example, my questions are:

  1. Where/how to configure the max size of any request -- i.e., 1 MB in my above example? I believe it is LimitRequestBody in httpd.conf but not 100% sure whether it is the only parameter for this purpose.
  2. If possible, where/how to configure max size per servlet -- i.e., max size of any rpc in my servlet is 1 MB?
  3. If possible, where/how to configure/check max size per rpc request -- i.e., max rpc1 size is 50 kB and max rpc2 size is 1 MB?
  4. If possible, where/how to configure/check max size per rpc request argument -- i.e., a is 10 kB, b is 40 kB, c is 1 MB, and d is 1 kB. I suspect it makes practical sense to do post-deserialization, doesn't it?
  5. For practical purposes based of cost/benefit, what level of pre-deserialization checking is generally recommended -- 1. global, 2. servlet, 3. rpc, 4. object-argument? Stated differently, what is roughly the cost-complexity on one hand and the added value on the other hand of each of the above pre-deserialization level checks?

Thanks much in advance.

Community
  • 1
  • 1
Patrick
  • 1,561
  • 2
  • 11
  • 22

1 Answers1

0

Based on what I have learned since I asked the question, my own answer and strategy until someone can show me better is:

  1. First line of defense and check is Apache's LimitRequestBody set in httpd.conf. It is the overall max for all rpc calls across all servlets.
  2. Second line of defense is servlet pre-deserialization by overriding GWT AbstractRemoteServiceServlet.readContent. For instance, one could do it as shown further below I suppose. This was the heart of what I was fishing for in this question.
  3. Then one can further check each rpc call argument post-deserialization. One could conveniently use the JSR 303 validation both on the server and client side -- see references StackOverflow and gwt r.e. client side.

Example on how to override AbstractRemoteServiceServlet.readContent:

@Override 
protected String readContent(HttpServletRequest request) throws ServletException, IOException
{
  final int contentLength = request.getContentLength();
  // _maxRequestSize should be large enough to be applicable to all rpc calls within this servlet.
  if (contentLength > _maxRequestSize)
    throw new IOException("Request too large");
  final String requestPayload = super.readContent(request);
  return requestPayload;
}

See this question in case the max request size if > 2GB.

From a security perspective, this strategy seems quite reasonable to me to control the size of data users send to server.

Community
  • 1
  • 1
Patrick
  • 1,561
  • 2
  • 11
  • 22