Skip to content

adding vnc auth#6413

Merged
Mzack9999 merged 8 commits intodevfrom
feat-4842-vnc
Sep 12, 2025
Merged

adding vnc auth#6413
Mzack9999 merged 8 commits intodevfrom
feat-4842-vnc

Conversation

@Mzack9999
Copy link
Member

@Mzack9999 Mzack9999 commented Aug 21, 2025

Proposed changes

Closes #4842

Vulnerable container:

docker run -it --rm \
  -p 5900:5900 \
  -e VNC_PASSWORD=mysecret \
  dorowu/ubuntu-desktop-lxde-vnc

Template:

id: vnc-password-test

info:
  name: VNC Password Authentication Test
  author: pdteam
  severity: info
  description: |
    Tests VNC authentication with correct and incorrect passwords.
  reference:
    - https://docs.projectdiscovery.io/templates/protocols/javascript/modules/vnc.VNCClient
  metadata:
    max-request: 2
    shodan-query: product:"vnc"
  tags: js,network,vnc,authentication

javascript:
  - code: |
      let vnc = require('nuclei/vnc');
      let client = new vnc.VNCClient();
      
      // Test with correct password
      let result1 = client.Connect(Host, Port, 'mysecret');
      log('Correct password result: ' + result1);
      
      // Test with incorrect password
      let result2 = client.Connect(Host, Port, 'wrongpassword');
      log('Incorrect password result: ' + result2);

    args:
      Host: "{{Host}}"
      Port: 5900
      
    extractors:
      - type: dsl
        dsl:
          - response

Output:

% go run . -t vnc.yaml -u 127.0.0.1 -debug       

                     __     _
   ____  __  _______/ /__  (_)
  / __ \/ / / / ___/ / _ \/ /
 / / / / /_/ / /__/ /  __/ /
/_/ /_/\__,_/\___/_/\___/_/   v3.4.8

                projectdiscovery.io

[INF] Current nuclei version: v3.4.8 (latest)
[INF] Current nuclei-templates version: v10.2.7 (latest)
[WRN] Scan results upload to cloud is disabled.
[INF] New templates added in latest release: 55
[INF] Templates loaded for current scan: 1
[WRN] Loading 1 unsigned templates for scan. Use with caution.
[INF] Targets loaded for current scan: 1
[JS] Correct password result: true
[JS] Incorrect password result: false
[DBG] [vnc-password-test] Dumped Javascript request for 127.0.0.1:5900:
Variables:
 map[string]interface {}:2 {
  "Host": "127.0.0.1",
  "Port": "5900",
} address=127.0.0.1:5900
[DBG]  [vnc-password-test] Javascript Code:

        let vnc = require('nuclei/vnc');
        let client = new vnc.VNCClient();
        // Test with correct password
        let result1 = client.Connect(Host, Port, 'mysecret');
        log('Correct password result: ' + result1);
        // Test with incorrect password
        let result2 = client.Connect(Host, Port, 'wrongpassword');
        log('Incorrect password result: ' + result2);

[DBG] [vnc-password-test] Dumped Javascript response for 127.0.0.1:5900:
map[string]interface {}:2 {
  "response": "Incorrect password result: false",
  "success": "true",
} address=127.0.0.1:5900
[vnc-password-test] [javascript] [info] 127.0.0.1:5900 ["Incorrect password result: false"]
[INF] Scan completed in 1.512213s. 1 matches found.

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 a VNC client API with password authentication and usage examples for programmatic VNC checks.
  • Tests
    • Added a JavaScript integration test for VNC password brute-force with containerized VNC setup, retries, and cleanup.
  • Chores
    • Updated dependencies to include a VNC client library to support the new functionality.

@Mzack9999 Mzack9999 self-assigned this Aug 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 21, 2025

Walkthrough

Adds a VNC authentication client and integration test: introduces VNCClient.Connect for password auth, wires a VNC Docker resource into JavaScript integration tests (vnc-pass-brute), updates imports/aliasing for the VNC plugin, and adds an indirect go.mod dependency on github.com/alexsnet/go-vnc.

Changes

