Skip to content

feat(jsonrpc): add resource restirct for jsonrpc#69

Open
317787106 wants to merge 5 commits intodevelopfrom
hotfix/restrict_jsonrpc_size
Open

feat(jsonrpc): add resource restirct for jsonrpc#69
317787106 wants to merge 5 commits intodevelopfrom
hotfix/restrict_jsonrpc_size

Conversation

@317787106
Copy link
Copy Markdown
Owner

@317787106 317787106 commented Apr 16, 2026

What does this PR do?

  • add resource restirct for jsonrpc

Why are these changes required?

This PR has been tested by:

  • Unit Tests
  • Manual Testing

Follow up

Extra details


Summary by cubic

Add configurable resource limits to JSON-RPC to cap batch size, response size, request time, and address filter size. This reduces memory use and protects nodes from oversized or slow requests.

  • New Features
    • Limits: node.jsonrpc.maxBatchSize (10), node.jsonrpc.maxResponseSize (25 MB), node.jsonrpc.maxRequestTimeout (30s), node.jsonrpc.maxAddressSize (1000).
    • Enforcement in JsonRpcServlet: buffered response with early size checks, cached request body, and per-request timeout.
    • Errors: returns -32005 (limit exceeded), -32003 (response too large), -32002 (timeout). Defaults set in CommonParameter and loaded via Args; keys added to config.conf.

Written for commit 7b33166. Summary will update on new commits.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 16, 2026

Warning

Rate limit exceeded

@317787106 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 38 minutes and 47 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 38 minutes and 47 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 172f0a1a-e68d-4655-a3db-41fc81cf3495

📥 Commits

Reviewing files that changed from the base of the PR and between 2de63bb and 7b33166.

📒 Files selected for processing (9)
  • common/src/main/java/org/tron/common/parameter/CommonParameter.java
  • common/src/main/java/org/tron/core/exception/jsonrpc/JsonRpcResponseTooLargeException.java
  • framework/src/main/java/org/tron/core/config/args/Args.java
  • framework/src/main/java/org/tron/core/config/args/ConfigKey.java
  • framework/src/main/java/org/tron/core/services/filter/BufferedResponseWrapper.java
  • framework/src/main/java/org/tron/core/services/filter/CachedBodyRequestWrapper.java
  • framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java
  • framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogFilter.java
  • framework/src/main/resources/config.conf
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/restrict_jsonrpc_size

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java">

<violation number="1" location="framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java:129">
P2: Race condition after timeout: `future.cancel(true)` only sends an interrupt; the RPC handler may still be running. Since `BufferedResponseWrapper` doesn't override header methods (`setStatus`, `setContentType`, etc.), the handler thread writes headers directly to the underlying `resp` concurrently with `writeJsonRpcError`. This can corrupt the HTTP response. Consider either wrapping header methods in `BufferedResponseWrapper` too, or awaiting actual thread termination before writing the error.</violation>

<violation number="2" location="framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java:155">
P1: No limit on request body size. `readBody` loads the entire input stream into memory before any validation runs. A malicious client can send a multi-gigabyte body to cause OOM. Add a maximum request body size check (e.g., reject if total bytes read exceeds a configured limit).</violation>

<violation number="3" location="framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java:168">
P1: The `message` string is concatenated into the JSON response without JSON-escaping. If `message` contains `"`, `\`, or control characters, the output is malformed JSON. Use the `ObjectMapper` (already available as `MAPPER`) to build the JSON safely, or at minimum escape the string.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

resp.getOutputStream().flush();
}

private byte[] readBody(InputStream in) throws IOException {
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 16, 2026

Choose a reason for hiding this comment

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

P1: No limit on request body size. readBody loads the entire input stream into memory before any validation runs. A malicious client can send a multi-gigabyte body to cause OOM. Add a maximum request body size check (e.g., reject if total bytes read exceeds a configured limit).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java, line 155:

<comment>No limit on request body size. `readBody` loads the entire input stream into memory before any validation runs. A malicious client can send a multi-gigabyte body to cause OOM. Add a maximum request body size check (e.g., reject if total bytes read exceeds a configured limit).</comment>

<file context>
@@ -66,6 +95,83 @@ public Integer getJsonRpcCode(int httpStatusCode) {
+    resp.getOutputStream().flush();
+  }
+
+  private byte[] readBody(InputStream in) throws IOException {
+    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+    byte[] tmp = new byte[4096];
</file context>
Fix with Cubic

Comment on lines +168 to +169
String body = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":" + error.code
+ ",\"message\":\"" + message + "\"},\"id\":" + idStr + "}";
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 16, 2026

Choose a reason for hiding this comment

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

P1: The message string is concatenated into the JSON response without JSON-escaping. If message contains ", \, or control characters, the output is malformed JSON. Use the ObjectMapper (already available as MAPPER) to build the JSON safely, or at minimum escape the string.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java, line 168:

<comment>The `message` string is concatenated into the JSON response without JSON-escaping. If `message` contains `"`, `\`, or control characters, the output is malformed JSON. Use the `ObjectMapper` (already available as `MAPPER`) to build the JSON safely, or at minimum escape the string.</comment>

<file context>
@@ -66,6 +95,83 @@ public Integer getJsonRpcCode(int httpStatusCode) {
+  private void writeJsonRpcError(HttpServletResponse resp, JsonRpcError error, String message,
+      JsonNode id) throws IOException {
+    String idStr = (id != null && !id.isNull() && !id.isMissingNode()) ? id.toString() : "null";
+    String body = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":" + error.code
+        + ",\"message\":\"" + message + "\"},\"id\":" + idStr + "}";
+    byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
</file context>
Suggested change
String body = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":" + error.code
+ ",\"message\":\"" + message + "\"},\"id\":" + idStr + "}";
String escapedMessage = MAPPER.writeValueAsString(message);
String body = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":" + error.code
+ ",\"message\":" + escapedMessage + "},\"id\":" + idStr + "}";
Fix with Cubic

try {
future.get(timeoutSec, TimeUnit.SECONDS);
} catch (TimeoutException e) {
future.cancel(true);
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 16, 2026

Choose a reason for hiding this comment

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

P2: Race condition after timeout: future.cancel(true) only sends an interrupt; the RPC handler may still be running. Since BufferedResponseWrapper doesn't override header methods (setStatus, setContentType, etc.), the handler thread writes headers directly to the underlying resp concurrently with writeJsonRpcError. This can corrupt the HTTP response. Consider either wrapping header methods in BufferedResponseWrapper too, or awaiting actual thread termination before writing the error.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java, line 129:

<comment>Race condition after timeout: `future.cancel(true)` only sends an interrupt; the RPC handler may still be running. Since `BufferedResponseWrapper` doesn't override header methods (`setStatus`, `setContentType`, etc.), the handler thread writes headers directly to the underlying `resp` concurrently with `writeJsonRpcError`. This can corrupt the HTTP response. Consider either wrapping header methods in `BufferedResponseWrapper` too, or awaiting actual thread termination before writing the error.</comment>

<file context>
@@ -66,6 +95,83 @@ public Integer getJsonRpcCode(int httpStatusCode) {
+    try {
+      future.get(timeoutSec, TimeUnit.SECONDS);
+    } catch (TimeoutException e) {
+      future.cancel(true);
+      JsonNode idNode = (!rootNode.isArray()) ? rootNode.get("id") : null;
+      writeJsonRpcError(resp, JsonRpcError.TIMEOUT, "Request timeout after " + timeoutSec + "s",
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant