Skip to content

gRPC JavaScript library - #7527

Merged
ehsandeep merged 2 commits into
devfrom
grpc-js-library
Jul 7, 2026
Merged

gRPC JavaScript library#7527
ehsandeep merged 2 commits into
devfrom
grpc-js-library

Conversation

@Mzack9999

@Mzack9999 Mzack9999 commented Jul 6, 2026

Copy link
Copy Markdown
Member

adds a grpc javascript library for nuclei templates, wrapping grpcurl. it supports server reflection and precompiled protosets, taking json requests and returning json responses. the client exposes invoke, invokewithheaders, listservices, listmethods, describesymbol, connect and close plus an options object for plaintext/tls, skip verify, server name, timeout, protoset path and max receive size.

connections are dialed through the execution fastdialer so host and ip denylists and restrict-local-network-access are enforced, with the host checked at construction and again per dial. protoset files are read through the local file access allowlist, so without -lfa only files inside the templates directory are allowed.

covered by unit tests against a local health service and the interop test service (unary with rich fields, request metadata, error status, server streaming, list/describe, protoset, malformed input, tls, and policy denials), a compiler test that runs require nuclei/grpc, and two signed javascript template integration tests.

Summary by CodeRabbit

  • New Features

    • Added JavaScript-accessible gRPC client support for connecting to services, listing methods, describing symbols, and making unary calls.
    • Supports server reflection and optional protoset descriptor files, plus plaintext/TLS controls, timeouts, and message size limits.
    • Added end-to-end gRPC health coverage (including denied-host/refusal behavior) and verified require()-based module usage.
  • Bug Fixes

    • Strengthened target validation, network-policy enforcement, and constructor/dial error handling.
    • Added clearer handling for malformed request payloads and unknown methods.
  • Tests

    • Expanded integration and unit test suites for gRPC invocation, descriptors, reflection/protoset paths, and TLS behavior.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db9d54f5-6eb3-43e6-a909-1bbafc8177ae

📥 Commits

Reviewing files that changed from the base of the PR and between 7a6e29e and c8b8739.

📒 Files selected for processing (1)
  • pkg/protocols/http/request_test.go

Walkthrough

This PR adds a new nuclei/grpc JS module for gRPC dialing, reflection/protoset descriptor loading, and unary invocation. It wires the module into the compiler, updates dependencies, and adds unit and integration coverage for health checks, policy checks, and TLS.

Changes

gRPC JS Module

Layer / File(s) Summary
Dependency updates for gRPC support
go.mod
Adds direct and indirect dependencies for grpcurl, protoreflect, grpc, and related transitive packages, and promotes protobuf to a direct dependency.
Dial, descriptor resolution, and unary invocation core
pkg/js/libs/grpc/invoke.go
Implements policy-checked dialing, protoset or reflection descriptor resolution, unary invocation, and symbol description helpers.
Client JS API surface
pkg/js/libs/grpc/grpc.go
Defines the JS-facing Options and Client types, constructor setup, lazy connection handling, and exported methods for connect, discovery, invocation, and cleanup.
Compiler registration and JS-level integration test
pkg/js/compiler/pool.go, pkg/js/compiler/grpc_integration_test.go
Registers the generated libgrpc JS module and adds a compiler-level test that requires nuclei/grpc and invokes a health check.
Interop TestService method coverage tests
pkg/js/libs/grpc/grpc_methods_test.go
Implements an interop TestService plus helpers for TLS and descriptor sets, and tests payload echo, metadata, error status, streaming, method listing, symbol description, protoset invocation, malformed JSON, and TLS invocation.
Client behavior and policy tests
pkg/js/libs/grpc/grpc_test.go
Adds helpers for in-process health servers, client construction, descriptor sets, and temp template dirs, plus tests for reflection invocation, protoset access control, network policy enforcement, target validation, and end-to-end unary invocation.
Template-based end-to-end gRPC scenarios
internal/tests/integration/javascript_grpc_test.go, internal/tests/integration/javascript_test.go
Adds gRPC health and denied-access scenarios and registers both cases in the JavaScript test suite.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested reviewers: dogancanbakir

Poem

