Add documentation for form limits & improve configuration via context attributes
Signed-off-by: Lachlan Roberts <lachlan.p.roberts@gmail.com>
This commit is contained in:
parent
165327a1bf
commit
190d441e1e
|
@ -0,0 +1,17 @@
|
|||
package org.eclipse.jetty.docs.programming.security;
|
||||
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
|
||||
public class FormSizeDocs
|
||||
{
|
||||
public void example()
|
||||
{
|
||||
ServletContextHandler servletContextHandler = new ServletContextHandler();
|
||||
int maxSizeInBytes = 1024;
|
||||
int formKeys = 100;
|
||||
// tag::formSizeConfig[]
|
||||
servletContextHandler.setMaxFormContentSize(maxSizeInBytes);
|
||||
servletContextHandler.setMaxFormKeys(formKeys);
|
||||
// end::formSizeConfig[]
|
||||
}
|
||||
}
|
|
@ -44,6 +44,7 @@
|
|||
** xref:troubleshooting/component-dump.adoc[]
|
||||
** xref:troubleshooting/debugging.adoc[]
|
||||
* Jetty Security
|
||||
** xref:security/configuring-form-size.adoc[]
|
||||
** xref:security/siwe-support.adoc[]
|
||||
* Migration Guides
|
||||
** xref:migration/94-to-10.adoc[]
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
[[configuring-form-size]]
|
||||
= Limiting Form Content
|
||||
|
||||
Form content sent to the server is processed by Jetty into a map of parameters to be used by the web application.
|
||||
This can be vulnerable to denial of service (DOS) attacks since significant memory and CPU can be consumed if a malicious clients sends very large form content or large number of form keys.
|
||||
Thus, Jetty limits the amount of data and keys that can be in a form posted to Jetty.
|
||||
|
||||
The default maximum size Jetty permits is 200000 bytes and 1000 keys.
|
||||
You can change this default for a particular webapp or for all webapps on a particular Server instance.
|
||||
|
||||
== Configuring Form Limits for a Webapp
|
||||
|
||||
To configure the form limits for a single web application, the servlet context handler (or webappContext) instance must be configured using the following methods:
|
||||
|
||||
[,java,indent=0]
|
||||
----
|
||||
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java[tags=formSizeConfig]
|
||||
----
|
||||
|
||||
These methods may be called directly when embedding Jetty, but more commonly are configured from a context XML file or WEB-INF/jetty-web.xml file:
|
||||
|
||||
[,xml,subs=attributes+]
|
||||
----
|
||||
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext">
|
||||
|
||||
...
|
||||
|
||||
<Set name="maxFormContentSize">200000</Set>
|
||||
<Set name="maxFormKeys">200</Set>
|
||||
</Configure>
|
||||
|
||||
----
|
||||
|
||||
These settings can also be set via the following Context attributes.
|
||||
|
||||
- `org.eclipse.jetty.server.Request.maxFormKeys`
|
||||
- `org.eclipse.jetty.server.Request.maxFormContentSize`
|
||||
|
||||
== Configuring Default Form Limits for the Server
|
||||
|
||||
The default `maxFormKeys` is 1000 and the default `maxFormContentSize` is 200000.
|
||||
|
||||
However, the following system properties can be set to change the default values of this across every context; `org.eclipse.jetty.server.Request.maxFormKeys` and `org.eclipse.jetty.server.Request.maxFormContentSize`.
|
|
@ -318,6 +318,8 @@ public class ServletContextHandler extends ContextHandler
|
|||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
dumpObjects(out, indent,
|
||||
Dumpable.named("maxFormKeys ", getMaxFormKeys()),
|
||||
Dumpable.named("maxFormContentSize ", getMaxFormContentSize()),
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
Dumpable.named("context " + this, getContext()),
|
||||
Dumpable.named("handler attributes " + this, getContext().getPersistentAttributes()),
|
||||
|
@ -2043,6 +2045,44 @@ public class ServletContextHandler extends ContextHandler
|
|||
{
|
||||
_servletContext.setExtendedListenerTypes(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name)
|
||||
{
|
||||
return switch (name)
|
||||
{
|
||||
case FormFields.MAX_FIELDS_ATTRIBUTE -> getMaxFormKeys();
|
||||
case FormFields.MAX_LENGTH_ATTRIBUTE -> getMaxFormContentSize();
|
||||
default -> super.getAttribute(name);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setAttribute(String name, Object attribute)
|
||||
{
|
||||
return switch (name)
|
||||
{
|
||||
case FormFields.MAX_FIELDS_ATTRIBUTE ->
|
||||
{
|
||||
int oldValue = getMaxFormKeys();
|
||||
if (attribute == null)
|
||||
setMaxFormKeys(DEFAULT_MAX_FORM_KEYS);
|
||||
else
|
||||
setMaxFormKeys(Integer.parseInt(attribute.toString()));
|
||||
yield oldValue;
|
||||
}
|
||||
case FormFields.MAX_LENGTH_ATTRIBUTE ->
|
||||
{
|
||||
int oldValue = getMaxFormContentSize();
|
||||
if (attribute == null)
|
||||
setMaxFormContentSize(DEFAULT_MAX_FORM_CONTENT_SIZE);
|
||||
else
|
||||
setMaxFormContentSize(Integer.parseInt(attribute.toString()));
|
||||
yield oldValue;
|
||||
}
|
||||
default -> super.setAttribute(name, attribute);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class ServletContextApi implements jakarta.servlet.ServletContext
|
||||
|
|
|
@ -60,6 +60,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.ClassLoaderDump;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
|
@ -986,6 +987,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
name = String.format("%s@%x", name, hashCode());
|
||||
|
||||
dumpObjects(out, indent,
|
||||
Dumpable.named("maxFormKeys ", getMaxFormKeys()),
|
||||
Dumpable.named("maxFormContentSize ", getMaxFormContentSize()),
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
new DumpableCollection("Systemclasses " + name, systemClasses),
|
||||
new DumpableCollection("Serverclasses " + name, serverClasses),
|
||||
|
|
|
@ -316,6 +316,8 @@ public class ServletContextHandler extends ContextHandler
|
|||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
dumpObjects(out, indent,
|
||||
Dumpable.named("maxFormKeys ", getMaxFormKeys()),
|
||||
Dumpable.named("maxFormContentSize ", getMaxFormContentSize()),
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
Dumpable.named("context " + this, getContext()),
|
||||
Dumpable.named("handler attributes " + this, getContext().getPersistentAttributes()),
|
||||
|
@ -2037,6 +2039,44 @@ public class ServletContextHandler extends ContextHandler
|
|||
{
|
||||
_servletContext.setExtendedListenerTypes(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name)
|
||||
{
|
||||
return switch (name)
|
||||
{
|
||||
case FormFields.MAX_FIELDS_ATTRIBUTE -> getMaxFormKeys();
|
||||
case FormFields.MAX_LENGTH_ATTRIBUTE -> getMaxFormContentSize();
|
||||
default -> super.getAttribute(name);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setAttribute(String name, Object attribute)
|
||||
{
|
||||
return switch (name)
|
||||
{
|
||||
case FormFields.MAX_FIELDS_ATTRIBUTE ->
|
||||
{
|
||||
int oldValue = getMaxFormKeys();
|
||||
if (attribute == null)
|
||||
setMaxFormKeys(DEFAULT_MAX_FORM_KEYS);
|
||||
else
|
||||
setMaxFormKeys(Integer.parseInt(attribute.toString()));
|
||||
yield oldValue;
|
||||
}
|
||||
case FormFields.MAX_LENGTH_ATTRIBUTE ->
|
||||
{
|
||||
int oldValue = getMaxFormContentSize();
|
||||
if (attribute == null)
|
||||
setMaxFormContentSize(DEFAULT_MAX_FORM_CONTENT_SIZE);
|
||||
else
|
||||
setMaxFormContentSize(Integer.parseInt(attribute.toString()));
|
||||
yield oldValue;
|
||||
}
|
||||
default -> super.setAttribute(name, attribute);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class ServletContextApi implements jakarta.servlet.ServletContext
|
||||
|
|
|
@ -60,6 +60,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.ClassLoaderDump;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
|
@ -882,6 +883,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
name = String.format("%s@%x", name, hashCode());
|
||||
|
||||
dumpObjects(out, indent,
|
||||
Dumpable.named("maxFormKeys ", getMaxFormKeys()),
|
||||
Dumpable.named("maxFormContentSize ", getMaxFormContentSize()),
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
new DumpableCollection("Protected classes " + name, protectedClasses),
|
||||
new DumpableCollection("Hidden classes " + name, hiddenClasses),
|
||||
|
|
|
@ -92,6 +92,7 @@ import org.eclipse.jetty.util.TypeUtil;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
@ -300,7 +301,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Supplie
|
|||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
dumpObjects(out, indent, new DumpableCollection("initparams " + this, getInitParams().entrySet()));
|
||||
dumpObjects(out, indent,
|
||||
Dumpable.named("maxFormKeys ", getMaxFormKeys()),
|
||||
Dumpable.named("maxFormContentSize ", getMaxFormContentSize()),
|
||||
new DumpableCollection("initparams " + this, getInitParams().entrySet()));
|
||||
}
|
||||
|
||||
public APIContext getServletContext()
|
||||
|
@ -2858,6 +2862,44 @@ public class ContextHandler extends ScopedHandler implements Attributes, Supplie
|
|||
{
|
||||
return _apiContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name)
|
||||
{
|
||||
return switch (name)
|
||||
{
|
||||
case FormFields.MAX_FIELDS_ATTRIBUTE -> getMaxFormKeys();
|
||||
case FormFields.MAX_LENGTH_ATTRIBUTE -> getMaxFormContentSize();
|
||||
default -> super.getAttribute(name);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setAttribute(String name, Object attribute)
|
||||
{
|
||||
return switch (name)
|
||||
{
|
||||
case FormFields.MAX_FIELDS_ATTRIBUTE ->
|
||||
{
|
||||
int oldValue = getMaxFormKeys();
|
||||
if (attribute == null)
|
||||
setMaxFormKeys(DEFAULT_MAX_FORM_KEYS);
|
||||
else
|
||||
setMaxFormKeys(Integer.parseInt(attribute.toString()));
|
||||
yield oldValue;
|
||||
}
|
||||
case FormFields.MAX_LENGTH_ATTRIBUTE ->
|
||||
{
|
||||
int oldValue = getMaxFormContentSize();
|
||||
if (attribute == null)
|
||||
setMaxFormContentSize(DEFAULT_MAX_FORM_CONTENT_SIZE);
|
||||
else
|
||||
setMaxFormContentSize(Integer.parseInt(attribute.toString()));
|
||||
yield oldValue;
|
||||
}
|
||||
default -> super.setAttribute(name, attribute);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class CoreToNestedHandler extends Abstract
|
||||
|
|
|
@ -945,6 +945,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
|
||||
dumpObjects(out, indent,
|
||||
Dumpable.named("environment", ContextHandler.ENVIRONMENT.getName()),
|
||||
Dumpable.named("maxFormKeys ", getMaxFormKeys()),
|
||||
Dumpable.named("maxFormContentSize ", getMaxFormContentSize()),
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
new DumpableCollection("Systemclasses " + name, systemClasses),
|
||||
new DumpableCollection("Serverclasses " + name, serverClasses),
|
||||
|
|
Loading…
Reference in New Issue