Skip to content

fix(js): mysql panic due to missing executionId in ctx#6735

Merged
Mzack9999 merged 5 commits intodevfrom
dwisiswant0/fix/js/mysql-panic-due-to-missing-executionId-in-ctx
Dec 29, 2025
Merged

fix(js): mysql panic due to missing executionId in ctx#6735
Mzack9999 merged 5 commits intodevfrom
dwisiswant0/fix/js/mysql-panic-due-to-missing-executionId-in-ctx

Conversation

@dwisiswant0
Copy link
Member

@dwisiswant0 dwisiswant0 commented Dec 25, 2025

Proposed changes

The connectWithDSN func used db.Exec() which
implicitly uses context.Background()[1]. This
caused the registered "nucleitcp" dialer
callback to receive a ctx missing the
executionId, leading to a panic during type
assertion.

Refactor connectWithDSN to accept executionId
explicitly and use it to create a context for
db.PingContext() (yeah, instead of db.Exec()).
And, add a defensive check in the dialer callback
to handle nil values gracefully.

Fixes #6733 regression introduced in #6296.

[1]: "Exec uses context.Background internally" -
https://pkg.go.dev/database/sql#DB.Exec.

Steps to Reproduce

# tty1
$ docker run --name some-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:9
# tty2
$ ./bin/nuclei-3.6.1 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.6.0 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.5.1 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.5.0 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.5.0 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.4.10 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.4.9 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.4.8 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
$ ./bin/nuclei-3.4.7 -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
[mysql-default-login] [javascript] [high] 127.0.0.1:3306 [passwords="root",usernames="root"]

Dumped JavaScript response:

map[string]interface {}:2 {
  "error": "panic: interface conversion: interface {} is nil, not string",
  "success": "false",
} address=http://127.0.0.1:3306

Proof

$ make build
$ ./bin/nuclei -u http://127.0.0.1:3306 -t javascript/default-logins/mysql-default-login.yaml -itags fuzz -silent
[mysql-default-login] [javascript] [high] 127.0.0.1:3306 [passwords="root",usernames="root"]

Checklist

  • Pull request is created against the dev branch
  • All checks passed (lint, unit/integration/regression tests etc.) with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Summary by CodeRabbit

  • New Features

    • Added MySQL connectivity integration test support for JavaScript-based testing.
  • Bug Fixes

    • Scoped memoization caches by execution to prevent cross-run cache interference across JS library checks.
    • Improved handling when execution context is missing to return clearer errors instead of panics.

✏️ Tip: You can customize this high-level summary in your review settings.

The `connectWithDSN` func used `db.Exec()` which
implicitly uses `context.Background()`[1]. This
caused the registered "nucleitcp" dialer
callback to receive a ctx missing the
`executionId`, leading to a panic during type
assertion.

Refactor `connectWithDSN` to accept `executionId`
explicitly and use it to create a `context` for
`db.PingContext()` (yeah, instead of `db.Exec()`).
And, add a defensive check in the dialer callback
to handle nil values gracefully.

Fixes #6733 regression introduced in #6296.

[1]: "Exec uses `context.Background` internally" -
     https://pkg.go.dev/database/sql#DB.Exec.

Signed-off-by: Dwi Siswanto <git@dw1.io>
Signed-off-by: Dwi Siswanto <git@dw1.io>
Signed-off-by: Dwi Siswanto <git@dw1.io>
@auto-assign auto-assign bot requested a review from dogancanbakir December 25, 2025 18:09
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 25, 2025

Walkthrough

Adds execution-scoped memoization keys across multiple protocol libraries, propagates executionId via context into MySQL connection paths (including signature changes and PingContext usage), adds a MySQL integration test that runs a temporary Docker MySQL container, and hardens dialer initialization to avoid panics.

Changes

Cohort / File(s) Summary
JavaScript Integration Test
cmd/integration-test/javascript.go
Adds javascriptMySQLConnect type and test; starts/stops a temporary MySQL Docker container, waits for readiness, runs nuclei templates against it, and aggregates results.
MySQL library — public API & logic
pkg/js/libs/mysql/mysql.go, pkg/js/libs/mysql/mysql_private.go
Changes ConnectWithDSN to accept context.Context and extract executionId; connectWithDSN now takes (executionId string, dsn string); uses PingContext(ctx) and defer db.Close(); updates call sites accordingly.
MySQL memoization internals
pkg/js/libs/mysql/memo.mysql.go, pkg/js/libs/mysql/memo.mysql_private.go
Memoization keys now include executionId; memoizedconnectWithDSN signature updated to accept executionId and keys include it.
Protocol memoization (many libs)
pkg/js/libs/mssql/memo.mssql.go, pkg/js/libs/oracle/memo.oracle.go, pkg/js/libs/postgres/memo.postgres.go, pkg/js/libs/pop3/memo.pop3.go, pkg/js/libs/rdp/memo.rdp.go, pkg/js/libs/redis/memo.redis.go, pkg/js/libs/rsync/memo.rsync.go, pkg/js/libs/smb/memo.smb.go, pkg/js/libs/smb/memo.smb_private.go, pkg/js/libs/smb/memo.smbghost.go, pkg/js/libs/telnet/memo.telnet.go, pkg/js/libs/vnc/memo.vnc.go
Updated memoization cache key construction to prefix keys with executionId, scoping caches per execution; no signature changes (except MySQL private where noted).
Protocol state / dialer init
pkg/protocols/common/protocolstate/state.go
Safely reads executionId from context (nil-guarded) and returns an explicit error if dialers are not initialized for that executionId instead of causing a panic.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 A tiny hop into code and clay,
Caches scoped to each bright day,
MySQL pings with contextual cheer,
Tests spin up a container near,
Whiskers twitch — regression gone away. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.71% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Out of Scope Changes check ❓ Inconclusive Most changes are tightly scoped to fixing the executionId propagation issue across database libraries. However, the new javascriptMySQLConnect test in cmd/integration-test/javascript.go appears tangential to the core panic fix. Clarify whether the integration test is necessary for the fix or should be submitted separately. The test adds significant scope beyond the minimal panic fix.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: addressing a MySQL panic caused by missing executionId in context, which aligns with the primary change across multiple files.
Linked Issues check ✅ Passed The PR fixes the root cause identified in #6733: MySQL module panic from missing executionId in context, implementing defensive nil-checks and context propagation throughout the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dwisiswant0/fix/js/mysql-panic-due-to-missing-executionId-in-ctx

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22469bd and 49309b4.

📒 Files selected for processing (1)
  • pkg/js/libs/mysql/mysql_private.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/js/libs/mysql/mysql_private.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Tests (ubuntu-latest)
  • GitHub Check: Tests (macOS-latest)
  • GitHub Check: Tests (windows-latest)

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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/mysql/mysql.go (1)

193-196: Signature update correctly enables context propagation.

The method now accepts ctx to extract executionId, aligning with the per-execution memoization and context-aware connection handling.

Consider using the comma-ok idiom for the type assertion to guard against panics if executionId is unexpectedly missing from the context (same pattern applies to other methods in this file):