Cohort / File(s) Summary
Integration Tests: JavaScript VNC brute
cmd/integration-test/javascript.go
Adds dockertest VNC resource (dorowu/ubuntu-desktop-lxde-vnc with VNC_PASSWORD=mysecret), initializes and purges the container, and implements javascriptVncPassBrute test that runs a nuclei template against localhost:<port> with retries and aggregated errors.
VNC Client Library
pkg/js/libs/vnc/vnc.go
Adds VNCClient type and Connect(ctx, host, port, password) (bool, error) which enforces host allowlist, obtains fast dialer, TCP-dials target, uses github.com/alexsnet/go-vnc to authenticate, classifies auth failures vs other errors (auth -> (false,nil)), and updates VNC plugin import alias usage.
Dependencies
go.mod
Adds indirect dependency github.com/alexsnet/go-vnc v0.1.0.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor JS as JS Runtime
  participant VC as VNCClient
  participant PS as ProtocolState / Dialers
  participant NET as Network (fast dialer)
  participant VN as go-vnc (client)

  JS->>VC: Connect(ctx, host, port, password)
  VC->>PS: IsHostAllowed / GetDialersWithId(executionId)
  alt host denied
    PS-->>VC: ErrHostDenied
    VC-->>JS: (false, ErrHostDenied)
  else allowed
    VC->>NET: Dial TCP (fast dialer, 10s)
    NET-->>VC: net.Conn / error
    VC->>VN: vnclib.Connect(conn, cfg{Password})
    alt auth fails
      VN-->>VC: auth error
      VC-->>JS: (false, nil)
    else other error
      VN-->>VC: error
      VC-->>JS: (false, error)
    else success
      VN-->>VC: client
      VC->>VN: Close()
      VC-->>JS: (true, nil)
    end
  end
