Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,15 @@ private static Set<String> expandPropertyRefs(Set<String> refs) {
}

Set<String> toReturn = new TreeSet<String>();
final int maxDepth = 32; // bound per-ref prefix expansion (CWE-400)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be defined as a constant, defined in a consistent location/format as the others (and configurable).

for (String raw : refs) {
int depth = 0;
for (int idx = raw.length(); idx >= 0; idx = raw.lastIndexOf('.', idx - 1)) {
toReturn.add(raw.substring(0, idx));
if (++depth > maxDepth) {
throw new ReportableException("Property reference exceeds the maximum depth of "
+ maxDepth + ": " + raw);
}
}
}
return toReturn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,10 @@ private void processInvocationMessages(RequestState state, RequestMessage req,
// No method invocations which can happen via RequestContext.fire()
return;
}
if (invocations.size() > MAX_INVOCATIONS) {
throw new ReportableException("Request contained " + invocations.size()
+ " invocations, exceeding the maximum of " + MAX_INVOCATIONS);
}
List<Method> contextMethods = new ArrayList<Method>(invocations.size());
List<Object> invocationResults = new ArrayList<Object>(invocations.size());
Map<Object, SortedSet<String>> allPropertyRefs = new HashMap<Object, SortedSet<String>>();
Expand Down Expand Up @@ -462,6 +466,11 @@ private void processInvocationMessages(RequestState state, RequestMessage req,
// Invoke it
domainReturnValue = service.invoke(domainMethod, args.toArray());
if (invocation.getPropertyRefs() != null) {
if (invocation.getPropertyRefs().size() > MAX_PROPERTY_REFS_PER_INVOCATION) {
throw new ReportableException("Invocation contained "
+ invocation.getPropertyRefs().size()
+ " propertyRefs, exceeding the maximum of " + MAX_PROPERTY_REFS_PER_INVOCATION);
}
SortedSet<String> paths = allPropertyRefs.get(domainReturnValue);
if (paths == null) {
paths = new TreeSet<String>();
Expand Down Expand Up @@ -500,11 +509,25 @@ private void processInvocationMessages(RequestState state, RequestMessage req,
}
}

/**
* Maximum number of operations accepted in a single RequestFactory request, bounding the
* per-operation reflective work (CWE-400 / CWE-409).
*/
private static final int MAX_OPERATIONS = 1000;
/** Maximum number of invocations accepted in a single RequestFactory request (CWE-400). */
private static final int MAX_INVOCATIONS = 1000;
/** Maximum propertyRefs accepted on a single invocation (CWE-400). */
private static final int MAX_PROPERTY_REFS_PER_INVOCATION = 100;

private void processOperationMessages(final RequestState state, RequestMessage req) {
List<OperationMessage> operations = req.getOperations();
if (operations == null) {
return;
}
if (operations.size() > MAX_OPERATIONS) {
throw new ReportableException("Request contained " + operations.size()
+ " operations, exceeding the maximum of " + MAX_OPERATIONS);
}

List<AutoBean<? extends BaseProxy>> beans = state.getBeansForPayload(operations);
assert operations.size() == beans.size();
Expand Down