From b9c6ad4e91672e520172b8d0af568a1616810df8 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 22 Nov 2024 17:15:01 +1100 Subject: [PATCH 1/7] Add documentation for form limits & improve configuration via context attributes Signed-off-by: Lachlan Roberts --- .../programming/security/FormSizeDocs.java | 30 ++++++++++ .../jetty/modules/programming-guide/nav.adoc | 2 + .../pages/security/configuring-form-size.adoc | 56 +++++++++++++++++++ .../ee10/servlet/ServletContextHandler.java | 40 +++++++++++++ .../jetty/ee10/webapp/WebAppContext.java | 3 + .../jetty/ee9/nested/ContextHandler.java | 44 ++++++++++++++- .../jetty/ee9/webapp/WebAppContext.java | 2 + 7 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java create mode 100644 documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc diff --git a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java new file mode 100644 index 000000000000..e370062dd156 --- /dev/null +++ b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java @@ -0,0 +1,30 @@ +// +// ======================================================================== +// 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 +// ======================================================================== +// + +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[] + } +} diff --git a/documentation/jetty/modules/programming-guide/nav.adoc b/documentation/jetty/modules/programming-guide/nav.adoc index ac50c0d7f133..a7094cf4c958 100644 --- a/documentation/jetty/modules/programming-guide/nav.adoc +++ b/documentation/jetty/modules/programming-guide/nav.adoc @@ -43,6 +43,8 @@ ** xref:troubleshooting/state-tracking.adoc[] ** xref:troubleshooting/component-dump.adoc[] ** xref:troubleshooting/debugging.adoc[] +* Jetty Security +** xref:security/configuring-form-size.adoc[] * Migration Guides ** xref:migration/94-to-10.adoc[] ** xref:migration/11-to-12.adoc[] diff --git a/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc new file mode 100644 index 000000000000..25f206dc4736 --- /dev/null +++ b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.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+] +---- + + + ... + + 200000 + 200 + + +---- + +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`. diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java index 4b2a34fa8b22..123c5a064322 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java @@ -319,6 +319,8 @@ public InvocationType getInvocationType() 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()), @@ -2045,6 +2047,44 @@ public void setExtendedListenerTypes(boolean b) { _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 diff --git a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java index 353a410bcc77..febf9ba5c6a6 100644 --- a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java +++ b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java @@ -57,6 +57,7 @@ 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; @@ -987,6 +988,8 @@ else if (getBaseResource() != null) 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), diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java index b85734a7a1ee..c146d099ca1f 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java @@ -94,6 +94,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.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; import org.eclipse.jetty.util.component.Environment; import org.eclipse.jetty.util.component.LifeCycle; @@ -302,7 +303,10 @@ public void insertHandler(org.eclipse.jetty.server.Handler.Singleton coreHandler @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() @@ -2861,6 +2865,44 @@ public APIContext getAPIContext() { 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 diff --git a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebAppContext.java b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebAppContext.java index 7ccf48b9e25d..eb028398e2f1 100644 --- a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebAppContext.java +++ b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebAppContext.java @@ -945,6 +945,8 @@ else if (getResourceBase() != null) 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), From 183e34cb325f72173f6622878b565deb965b25bf Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 19 Dec 2024 16:06:18 +1100 Subject: [PATCH 2/7] PR #12560 - changes from review Signed-off-by: Lachlan Roberts --- .../{FormSizeDocs.java => FormDocs.java} | 16 ++++----- .../pages/security/configuring-form-size.adoc | 33 +++++++------------ .../ee10/servlet/ServletContextHandler.java | 4 +-- .../jetty/ee10/webapp/WebAppContext.java | 5 +-- 4 files changed, 24 insertions(+), 34 deletions(-) rename documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/{FormSizeDocs.java => FormDocs.java} (70%) diff --git a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java similarity index 70% rename from documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java rename to documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java index e370062dd156..e4f155a582be 100644 --- a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormSizeDocs.java +++ b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java @@ -15,16 +15,16 @@ import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -public class FormSizeDocs +public class FormDocs { - public void example() + public void limitFormContent() { ServletContextHandler servletContextHandler = new ServletContextHandler(); - int maxSizeInBytes = 1024; - int formKeys = 100; - // tag::formSizeConfig[] - servletContextHandler.setMaxFormContentSize(maxSizeInBytes); - servletContextHandler.setMaxFormKeys(formKeys); - // end::formSizeConfig[] + // tag::limitFormContent[] + int maxFormKeys = 100; + int maxFormSizeInBytes = 1024; + servletContextHandler.setMaxFormContentSize(maxFormSizeInBytes); + servletContextHandler.setMaxFormKeys(maxFormKeys); + // end::limitFormContent[] } } diff --git a/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc index 25f206dc4736..db8971415c33 100644 --- a/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc +++ b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc @@ -11,40 +11,26 @@ // ======================================================================== // -[[configuring-form-size]] +[[limit-form-content]] = 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. +Forms can be a vector for denial-of-service attacks, since significant memory and CPU can be consumed if a malicious client sends very large form content or a 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. +You can change this default for a particular web application or for all web applications on a particular `Server` instance. -== Configuring Form Limits for a Webapp +== Configuring Form Limits for a Web Application -To configure the form limits for a single web application, the servlet context handler (or webappContext) instance must be configured using the following methods: +To configure the form limits for a single web application, the `ServletContextHandler` (or `WebAppContext`) instance can 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] +include::code:example$src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java.java[tags=limitFormContent] ---- -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+] ----- - - - ... - - 200000 - 200 - - ----- - -These settings can also be set via the following Context attributes. +These settings can also be set via the following `ServletContext` attributes. - `org.eclipse.jetty.server.Request.maxFormKeys` - `org.eclipse.jetty.server.Request.maxFormContentSize` @@ -53,4 +39,7 @@ These settings can also be set via the following Context attributes. 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`. +However, the following system properties can be set to change the default values of this across every context: + +- `org.eclipse.jetty.server.Request.maxFormKeys` +- `org.eclipse.jetty.server.Request.maxFormContentSize`. diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java index 123c5a064322..4f91667f2d5f 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java @@ -319,11 +319,11 @@ public InvocationType getInvocationType() 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()), + Dumpable.named("maxFormKeys ", getMaxFormKeys()), + Dumpable.named("maxFormContentSize ", getMaxFormContentSize()), new DumpableCollection("initparams " + this, getInitParams().entrySet())); } diff --git a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java index febf9ba5c6a6..efeea31e8faf 100644 --- a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java +++ b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java @@ -988,14 +988,15 @@ else if (getBaseResource() != null) name = String.format("%s@%x", name, hashCode()); dumpObjects(out, indent, - Dumpable.named("maxFormKeys ", getMaxFormKeys()), - Dumpable.named("maxFormContentSize ", getMaxFormContentSize()), + Dumpable.named("environment", ServletContextHandler.ENVIRONMENT.getName()), new ClassLoaderDump(getClassLoader()), new DumpableCollection("Systemclasses " + name, systemClasses), new DumpableCollection("Serverclasses " + name, serverClasses), new DumpableCollection("Configurations " + name, _configurations), new DumpableCollection("Handler attributes " + name, asAttributeMap().entrySet()), new DumpableCollection("Context attributes " + name, getContext().asAttributeMap().entrySet()), + Dumpable.named("maxFormKeys ", getMaxFormKeys()), + Dumpable.named("maxFormContentSize ", getMaxFormContentSize()), new DumpableCollection("EventListeners " + this, getEventListeners()), new DumpableCollection("Initparams " + name, getInitParams().entrySet()) ); From 2da9e402777e1960db848435a4b51d8594a34d99 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 20 Dec 2024 10:40:44 +1100 Subject: [PATCH 3/7] PR #12559 - changes to OpenID docs from review Signed-off-by: Lachlan Roberts --- .../pages/security/configuring-form-size.adoc | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc diff --git a/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc new file mode 100644 index 000000000000..e30681044783 --- /dev/null +++ b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc @@ -0,0 +1,53 @@ +// +// ======================================================================== +// 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 +// ======================================================================== +// + +[[limit-form-content]] += 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. +Forms can be a vector for denial-of-service attacks, since significant memory and CPU can be consumed if a malicious client sends very large form content or a 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 web application or for all web applications on a particular `Server` instance. + +== Configuring Form Limits for a Web Application + +To configure the form limits for a single web application, the `WebAppContext` instance can be configured from a context XML file or `WEB-INF/jetty-web.xml` file: + +[,xml,subs=attributes+] +---- + + + ... + + 200000 + 200 + + +---- + +These settings can also be set via the following `ServletContext` 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` +- `org.eclipse.jetty.server.Request.maxFormContentSize`. + From d8a5ad248c1a26db0f34352e2c8ed28558ee3f80 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Mon, 6 Jan 2025 17:44:50 +1100 Subject: [PATCH 4/7] PR #12560 - add docs about limiting form size with Jetty Core API Signed-off-by: Lachlan Roberts --- .../jetty/docs/programming/security/FormDocs.java | 13 +++++++++++++ .../jetty/modules/operations-guide/nav.adoc | 2 ++ .../pages/security/configuring-form-size.adoc | 1 - .../pages/security/configuring-form-size.adoc | 13 ++++++++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java index e4f155a582be..7ea2733e9b49 100644 --- a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java +++ b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java @@ -14,6 +14,9 @@ package org.eclipse.jetty.docs.programming.security; import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.server.FormFields; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.util.Fields; public class FormDocs { @@ -27,4 +30,14 @@ public void limitFormContent() servletContextHandler.setMaxFormKeys(maxFormKeys); // end::limitFormContent[] } + + public void jettyCoreAPI() + { + Request request = null; + // tag::jettyCoreAPI[] + int maxFormKeys = 100; + int maxFormSizeInBytes = 1024; + Fields fields = FormFields.getFields(request, maxFormKeys, maxFormSizeInBytes); + // end::jettyCoreAPI[] + } } diff --git a/documentation/jetty/modules/operations-guide/nav.adoc b/documentation/jetty/modules/operations-guide/nav.adoc index eb03e27de1f4..85a995bb712f 100644 --- a/documentation/jetty/modules/operations-guide/nav.adoc +++ b/documentation/jetty/modules/operations-guide/nav.adoc @@ -32,6 +32,8 @@ * xref:jstl/index.adoc[] * xref:jsf-taglibs/index.adoc[] * xref:jndi/index.adoc[] +* Jetty Security +** xref:security/configuring-form-size.adoc[] * xref:jaas/index.adoc[] * xref:jaspi/index.adoc[] * xref:jmx/index.adoc[] diff --git a/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc index e30681044783..3a07246d1e8f 100644 --- a/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc +++ b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc @@ -50,4 +50,3 @@ However, the following system properties can be set to change the default values - `org.eclipse.jetty.server.Request.maxFormKeys` - `org.eclipse.jetty.server.Request.maxFormContentSize`. - diff --git a/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc index db8971415c33..29aa6f45728a 100644 --- a/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc +++ b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc @@ -27,7 +27,7 @@ To configure the form limits for a single web application, the `ServletContextHa [,java,indent=0] ---- -include::code:example$src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java.java[tags=limitFormContent] +include::code:example$src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java[tags=limitFormContent] ---- These settings can also be set via the following `ServletContext` attributes. @@ -43,3 +43,14 @@ However, the following system properties can be set to change the default values - `org.eclipse.jetty.server.Request.maxFormKeys` - `org.eclipse.jetty.server.Request.maxFormContentSize`. + +== Limiting Form Content with Jetty Core API + +The class `FormFields` is used to parse forms with the Jetty Core API, which provides `onFields` and `getFields` static methods to provide both async & blocking ways to parse a form. + +These methods take parameters for `maxFields` and `maxLength` which can be used to limit the form content. + +[,java,indent=0] +---- +include::code:example$src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java[tags=jettyCoreAPI] +---- \ No newline at end of file From 3d5a14155de21dcfde5c03565a9778ecbf17330c Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 7 Jan 2025 11:09:08 +1100 Subject: [PATCH 5/7] PR #12560 - update docs from review Signed-off-by: Lachlan Roberts --- .../docs/programming/security/FormDocs.java | 8 +++++++- .../pages/security/configuring-form-size.adoc | 6 +++--- .../pages/security/configuring-form-size.adoc | 8 ++++---- .../org/eclipse/jetty/server/FormFields.java | 16 ++++++++-------- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java index 7ea2733e9b49..fd7d79900556 100644 --- a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java +++ b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/security/FormDocs.java @@ -37,7 +37,13 @@ public void jettyCoreAPI() // tag::jettyCoreAPI[] int maxFormKeys = 100; int maxFormSizeInBytes = 1024; - Fields fields = FormFields.getFields(request, maxFormKeys, maxFormSizeInBytes); + Fields fields; + + // Explicit set the form limits. + fields = FormFields.getFields(request, maxFormKeys, maxFormSizeInBytes); + + // Rely on default form limits. + fields = FormFields.getFields(request); // end::jettyCoreAPI[] } } diff --git a/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc index 3a07246d1e8f..be2f0e59d85f 100644 --- a/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc +++ b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc @@ -44,9 +44,9 @@ These settings can also be set via the following `ServletContext` attributes. == 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: +The following system properties can be used to configure form limits for the entire server, including all contexts without explicit configuration: - `org.eclipse.jetty.server.Request.maxFormKeys` - `org.eclipse.jetty.server.Request.maxFormContentSize`. + +If not configured for either the server or a specific context, then the default `maxFormKeys` is 1000 and the default `maxFormContentSize` is 200000. \ No newline at end of file diff --git a/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc index 29aa6f45728a..ae0443458119 100644 --- a/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc +++ b/documentation/jetty/modules/programming-guide/pages/security/configuring-form-size.adoc @@ -37,18 +37,18 @@ These settings can also be set via the following `ServletContext` attributes. == 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: +The following system properties can be used to configure form limits for the entire server, including all contexts without explicit configuration: - `org.eclipse.jetty.server.Request.maxFormKeys` - `org.eclipse.jetty.server.Request.maxFormContentSize`. +If not configured for either the server or a specific context, then the default `maxFormKeys` is 1000 and the default `maxFormContentSize` is 200000. + == Limiting Form Content with Jetty Core API The class `FormFields` is used to parse forms with the Jetty Core API, which provides `onFields` and `getFields` static methods to provide both async & blocking ways to parse a form. -These methods take parameters for `maxFields` and `maxLength` which can be used to limit the form content. +These methods can take parameters for `maxFields` and `maxLength` which can be used to limit the form content. [,java,indent=0] ---- diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java index 1bf6997c1453..a656401b2ca1 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java @@ -130,8 +130,8 @@ public static Fields getFields(Request request) * Calls to {@code onFields} and {@code getFields} methods are idempotent, and * can be called multiple times, with subsequent calls returning the results of the first call. * @param request The request to get or read the Fields from - * @param maxFields The maximum number of fields to accept - * @param maxLength The maximum length of fields + * @param maxFields The maximum number of fields to accept or -1 for unlimited + * @param maxLength The maximum length of fields or -1 for unlimited. * @return the Fields * @see #onFields(Request, Promise.Invocable) * @see #onFields(Request, Charset, Promise.Invocable) @@ -185,8 +185,8 @@ public static void onFields(Request request, Charset charset, Promise.Invocable< * * @param request The request to get or read the Fields from * @param charset The {@link Charset} of the request content, if previously extracted. - * @param maxFields The maximum number of fields to accept - * @param maxLength The maximum length of fields + * @param maxFields The maximum number of fields to accept or -1 for unlimited + * @param maxLength The maximum length of fields or -1 for unlimited * @param promise The action to take when the FormFields are available. */ public static void onFields(Request request, Charset charset, int maxFields, int maxLength, Promise.Invocable promise) @@ -249,8 +249,8 @@ public static CompletableFuture from(Request request, Charset charset) * @param request The {@link Request} in which to look for an existing {@link FormFields} attribute, * using the classname as the attribute name, else the request is used * as a {@link Content.Source} from which to read the fields and set the attribute. - * @param maxFields The maximum number of fields to be parsed - * @param maxLength The maximum total size of the fields + * @param maxFields The maximum number of fields to be parsed or -1 for unlimited + * @param maxLength The maximum total size of the fields or -1 for unlimited * @return A {@link CompletableFuture} that will provide the {@link Fields} or a failure. * @deprecated use {@link #onFields(Request, Charset, int, int, Promise.Invocable)} instead. */ @@ -266,8 +266,8 @@ public static CompletableFuture from(Request request, int maxFields, int * using the classname as the attribute name, else the request is used * as a {@link Content.Source} from which to read the fields and set the attribute. * @param charset the {@link Charset} to use for byte to string conversion. - * @param maxFields The maximum number of fields to be parsed - * @param maxLength The maximum total size of the fields + * @param maxFields The maximum number of fields to be parsed or -1 for unlimited + * @param maxLength The maximum total size of the fields or -1 for unlimited * @return A {@link CompletableFuture} that will provide the {@link Fields} or a failure. * @deprecated use {@link #onFields(Request, Charset, int, int, Promise.Invocable)} instead. */ From 81ccbf39741246404bfa821936e593e296f6a10e Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 7 Jan 2025 11:18:31 +1100 Subject: [PATCH 6/7] PR #12560 - add form limit attributes to name set Signed-off-by: Lachlan Roberts --- .../jetty/ee10/servlet/ServletContextHandler.java | 9 +++++++++ .../org/eclipse/jetty/ee9/nested/ContextHandler.java | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java index 4f91667f2d5f..32374f755eff 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java @@ -2085,6 +2085,15 @@ public Object setAttribute(String name, Object attribute) default -> super.setAttribute(name, attribute); }; } + + @Override + public Set getAttributeNameSet() + { + Set names = new HashSet<>(super.getAttributeNameSet()); + names.add(FormFields.MAX_FIELDS_ATTRIBUTE); + names.add(FormFields.MAX_LENGTH_ATTRIBUTE); + return Collections.unmodifiableSet(names); + } } public class ServletContextApi implements jakarta.servlet.ServletContext diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java index c146d099ca1f..1b7693f926c6 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java @@ -2905,6 +2905,15 @@ public Object setAttribute(String name, Object attribute) } } + @Override + public Set getAttributeNameSet() + { + Set names = new HashSet<>(super.getAttributeNameSet()); + names.add(FormFields.MAX_FIELDS_ATTRIBUTE); + names.add(FormFields.MAX_LENGTH_ATTRIBUTE); + return Collections.unmodifiableSet(names); + } + private class CoreToNestedHandler extends Abstract { @Override From ba44f80bea3905004d7c7eb84da604f59813432c Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 7 Jan 2025 11:32:52 +1100 Subject: [PATCH 7/7] PR #12560 - remove duplicated docs Signed-off-by: Lachlan Roberts --- .../pages/security/configuring-form-size.adoc | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc index be2f0e59d85f..451965f5b9a0 100644 --- a/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc +++ b/documentation/jetty/modules/operations-guide/pages/security/configuring-form-size.adoc @@ -14,12 +14,7 @@ [[limit-form-content]] = 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. -Forms can be a vector for denial-of-service attacks, since significant memory and CPU can be consumed if a malicious client sends very large form content or a 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 web application or for all web applications on a particular `Server` instance. +Forms can be a vector for denial-of-service attacks, like explained in xref:programming-guide:security/configuring-form-size.adoc[this section] of the Programming Guide. == Configuring Form Limits for a Web Application @@ -41,12 +36,3 @@ These settings can also be set via the following `ServletContext` attributes. - `org.eclipse.jetty.server.Request.maxFormKeys` - `org.eclipse.jetty.server.Request.maxFormContentSize` - -== Configuring Default Form Limits for the Server - -The following system properties can be used to configure form limits for the entire server, including all contexts without explicit configuration: - -- `org.eclipse.jetty.server.Request.maxFormKeys` -- `org.eclipse.jetty.server.Request.maxFormContentSize`. - -If not configured for either the server or a specific context, then the default `maxFormKeys` is 1000 and the default `maxFormContentSize` is 200000. \ No newline at end of file