Loading
sequenceDiagram
  autonumber
  actor TR as Test Runner
  participant DP as Docker Pool
  participant VC as VNC Container
  participant NU as nuclei
  participant TM as vnc-pass-brute.yaml

  TR->>DP: Start VNC container (dorowu/ubuntu-desktop-lxde-vnc, VNC_PASSWORD=mysecret)
  DP-->>TR: Resource (exposes 5900/tcp -> host port)
  TR->>TR: Wait ~3s and retry loop
  TR->>NU: Execute vnc-pass-brute.yaml on localhost:<port>
  NU->>TM: Run checks / brute attempts
  TM-->>NU: Results
  NU-->>TR: Results (count)
  alt exactly one result
    TR-->>TR: Mark test pass
  else
    TR-->>TR: Record error and retry until exhausted
  end
  TR->>DP: Purge resource (deferred)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Pre-merge checks (4 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "adding vnc auth" concisely and accurately represents the main change in this PR — adding VNC authentication support (a VNCClient API, JS module, and tests). It is short, directly related to the changeset, and communicates the primary intent to reviewers. For polish, consider capitalizing and making it slightly more descriptive (for example, "Add VNC authentication support").
Linked Issues Check ✅ Passed The changes directly implement the objectives of issue #4842 by adding a VNCClient.Connect API that distinguishes authentication success/failure, a nuclei JavaScript module and template that test correct and incorrect passwords, and an integration test plus a vulnerable VNC container to exercise the flow. These additions enable VNC authentication testing and align with the vnc-brute use case described in the linked issue. Based on the provided summaries, the coding requirements in the linked issue appear satisfied.
Out of Scope Changes Check ✅ Passed All modified files in the provided summary (pkg/js/libs/vnc/vnc.go, cmd/integration-test/javascript.go, go.mod) are directly related to implementing VNC authentication and its tests, and I do not see unrelated or extraneous changes. The added indirect dependency and plugin import are consistent with the VNC feature. No out-of-scope changes were detected in the supplied summary.

Poem

A rabbit taps keys with a curious grin,
"VNC, let's try a password and begin!"
Containers hum, ports wink in the night,
Nuclei sniffs softly and finds what is right.
Hop, hash, and a pass — the test hops in delight. 🐇🖥️

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-4842-vnc

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.

@Mzack9999 Mzack9999 marked this pull request as ready for review August 25, 2025 14:47
@auto-assign auto-assign bot requested a review from dogancanbakir August 25, 2025 14:47
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: 5

🧹 Nitpick comments (5)
cmd/integration-test/javascript.go (3)

18-19: Disable VNC test on Windows/macOS like other Docker-based JS tests.

Redis and SSH Docker-based tests are disabled on Windows/macOS; the VNC test should follow suit to avoid CI flakiness on non-Linux runners.

-	{Path: "protocols/javascript/vnc-pass-brute.yaml", TestCase: &javascriptVncPassBrute{}},
+	{Path: "protocols/javascript/vnc-pass-brute.yaml", TestCase: &javascriptVncPassBrute{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},

103-134: Stabilize the VNC integration test (readiness wait, copy/paste comment).

  • The image dorowu/ubuntu-desktop-lxde-vnc is heavy; 3s is often not enough for the VNC server to accept connections, causing flakes.
  • Comment mentions “ssh” instead of “vnc”.

Increase the wait and fix the comment:

-			//let ssh server start
-			time.Sleep(3 * time.Second)
+			// let vnc server start
+			time.Sleep(8 * time.Second)

Optionally, make pool.Retry meaningful by returning err (current closure always returns nil and never retries within the pool.Retry loop):

-			results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
-			return nil
+			results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
+			return err

If you prefer to keep the outer for-retry loop, consider dropping pool.Retry entirely to reduce nesting.

Also consider raising defaultRetry from 3 to 5 for this heavy image (outside the changed hunk).


201-218: Give the VNC container more time to live; 30s expiry is tight for a desktop+VNC image.

30 seconds can expire mid-test under load/emulation (especially with Platform forced to linux/amd64 on non-amd64 runners).

-	// by default expire after 30 sec
-	if err := vncResource.Expire(30); err != nil {
+	// give the desktop+vnc container enough time
+	if err := vncResource.Expire(120); err != nil {

Optional: if CI runners are arm64, consider dropping Platform override to avoid qemu emulation overhead (align with how other tests handle this if possible).

pkg/js/libs/vnc/vnc.go (2)

51-54: Guard against missing executionId in context (to avoid panics).

Direct type assertion can panic if context is not prepared by the runtime.

-func (c *VNCClient) Connect(ctx context.Context, host string, port int, password string) (bool, error) {
-	executionId := ctx.Value("executionId").(string)
+func (c *VNCClient) Connect(ctx context.Context, host string, port int, password string) (bool, error) {
+	execVal := ctx.Value("executionId")
+	executionId, _ := execVal.(string)
+	if executionId == "" {
+		return false, fmt.Errorf("executionId missing in context")
+	}
 	return connect(executionId, host, port, password)
 }

Note: If other JS libs intentionally assume presence and prefer panic, feel free to keep the pattern for consistency; otherwise the above improves safety.


101-110: Update isAuthError to broaden error tokens; no typed sentinel errors in alexsnet/go-vnc

The upstream github.com/alexsnet/go-vnc library does not export a sentinel or typed error for authentication failures, so we must continue using substring matching as a fallback. To reduce false negatives, consider broadening the set of tokens and add a TODO for future migration to errors.Is/errors.As when such typed errors become available.

Suggested diff:

--- a/pkg/js/libs/vnc/vnc.go
+++ b/pkg/js/libs/vnc/vnc.go
@@ -107,7 +107,11 @@ func isAuthError(err error) bool {
-   return stringsutil.ContainsAnyI(errStr, "authentication", "auth", "password", "invalid", "failed")
+   // TODO: once go-vnc exports a sentinel auth error (e.g., ErrAuthFailed), switch to errors.Is/As here.
+   return stringsutil.ContainsAnyI(errStr,
+       "authentication", "auth", "password", "invalid", "failed",
+       "denied", "unauth", "unauthorized", "access denied")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0f7b33c and e83382d.

⛔ Files ignored due to path filters (4)
  • go.sum is excluded by !**/*.sum
  • integration_tests/protocols/javascript/vnc-pass-brute.yaml is excluded by !**/*.yaml
  • pkg/js/generated/go/libvnc/vnc.go is excluded by !**/generated/**
  • pkg/js/generated/ts/vnc.ts is excluded by !**/generated/**
📒 Files selected for processing (3)
  • cmd/integration-test/javascript.go (3 hunks)
  • go.mod (1 hunks)
  • pkg/js/libs/vnc/vnc.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
cmd/integration-test/javascript.go (1)
pkg/testutils/integration.go (2)
  • TestCase (247-250)
  • RunNucleiTemplateAndGetResults (30-32)
pkg/js/libs/vnc/vnc.go (4)
pkg/js/generated/ts/vnc.ts (2)
  • VNCClient (44-65)
  • Connect (62-64)
pkg/js/libs/redis/redis.go (1)
  • Connect (63-66)
pkg/protocols/common/protocolstate/headless.go (2)
  • IsHostAllowed (124-150)
  • ErrHostDenied (22-22)
pkg/protocols/common/protocolstate/state.go (1)
  • GetDialersWithId (39-45)
🔇 Additional comments (3)
cmd/integration-test/javascript.go (1)

24-27: LGTM: resource wiring is consistent with existing pattern.

Adding vncResource alongside redis/ssh and reusing pool/defaultRetry matches the current test infra conventions.

pkg/js/libs/vnc/vnc.go (2)

30-39: Public VNCClient type and JS docs look good.

The zero-field client aligns with other JS libs; examples match the generated TS interface.


143-143: LGTM: plugin alias switch to vncplugin.VNCPlugin is correct.

Import aliasing is clear and avoids path ambiguity with other plugins.

github.com/alecthomas/kingpin/v2 v2.4.0 // indirect
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/alexsnet/go-vnc v0.1.0 // indirect
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Make go-vnc a direct dependency and tidy the module.

The package is imported directly in pkg/js/libs/vnc/vnc.go, so it should not be marked as indirect. This can cause drift and tooling confusion.

Apply this minimal change and then run go mod tidy:

-	github.com/alexsnet/go-vnc v0.1.0 // indirect
+	github.com/alexsnet/go-vnc v0.1.0

Run the following to verify and clean up:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
go mod tidy -v
go mod why -m github.com/alexsnet/go-vnc || true

Length of output: 24910


Remove indirect marker for github.com/alexsnet/go-vnc and tidy module

The output of your verification confirms that pkg/js/libs/vnc/vnc.go imports github.com/alexsnet/go-vnc directly:

# github.com/alexsnet/go-vnc
github.com/projectdiscovery/nuclei/v3/pkg/js/libs/vnc
github.com/alexsnet/go-vnc

Accordingly, update your go.mod:

-	github.com/alexsnet/go-vnc v0.1.0 // indirect
+	github.com/alexsnet/go-vnc v0.1.0

Then run:

go mod tidy

to ensure the module file is clean and accurate.

🤖 Prompt for AI Agents
In go.mod around line 147, the dependency github.com/alexsnet/go-vnc is marked
as // indirect but is imported directly by pkg/js/libs/vnc/vnc.go; remove the
indirect marker by making the dependency direct (e.g., run go get
github.com/alexsnet/go-vnc@v0.1.0 or update the requirement entry so it is not
commented as indirect) and then run go mod tidy to clean up go.mod/go.sum and
commit the updated files.

Comment on lines +61 to +65
if !protocolstate.IsHostAllowed(executionId, host) {
// host is not valid according to network policy
return false, protocolstate.ErrHostDenied.Msgf(host)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Include port in network-policy check to handle IPv6 and port-scoped rules.

Passing only the host can misclassify IPv6 literals and bypass/over-block port-scoped policies. Use host:port.

-	if !protocolstate.IsHostAllowed(executionId, host) {
+	addr := net.JoinHostPort(host, strconv.Itoa(port))
+	if !protocolstate.IsHostAllowed(executionId, addr) {
 		// host is not valid according to network policy
-		return false, protocolstate.ErrHostDenied.Msgf(host)
+		return false, protocolstate.ErrHostDenied.Msgf(addr)
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if !protocolstate.IsHostAllowed(executionId, host) {
// host is not valid according to network policy
return false, protocolstate.ErrHostDenied.Msgf(host)
}
addr := net.JoinHostPort(host, strconv.Itoa(port))
if !protocolstate.IsHostAllowed(executionId, addr) {
// host is not valid according to network policy
return false, protocolstate.ErrHostDenied.Msgf(addr)
}
🤖 Prompt for AI Agents
In pkg/js/libs/vnc/vnc.go around lines 61 to 65, the network-policy check
currently passes only the host which misclassifies IPv6 literals and ignores
port-scoped rules; change the check to pass the host with port (host:port)
instead — format IPv6 literals with brackets (e.g. [ipv6]:port) when composing
the address, then call protocolstate.IsHostAllowed(executionId, hostWithPort)
and return protocolstate.ErrHostDenied.Msgf(hostWithPort) on denial so policy
evaluations correctly consider both address and port.

Comment on lines +66 to +70
dialer := protocolstate.GetDialersWithId(executionId)
if dialer == nil {
return false, fmt.Errorf("dialers not initialized for %s", executionId)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Nil-check Fastdialer to avoid nil deref.

Dialers may be present but Fastdialer nil during early init or in restricted contexts.

 	dialer := protocolstate.GetDialersWithId(executionId)
 	if dialer == nil {
 		return false, fmt.Errorf("dialers not initialized for %s", executionId)
 	}
+	if dialer.Fastdialer == nil {
+		return false, fmt.Errorf("fastdialer not initialized for %s", executionId)
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dialer := protocolstate.GetDialersWithId(executionId)
if dialer == nil {
return false, fmt.Errorf("dialers not initialized for %s", executionId)
}
dialer := protocolstate.GetDialersWithId(executionId)
if dialer == nil {
return false, fmt.Errorf("dialers not initialized for %s", executionId)
}
if dialer.Fastdialer == nil {
return false, fmt.Errorf("fastdialer not initialized for %s", executionId)
}
🤖 Prompt for AI Agents
In pkg/js/libs/vnc/vnc.go around lines 66 to 70, the code checks dialer for nil
but does not verify that dialer.Fastdialer is non-nil; add a nil-check for
dialer.Fastdialer immediately after confirming dialer exists and before any use
to avoid a nil pointer dereference, and return an appropriate error (e.g., false
and fmt.Errorf("fastdialer not initialized for %s", executionId)) or handle the
missing fastdialer case gracefully (log/propagate) consistent with surrounding
error handling.

Comment on lines +71 to +81
conn, err := dialer.Fastdialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
if err != nil {
return false, err
}
defer func() {
_ = conn.Close()
}()

// Set connection timeout
_ = conn.SetDeadline(time.Now().Add(10 * time.Second))

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Propagate context and set a timeout for dialing; avoid context.TODO.

Use a bounded context for the dial and reuse the same for the handshake; deadline on the net.Conn alone doesn’t cancel the dialing attempt.

-	conn, err := dialer.Fastdialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	addr := net.JoinHostPort(host, strconv.Itoa(port))
+	conn, err := dialer.Fastdialer.Dial(ctx, "tcp", addr)
 	if err != nil {
 		return false, err
 	}
 	defer func() {
 		_ = conn.Close()
 	}()
 
 	// Set connection timeout
-	_ = conn.SetDeadline(time.Now().Add(10 * time.Second))
+	_ = conn.SetDeadline(time.Now().Add(10 * time.Second))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
conn, err := dialer.Fastdialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
if err != nil {
return false, err
}
defer func() {
_ = conn.Close()
}()
// Set connection timeout
_ = conn.SetDeadline(time.Now().Add(10 * time.Second))
// Propagate a 10s timeout into the dial (so the dial itself will be canceled if it hangs)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
addr := net.JoinHostPort(host, strconv.Itoa(port))
conn, err := dialer.Fastdialer.Dial(ctx, "tcp", addr)
if err != nil {
return false, err
}
defer func() {
_ = conn.Close()
}()
// Also set a deadline on the established connection for the handshake/read/write
_ = conn.SetDeadline(time.Now().Add(10 * time.Second))
🤖 Prompt for AI Agents
In pkg/js/libs/vnc/vnc.go around lines 71 to 81, replace the use of context.TODO
and the lone conn.SetDeadline with a bounded context that is used for dialing
and the subsequent handshake: create a ctx, cancel :=
context.WithTimeout(parentCtxOrBackground, 10*time.Second) and defer cancel(),
call dialer.Fastdialer.Dial(ctx, ...) so the dial can be canceled by the
timeout, reuse that same ctx when performing the VNC handshake, and if you still
set a conn deadline derive it from ctx.Deadline() (if present) rather than
hardcoding time.Now().Add(...); ensure the cancel() is deferred immediately
after ctx creation.

Comment on lines +85 to +93
// Attempt to connect and authenticate
c, err := vnclib.Connect(context.TODO(), conn, vncConfig)
if err != nil {
// Check for specific authentication errors
if isAuthError(err) {
return false, nil // Authentication failed, but connection succeeded
}
return false, err // Connection or other error
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Reuse the same bounded context for the VNC handshake.

Avoid context.TODO so the handshake obeys the same timeout/cancellation.

-	c, err := vnclib.Connect(context.TODO(), conn, vncConfig)
+	c, err := vnclib.Connect(ctx, conn, vncConfig)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Attempt to connect and authenticate
c, err := vnclib.Connect(context.TODO(), conn, vncConfig)
if err != nil {
// Check for specific authentication errors
if isAuthError(err) {
return false, nil // Authentication failed, but connection succeeded
}
return false, err // Connection or other error
}
// Attempt to connect and authenticate
c, err := vnclib.Connect(ctx, conn, vncConfig)
if err != nil {
// Check for specific authentication errors
if isAuthError(err) {
return false, nil // Authentication failed, but connection succeeded
}
return false, err // Connection or other error
}
🤖 Prompt for AI Agents
In pkg/js/libs/vnc/vnc.go around lines 85 to 93, the handshake call uses
context.TODO(), which ignores the caller's timeout/cancellation; replace
context.TODO() with the function's context parameter (ctx) so the vnclib.Connect
call uses the same bounded context; if the function currently lacks a
context.Context parameter, add one to the signature and propagate it through all
callers so the VNC connect/handshake obeys the caller's timeout and
cancellation.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/integration-test/javascript.go (1)

185-196: Fix shadowed ‘pool’: tests skip and purging may not work.
Using := here creates a local pool and leaves the package-level pool nil; Execute() methods then skip due to pool == nil. Replace with assignment to the global.

 func init() {
 	// uses a sensible default on windows (tcp/http) and linux/osx (socket)
-	pool, err := dockertest.NewPool("")
+	var err error
+	pool, err = dockertest.NewPool("")
🧹 Nitpick comments (4)
cmd/integration-test/javascript.go (4)

19-20: Gate VNC test on Windows/macOS to match other JS tests and avoid Docker/platform quirks.
Add the same DisableOn guard used by other tests.

-	{Path: "protocols/javascript/vnc-pass-brute.yaml", TestCase: &javascriptVncPassBrute{}},
+	{Path: "protocols/javascript/vnc-pass-brute.yaml", TestCase: &javascriptVncPassBrute{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},

116-136: Make dockertest Retry actually retry; fix misleading comment.
The closure always returns nil, so Retry never retries. Also the comment mentions SSH in the Oracle test.

 	errs := []error{}
 	for i := 0; i < defaultRetry; i++ {
 		results := []string{}
 		var err error
-		_ = pool.Retry(func() error {
-			//let ssh server start
+		err = pool.Retry(func() error {
+			// let oracle server start
 			time.Sleep(3 * time.Second)
-			results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
-			return nil
+			var innerErr error
+			results, innerErr = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
+			return innerErr
 		})
 		if err != nil {
 			return err
 		}

138-168: VNC Execute: enable real retries and fix the comment.
Same Retry issue and SSH copy-paste comment here.

 	for i := 0; i < defaultRetry; i++ {
 		results := []string{}
 		var err error
-		_ = pool.Retry(func() error {
-			//let ssh server start
+		err = pool.Retry(func() error {
+			// let vnc server start
 			time.Sleep(3 * time.Second)
-			results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
-			return nil
+			var innerErr error
+			results, innerErr = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
+			return innerErr
 		})
 		if err != nil {
 			return err
 		}

255-271: Increase VNC container expiration to reduce flakiness.
This image is heavy and often needs >30s to be ready, especially under emulation (linux/amd64 on ARM). Give it more headroom.

-	// by default expire after 30 sec
-	if err := vncResource.Expire(30); err != nil {
+	// give more headroom for UI/VNC to come up
+	if err := vncResource.Expire(90); err != nil {
 		log.Printf("Could not expire resource: %s", err)
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e83382d and 521a21c.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (2)
  • cmd/integration-test/javascript.go (3 hunks)
  • go.mod (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • go.mod
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • cmd/integration-test/javascript.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 (1)
cmd/integration-test/javascript.go (1)

26-27: LGTM on new resource variable.
Consistent with existing resources.

@Mzack9999 Mzack9999 merged commit 46555bc into dev Sep 12, 2025
31 of 32 checks passed
@Mzack9999 Mzack9999 deleted the feat-4842-vnc branch September 12, 2025 11:17
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.

VNC Enhancement

1 participant