A bunny hopped to gRPC land,
with protosets and health checks in hand.
Reflection sang, "SERVING" bright,
and policy kept the path just right. 🐰
Hop, invoke, and close with cheer —
new JS gRPC is here!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: adding a new gRPC JavaScript library.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch grpc-js-library

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/js/libs/grpc/grpc_test.go (1)

81-105: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate descriptor-set-building logic with grpc_methods_test.go.

This recursive add closure duplicates marshalDescriptorSet in grpc_methods_test.go (lines 112-134) almost line-for-line. Since both are in the same grpc test package, healthProtoset could simply delegate to the more general helper.

♻️ Proposed consolidation
-func healthProtoset(t *testing.T) []byte {
-	t.Helper()
-
-	fds := &descriptorpb.FileDescriptorSet{}
-	seen := map[string]bool{}
-	var add func(fd protoreflect.FileDescriptor)
-	add = func(fd protoreflect.FileDescriptor) {
-		if seen[fd.Path()] {
-			return
-		}
-		seen[fd.Path()] = true
-		imports := fd.Imports()
-		for i := 0; i < imports.Len(); i++ {
-			add(imports.Get(i).FileDescriptor)
-		}
-		fds.File = append(fds.File, protodesc.ToFileDescriptorProto(fd))
-	}
-	add(healthpb.File_grpc_health_v1_health_proto)
-
-	data, err := proto.Marshal(fds)
-	require.NoError(t, err)
-	return data
-}
+func healthProtoset(t *testing.T) []byte {
+	t.Helper()
+	return marshalDescriptorSet(t, healthpb.File_grpc_health_v1_health_proto)
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/js/libs/grpc/grpc_test.go` around lines 81 - 105, The descriptor-set
construction in healthProtoset duplicates the recursive marshalDescriptorSet
logic already present in grpc_methods_test.go. Refactor healthProtoset to reuse
that shared helper instead of maintaining a second add closure, keeping
healthProtoset focused on selecting healthpb.File_grpc_health_v1_health_proto
and delegating the actual FileDescriptorSet serialization to
marshalDescriptorSet.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@go.mod`:
- Line 237: Upgrade the indirect dependency github.com/go-jose/go-jose/v4 in
go.mod from v4.0.5 to v4.1.4 or later, and update the resolved module state so
the grpcurl/spiffe/xds dependency chain pulls in the fixed version. Verify the
module graph still builds cleanly after the version bump and that no older
transitive reference to go-jose remains pinned.

---

Nitpick comments:
In `@pkg/js/libs/grpc/grpc_test.go`:
- Around line 81-105: The descriptor-set construction in healthProtoset
duplicates the recursive marshalDescriptorSet logic already present in
grpc_methods_test.go. Refactor healthProtoset to reuse that shared helper
instead of maintaining a second add closure, keeping healthProtoset focused on
selecting healthpb.File_grpc_health_v1_health_proto and delegating the actual
FileDescriptorSet serialization to marshalDescriptorSet.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f77a0681-da60-4811-bf07-3a4af5d6954b

📥 Commits

Reviewing files that changed from the base of the PR and between e4a83ad and 7a6e29e.

⛔ Files ignored due to path filters (6)
  • go.sum is excluded by !**/*.sum
  • internal/tests/integration/testdata/protocols/javascript/grpc-denied.yaml is excluded by !**/*.yaml
  • internal/tests/integration/testdata/protocols/javascript/grpc-health.yaml is excluded by !**/*.yaml
  • pkg/js/generated/go/libgrpc/grpc.go is excluded by !**/generated/**
  • pkg/js/generated/ts/grpc.ts is excluded by !**/generated/**
  • pkg/js/generated/ts/index.ts is excluded by !**/generated/**
📒 Files selected for processing (9)
  • go.mod
  • internal/tests/integration/javascript_grpc_test.go
  • internal/tests/integration/javascript_test.go
  • pkg/js/compiler/grpc_integration_test.go
  • pkg/js/compiler/pool.go
  • pkg/js/libs/grpc/grpc.go
  • pkg/js/libs/grpc/grpc_methods_test.go
  • pkg/js/libs/grpc/grpc_test.go
  • pkg/js/libs/grpc/invoke.go

Comment thread go.mod
github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.9.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.5 // indirect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== go.mod context ==\n'
sed -n '220,245p' go.mod

printf '\n== go.sum matches ==\n'
rg -n 'github.com/go-jose/go-jose/v4' go.mod go.sum || true

printf '\n== repository usages ==\n'
rg -n 'go-jose|go-jose/v4|jose' . --glob '!go.sum' --glob '!*.min.*' || true

Repository: projectdiscovery/nuclei

Length of output: 1969


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== possible callers/importers ==\n'
rg -n 'github.com/go-jose/go-jose/v4|go-jose|jwe|jws|jwt|oidc|openid' . \
  --glob '!go.sum' --glob '!*.md' --glob '!vendor/**' || true

printf '\n== go mod why (if available) ==\n'
go mod why -m github.com/go-jose/go-jose/v4 2>/dev/null || true

Repository: projectdiscovery/nuclei

Length of output: 1280


🌐 Web query:

GHSA-78h2-9frx-2jm8 go-jose/go-jose v4.0.5 fixed in 4.1.4 JWE key-wrapping alg empty encrypted_key panic

💡 Result:

The vulnerability GHSA-78h2-9frx-2jm8 (also tracked as CVE-2026-34986) describes a denial-of-service vulnerability in the go-jose library that causes a panic during JWE (JSON Web Encryption) decryption [1][2]. The issue occurs when an application attempts to decrypt a JWE object where the alg header indicates a key-wrapping algorithm (excluding A128GCMKW, A192GCMKW, and A256GCMKW) and the encrypted_key field is empty [1][3]. The panic is triggered in the cipher.KeyUnwrap function within key_wrap.go because it attempts to allocate a slice with an invalid (zero or negative) length based on the length of the empty encrypted_key [1][3]. This vulnerability is fixed in: - go-jose/go-jose v4.1.4 [1][2] - go-jose/go-jose v3.0.5 [1][2] Applications that do not include key-wrapping algorithms in the list of accepted key algorithms passed to ParseEncrypted, ParseEncryptedJSON, or ParseEncryptedCompact functions are not affected [1][3]. For those using key-wrapping, it is recommended to upgrade to the patched versions or implement pre-validation to ensure the encrypted_key field is non-empty [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== direct usage of grpcurl / spiffe / xds-related deps ==\n'
rg -n 'fullstorydev/grpcurl|go-spiffe|spiffe|xds|certprovider|credentials/xds' . \
  --glob '!go.sum' --glob '!*.md' --glob '!vendor/**' || true

printf '\n== module graph snippets ==\n'
go mod why -m github.com/fullstorydev/grpcurl 2>/dev/null || true
go mod why -m github.com/spiffe/go-spiffe/v2 2>/dev/null || true

Repository: projectdiscovery/nuclei

Length of output: 1011


Upgrade github.com/go-jose/go-jose/v4 to v4.1.4+
This indirect dep comes in through grpcurl/spiffe/xds, and v4.0.5 is affected by GHSA-78h2-9frx-2jm8 when decrypting JWE with key-wrapping alg and an empty encrypted_key.

🧰 Tools
🪛 OSV Scanner (2.4.0)

[HIGH] 237-237: github.com/go-jose/go-jose/v4 4.0.5: Go JOSE Panics in JWE decryption in github.com/go-jose/go-jose

(GO-2026-4945)


[HIGH] 237-237: github.com/go-jose/go-jose/v4 4.0.5: Go JOSE Panics in JWE decryption

(GHSA-78h2-9frx-2jm8)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@go.mod` at line 237, Upgrade the indirect dependency
github.com/go-jose/go-jose/v4 in go.mod from v4.0.5 to v4.1.4 or later, and
update the resolved module state so the grpcurl/spiffe/xds dependency chain
pulls in the fixed version. Verify the module graph still builds cleanly after
the version bump and that no older transitive reference to go-jose remains
pinned.

Source: Linters/SAST tools

@ehsandeep
ehsandeep requested a review from dwisiswant0 July 7, 2026 13:19
@ehsandeep
ehsandeep merged commit 85723be into dev Jul 7, 2026
19 checks passed
@ehsandeep
ehsandeep deleted the grpc-js-library branch July 7, 2026 18:55
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.

3 participants