🔎 Optional defensive type assertion
 func (c *MySQLClient) ConnectWithDSN(ctx context.Context, dsn string) (bool, error) {
-	executionId := ctx.Value("executionId").(string)
+	executionId, ok := ctx.Value("executionId").(string)
+	if !ok {
+		return false, fmt.Errorf("executionId not found in context")
+	}
 	return memoizedconnectWithDSN(executionId, dsn)
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78e90e3 and 22469bd.

⛔ Files ignored due to path filters (1)
  • integration_tests/protocols/javascript/mysql-connect.yaml is excluded by !**/*.yaml
📒 Files selected for processing (18)
  • cmd/integration-test/javascript.go
  • pkg/js/libs/mssql/memo.mssql.go
  • pkg/js/libs/mysql/memo.mysql.go
  • pkg/js/libs/mysql/memo.mysql_private.go
  • pkg/js/libs/mysql/mysql.go
  • pkg/js/libs/mysql/mysql_private.go
  • pkg/js/libs/oracle/memo.oracle.go
  • pkg/js/libs/pop3/memo.pop3.go
  • pkg/js/libs/postgres/memo.postgres.go
  • pkg/js/libs/rdp/memo.rdp.go
  • pkg/js/libs/redis/memo.redis.go
  • pkg/js/libs/rsync/memo.rsync.go
  • pkg/js/libs/smb/memo.smb.go
  • pkg/js/libs/smb/memo.smb_private.go
  • pkg/js/libs/smb/memo.smbghost.go
  • pkg/js/libs/telnet/memo.telnet.go
  • pkg/js/libs/vnc/memo.vnc.go
  • pkg/protocols/common/protocolstate/state.go
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Format Go code using go fmt ./...
Run static analysis using go vet ./... on Go code

Files:

  • pkg/js/libs/smb/memo.smb_private.go
  • pkg/js/libs/telnet/memo.telnet.go
  • pkg/js/libs/redis/memo.redis.go
  • pkg/js/libs/smb/memo.smb.go
  • pkg/js/libs/rdp/memo.rdp.go
  • pkg/protocols/common/protocolstate/state.go
  • pkg/js/libs/mysql/memo.mysql_private.go
  • pkg/js/libs/mysql/mysql.go
  • pkg/js/libs/mysql/mysql_private.go
  • pkg/js/libs/mysql/memo.mysql.go
  • pkg/js/libs/vnc/memo.vnc.go
  • pkg/js/libs/pop3/memo.pop3.go
  • cmd/integration-test/javascript.go
  • pkg/js/libs/rsync/memo.rsync.go
  • pkg/js/libs/oracle/memo.oracle.go
  • pkg/js/libs/postgres/memo.postgres.go
  • pkg/js/libs/mssql/memo.mssql.go
  • pkg/js/libs/smb/memo.smbghost.go
pkg/js/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use custom JavaScript runtime for code protocol templates with auto-generated bindings from pkg/js/generated/

Files:

  • pkg/js/libs/smb/memo.smb_private.go
  • pkg/js/libs/telnet/memo.telnet.go
  • pkg/js/libs/redis/memo.redis.go
  • pkg/js/libs/smb/memo.smb.go
  • pkg/js/libs/rdp/memo.rdp.go
  • pkg/js/libs/mysql/memo.mysql_private.go
  • pkg/js/libs/mysql/mysql.go
  • pkg/js/libs/mysql/mysql_private.go
  • pkg/js/libs/mysql/memo.mysql.go
  • pkg/js/libs/vnc/memo.vnc.go
  • pkg/js/libs/pop3/memo.pop3.go
  • pkg/js/libs/rsync/memo.rsync.go
  • pkg/js/libs/oracle/memo.oracle.go
  • pkg/js/libs/postgres/memo.postgres.go
  • pkg/js/libs/mssql/memo.mssql.go
  • pkg/js/libs/smb/memo.smbghost.go
pkg/js/libs/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use custom JavaScript library implementations located in pkg/js/libs/ for JavaScript protocol support

Files:

  • pkg/js/libs/smb/memo.smb_private.go
  • pkg/js/libs/telnet/memo.telnet.go
  • pkg/js/libs/redis/memo.redis.go
  • pkg/js/libs/smb/memo.smb.go
  • pkg/js/libs/rdp/memo.rdp.go
  • pkg/js/libs/mysql/memo.mysql_private.go
  • pkg/js/libs/mysql/mysql.go
  • pkg/js/libs/mysql/mysql_private.go
  • pkg/js/libs/mysql/memo.mysql.go
  • pkg/js/libs/vnc/memo.vnc.go
  • pkg/js/libs/pop3/memo.pop3.go
  • pkg/js/libs/rsync/memo.rsync.go
  • pkg/js/libs/oracle/memo.oracle.go
  • pkg/js/libs/postgres/memo.postgres.go
  • pkg/js/libs/mssql/memo.mssql.go
  • pkg/js/libs/smb/memo.smbghost.go
pkg/protocols/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/protocols/**/*.go: Each protocol implementation should implement the Request interface with Compile(), ExecuteWithResults(), Match(), and Extract() methods
Protocol implementations should embed Operators for matching/extraction functionality

Files:

  • pkg/protocols/common/protocolstate/state.go
🧬 Code graph analysis (1)
cmd/integration-test/javascript.go (1)
pkg/testutils/integration.go (2)
  • TestCase (247-250)
  • RunNucleiTemplateAndGetResults (30-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint
🔇 Additional comments (11)
pkg/js/libs/redis/memo.redis.go (1)

12-12: LGTM! Execution-scoped memoization correctly applied across all protocol libraries.

The memoization key updates consistently incorporate executionId across all 8 modified memo files (rsync, telnet, rdp, vnc, mssql, mysql, oracle, redis). This change ensures cache entries are isolated per execution context rather than shared globally by host/port alone, which is essential for preventing the nil executionId panic described in the PR objectives.

The pattern is mechanically correct and aligns with the PR's goal of fixing issue #6733.

Also applies to: 28-28, 44-44, 60-60

pkg/js/libs/postgres/memo.postgres.go (1)

15-29: LGTM - executionId scoping applied consistently.

The memoization keys now correctly include executionId to ensure per-execution cache isolation, which addresses the root cause of the regression.

pkg/js/libs/mysql/memo.mysql_private.go (1)

11-15: LGTM - Memoization wrapper correctly updated.

The function now properly accepts and propagates executionId to the underlying connectWithDSN function, ensuring the cache key is execution-scoped.

pkg/protocols/common/protocolstate/state.go (1)

203-210: Defensive nil handling correctly prevents the panic.

The guarded extraction of executionId from context prevents the type assertion panic that was causing the regression. The subsequent dialer nil check with a clear error message improves debuggability.

Note: If executionId is nil, this will pass an empty string to GetDialersWithId(""), which will return nil and trigger the error on line 209. This is acceptable behavior since the error message will indicate "dialers not initialized for ", though the empty ID might be slightly confusing in logs.

pkg/js/libs/smb/memo.smb.go (1)

13-30: LGTM - Consistent executionId scoping for SMB functions.

Both memoized SMB functions now include executionId in their cache keys, maintaining consistency with the broader caching pattern.

pkg/js/libs/smb/memo.smbghost.go (1)

12-16: LGTM - SMBGhost detection memoization updated.

The cache key now correctly includes executionId for execution-scoped caching.

pkg/js/libs/mysql/mysql_private.go (1)

76-92: Core fix correctly propagates executionId through context.

The refactor from db.Exec("select 1") to db.PingContext(ctx) with an executionId-enriched context is the correct solution. This ensures the custom MySQL dialer receives the execution context needed to retrieve the appropriate dialer instance.

Good additions:

  • defer db.Close() ensures proper resource cleanup
  • Using PingContext is more appropriate for connection verification than executing a query
pkg/js/libs/smb/memo.smb_private.go (1)

15-19: LGTM - SMBv2 metadata collection memoization updated.

The cache key now includes executionId for proper execution scoping.

cmd/integration-test/javascript.go (1)

382-399: MySQL Docker container setup looks correct.

The container configuration follows the established pattern with proper environment variables and expiration handling.

pkg/js/libs/mysql/mysql.go (1)

111-111: LGTM!

The change correctly propagates executionId to connectWithDSN, ensuring the dialer callback receives the proper execution context and the memoization cache is scoped per execution.

pkg/js/libs/pop3/memo.pop3.go (1)

12-12: LGTM! Cache key now properly scoped by executionId.

The addition of executionId to the memoization hash key correctly ensures that cached POP3 connection results are isolated per execution, preventing unintended cache hits across different execution contexts. This aligns with the PR's objective to propagate executionId throughout the connection flow.

Since this file is generated by the memogen tool from the source function signature, the change reflects that isPoP3() now includes executionId as a parameter, and the memo wrapper was regenerated accordingly.

Signed-off-by: Dwi Siswanto <git@dw1.io>
@dwisiswant0 dwisiswant0 added this to the v3.6.2 milestone Dec 26, 2025
@dwisiswant0
Copy link
Member Author

Tests will be resolved after #6737 & #6739. So currently it's irrelevant.

@Mzack9999 Mzack9999 merged commit 2d3168b into dev Dec 29, 2025
5 of 6 checks passed
@Mzack9999 Mzack9999 deleted the dwisiswant0/fix/js/mysql-panic-due-to-missing-executionId-in-ctx branch December 29, 2025 07:34
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.

[BUG] Regression: Javascript 'MYSQL' module fails in latest version (works in v3.4.7)

2 participants