Skip to content

Add STARTTLS support to testssl-inspector#197

Open
ahmedhxssam wants to merge 1 commit into
GRCEngClub:mainfrom
ahmedhxssam:fix-165-starttls-testssl
Open

Add STARTTLS support to testssl-inspector#197
ahmedhxssam wants to merge 1 commit into
GRCEngClub:mainfrom
ahmedhxssam:fix-165-starttls-testssl

Conversation

@ahmedhxssam

@ahmedhxssam ahmedhxssam commented Jun 15, 2026

Copy link
Copy Markdown

Summary

Adds --starttls=<proto> support to the testssl-inspector scan wrapper so users can scan STARTTLS services such as SMTP, IMAP, POP3, FTP, LDAP, Postgres, MySQL, and SMTPS.

Changes

  • Parses --starttls=<proto> in scan.js
  • Validates supported STARTTLS protocols
  • Rejects unknown protocols with EXIT.USAGE
  • Defaults target ports when no explicit port is provided
  • Preserves explicit target ports like mail.example.com:587
  • Passes --starttls <proto> through to testssl.sh
  • Updates commands/scan.md and README.md

Verification

Syntax check:

node --check plugins/connectors/testssl-inspector/scripts/scan.js
echo $?

Result:

0

Contract fixture validation:

bash tests/validate-contract-fixtures.sh
echo $?

Result:

All 49 fixture(s) valid.
0

Happy-path STARTTLS argument parsing:

node plugins/connectors/testssl-inspector/scripts/scan.js --target=mail.example.com --starttls=smtp --no-docker --output=json
echo $?

Result:

[testssl-inspector] testssl.sh not on PATH. Install via: brew install testssl (macOS), apt install testssl.sh (Debian/Ubuntu), or git clone https://github.com/testssl/testssl.sh ~/.local/share/testssl.sh && export PATH="$HOME/.local/share/testssl.sh:$PATH". Or rerun with --docker.
3

This confirms --starttls=smtp is no longer rejected as an unknown flag. The command reaches runner/tool resolution, but testssl.sh is not installed locally.

Explicit port preservation smoke test:

node plugins/connectors/testssl-inspector/scripts/scan.js --target=mail.example.com:587 --starttls=smtp --no-docker --output=json
echo $?

Result:

[testssl-inspector] testssl.sh not on PATH. Install via: brew install testssl (macOS), apt install testssl.sh (Debian/Ubuntu), or git clone https://github.com/testssl/testssl.sh ~/.local/share/testssl.sh && export PATH="$HOME/.local/share/testssl.sh:$PATH". Or rerun with --docker.
3

This confirms an explicit-port STARTTLS command is accepted and reaches runner/tool resolution.

Unknown protocol path:

node plugins/connectors/testssl-inspector/scripts/scan.js --target=mail.example.com --starttls=bogus --output=json
echo $?

Result:

[testssl-inspector] unknown STARTTLS protocol: bogus. Supported protocols: smtp, imap, pop3, ftp, ldap, postgres, mysql, smtps
2

Closes #165

Summary by CodeRabbit

  • New Features

    • Added STARTTLS support for scanning multiple protocol endpoints (SMTP, IMAP, etc.) with automatic default port assignment and explicit port override capability.
  • Documentation

    • Updated documentation to explain STARTTLS protocol usage with practical examples demonstrating both default and explicit port handling.

@ahmedhxssam ahmedhxssam requested a review from a team as a code owner June 15, 2026 09:41
@qodo-code-review

qodo-code-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0)

Context used
✅ Compliance rules (platform): 17 rules

Grey Divider


Action required

1. Node script in connector plugin 📘 Rule violation ⌂ Architecture
Description
The modified plugins/connectors/testssl-inspector/scripts/scan.js is a Node.js entrypoint located
under a non-allowed (non-persona) plugin directory. This violates the requirement that Node.js
scripts only exist under the allowed persona plugins, creating compliance and runtime-governance
risk.
Code

plugins/connectors/testssl-inspector/scripts/scan.js[R35-46]

+const STARTTLS_PORTS = Object.freeze({
+  smtp: 25,
+  imap: 143,
+  pop3: 110,
+  ftp: 21,
+  ldap: 389,
+  postgres: 5432,
+  mysql: 3306,
+  smtps: 465,
+});
+
+const SUPPORTED_STARTTLS = Object.keys(STARTTLS_PORTS).join(', ');
Evidence
PR Compliance ID 396516 restricts Node.js scripts to specific persona plugins only. The PR modifies
plugins/connectors/testssl-inspector/scripts/scan.js (a Node.js script) within a connector plugin
path, which is outside the allowed persona plugin set.

Rule 396516: Restrict Node.js scripts to allowed persona plugins
plugins/connectors/testssl-inspector/scripts/scan.js[35-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`plugins/connectors/testssl-inspector/scripts/scan.js` is a Node.js runtime entrypoint, but it lives under `plugins/connectors/...`, which is not one of the allowed persona plugins.

## Issue Context
Compliance policy restricts Node.js scripts to persona plugins named exactly: `grc-engineer`, `grc-auditor`, `grc-internal`, or `grc-tprm`. This PR modifies a Node.js script in a connector plugin, which violates that restriction.

## Fix Focus Areas
- plugins/connectors/testssl-inspector/scripts/scan.js[35-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Docker JSON path mismatch 🐞 Bug ☼ Reliability
Description
In Docker mode the JSON output path is generated as a container path (/tmp/scan-out/...), but
runTestssl() later reads that same path on the host filesystem, so --docker scans will fail when
trying to load the JSON results.
Code

plugins/connectors/testssl-inspector/scripts/scan.js[R238-256]

  const out = outDir || CACHE_DIR;
  const jsonPath = path.join(out, `testssl-raw-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.json`);
  const base = [
    '--quiet', '--warnings', 'off', '--color', '0',
    '--jsonfile-pretty', jsonPath,
  ];
  if (mode === 'fast') base.push('--fast');
+  if (starttls) {
+    base.push('--starttls', starttls);
+  }
  base.push(target);
  base.__jsonPath = jsonPath;
  return base;
}

-async function runTestssl(runner, target, mode, log) {
+async function runTestssl(runner, target, mode, starttls, log) {
  const argv = runner.argv(target, mode);
  const jsonPath = argv.__jsonPath;
  log(`scanning ${target}`);
Evidence
The docker runner mounts CACHE_DIR into the container at /tmp/scan-out and calls testsslArgs() with
outDir '/tmp/scan-out', which makes __jsonPath a container-only path. runTestssl() then reads
__jsonPath directly from the host filesystem, where /tmp/scan-out is not the mounted directory, so
the JSON read will fail.

plugins/connectors/testssl-inspector/scripts/scan.js[173-186]
plugins/connectors/testssl-inspector/scripts/scan.js[237-260]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
In `--docker` mode, `testsslArgs()` sets `argv.__jsonPath` to a container path (e.g. `/tmp/scan-out/...json`). After `docker run` completes, `runTestssl()` uses `fs.readFile(jsonPath)` on the host, which should instead read from `${CACHE_DIR}/...json` (the bind-mounted directory).

### Issue Context
Docker binds `${CACHE_DIR}` (host) to `/tmp/scan-out` (container). The JSON file is written inside the container to `/tmp/scan-out/<file>`, which appears on the host at `${CACHE_DIR}/<file>`.

### Fix Focus Areas
- plugins/connectors/testssl-inspector/scripts/scan.js[173-201]
- plugins/connectors/testssl-inspector/scripts/scan.js[237-263]

### Suggested approach
- Generate a filename once (e.g. `const fname = ...`), and set:
 - `containerJsonPath = path.posix.join('/tmp/scan-out', fname)` for the `--jsonfile-pretty` argument.
 - `hostJsonPath = path.join(CACHE_DIR, fname)` for `base.__jsonPath`.
- Alternatively, keep `--jsonfile-pretty` pointing at the container path but translate `argv.__jsonPath` to the host path in the docker runner (e.g., replace the `/tmp/scan-out/` prefix with `${CACHE_DIR}/` before reading).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Error target not resolved 🐞 Bug ◔ Observability
Description
When STARTTLS default-port expansion is applied, failures still record/log the original target
(without the appended port), so stderr and the JSON errors[] output can disagree with the actual
scan target.
Code

plugins/connectors/testssl-inspector/scripts/scan.js[R89-94]

+      const finalTarget = withDefaultStarttlsPort(target, args.starttls);
+      const raw = await runTestssl(runner, finalTarget, mode, args.starttls, log);
+      const doc = normalizeTargetFindings(raw, finalTarget, runId, runner.version, expansion);
      findings.push(doc);
    } catch (err) {
      errors.push({ target, error: err.message });
Evidence
The scan and normalization run against finalTarget, but on error the code uses target (original
string) in both the logged message and the errors array, so the reported target may omit the
effective port that was actually used.

plugins/connectors/testssl-inspector/scripts/scan.js[87-96]
plugins/connectors/testssl-inspector/scripts/scan.js[230-235]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`finalTarget` (with default STARTTLS port appended) is used for scanning and for normalization, but the `catch` path still logs/persists the original `target`. This makes troubleshooting confusing for STARTTLS scans when the user omitted an explicit port.

### Issue Context
This only affects the error path (when a scan throws). Successful scans already use `finalTarget` for `metadata.target`.

### Fix Focus Areas
- plugins/connectors/testssl-inspector/scripts/scan.js[87-97]
- plugins/connectors/testssl-inspector/scripts/scan.js[230-235]

### Suggested approach
- In the loop, compute `finalTarget` outside the try/catch (or store it in a variable accessible to the catch).
- In the catch block, log and store `finalTarget` as the primary `target` value.
- Optionally include both values, e.g. `{ target: finalTarget, original_target: target, error: ... }`. This preserves user input while accurately reflecting what was attempted.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

STARTTLS support is added to the testssl-inspector connector. scan.js gains a --starttls=<proto> CLI option backed by a protocol→default-port lookup table, per-target port rewriting, protocol validation, and forwarding through resolveRunner and testsslArgs into the testssl.sh invocation. scan.md and README.md are updated to document the new flag and behavior.

Changes

STARTTLS Support for testssl-inspector

Layer / File(s) Summary
STARTTLS protocol table, arg parsing, target rewriting, and runner plumbing
plugins/connectors/testssl-inspector/scripts/scan.js
Adds STARTTLS_DEFAULTS protocol→port map and derived supported-protocols list. Extends parseArgs to accept --starttls=<proto> with validation against the supported set (exits with code 2 on unknown protocol) and initializes starttls state to null. Updates the per-target loop to call withDefaultStarttlsPort when --starttls is set. Threads starttls through resolveRunner, into both Docker and non-Docker argv construction, and into testsslArgs/runTestssl. Adds withDefaultStarttlsPort(target, starttls) helper and extends testsslArgs to emit --starttls <proto> before the target.
scan.md and README.md documentation
plugins/connectors/testssl-inspector/commands/scan.md, plugins/connectors/testssl-inspector/README.md
Adds --starttls=<proto> to the options table in scan.md with port-default behavior; replaces generic scan examples with STARTTLS invocations (SMTP default port, SMTP explicit port, IMAP); revises Targets and scope to reflect STARTTLS is now wired in. Updates README.md Scope to state HTTPS is the default and enumerate STARTTLS protocols with their default ports and port-handling rules.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hop hop, the scanner grows,
Now it speaks in SMTP flows,
IMAP, POP3, ports galore,
--starttls=smtp opens the door,
No more dropping to the CLI,
This bunny wired it — my oh my! ✉️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 clearly and concisely describes the main change: adding STARTTLS support to the testssl-inspector plugin.
Linked Issues check ✅ Passed The PR fully implements all requirements from issue #165: accepts --starttls flag, validates protocols, defaults ports, updates documentation, and passes validation tests.
Out of Scope Changes check ✅ Passed All changes are directly related to adding STARTTLS support across documentation and the scan.js script, with no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add STARTTLS support to testssl-inspector scan wrapper
✨ Enhancement 📝 Documentation 🕐 10-20 Minutes

Grey Divider

Walkthroughs

Description
• Add --starttls= to enable scanning STARTTLS services via testssl.sh.
• Validate allowed STARTTLS protocols and default ports; preserve explicit target ports.
• Document STARTTLS usage and examples in README and scan command docs.
Diagram
graph TD
  A["scan.js (CLI)"] --> B["parseArgs()"] --> C["STARTTLS ports map"] --> D["withDefaultStarttlsPort()"] --> E["resolveRunner()/testsslArgs()"] --> F["testssl.sh"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Pass through `--starttls` without protocol allowlist/port defaults
  • ➕ Less wrapper logic; automatically supports any future testssl STARTTLS modes
  • ➖ Worse UX: users must always supply correct ports
  • ➖ No early validation; errors shift to testssl output/exit codes
2. Use a host/port parser that handles IPv6 literals explicitly
  • ➕ Avoids false 'port present' detection for IPv6 targets containing ':'
  • ➕ Clearer and more robust target normalization
  • ➖ More code and/or a new dependency
  • ➖ Slightly larger surface area to test

Recommendation: Current approach (explicit allowlist + default-port inference + passthrough to testssl) is a good UX/robustness balance. Consider tightening target parsing for IPv6 (':' detection) if IPv6 targets are in scope, and remove/avoid unused parameters (e.g., runTestssl currently receives starttls but doesn’t use it directly).

Grey Divider

File Changes

Enhancement (1)
scan.js Parse/validate '--starttls', infer ports, and pass through to testssl +46/-10

Parse/validate '--starttls', infer ports, and pass through to testssl

• Adds a STARTTLS protocol allowlist with default ports, parses '--starttls=<proto>' with usage errors for unknown values, and appends a default port when a target has none. Threads the STARTTLS value into runner argument construction so '--starttls <proto>' is forwarded to testssl.sh for both docker and local runners.

plugins/connectors/testssl-inspector/scripts/scan.js


Documentation (2)
README.md Document STARTTLS protocols and default-port behavior +12/-1

Document STARTTLS protocols and default-port behavior

• Replaces the prior HTTPS-only scope note with STARTTLS support documentation. Lists supported protocols with their default ports and explains default-port insertion vs explicit-port preservation.

plugins/connectors/testssl-inspector/README.md


scan.md Add '--starttls' option docs and STARTTLS examples +14/-4

Add '--starttls' option docs and STARTTLS examples

• Documents the new '--starttls=<proto>' flag, including supported protocols and port defaulting rules. Adds example commands for SMTP/IMAP STARTTLS scans and updates scope wording to reflect STARTTLS support.

plugins/connectors/testssl-inspector/commands/scan.md


Grey Divider

Qodo Logo

@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown

Greptile Summary

This PR wires --starttls=<proto> support into the testssl-inspector scan wrapper, allowing users to inspect TLS on SMTP, IMAP, POP3, FTP, LDAP, PostgreSQL, MySQL, and SMTPS endpoints. Argument parsing validates and lower-cases the protocol, injects a default port when none is given, and passes --starttls <proto> through to testssl.sh.

  • Core logic (scan.js): adds STARTTLS_PORTS map, withDefaultStarttlsPort helper, updated parseArgs/testsslArgs/resolveRunner, and threads starttls through the runner closure.
  • Docs (scan.md, README.md): lists supported protocols with default ports and adds three new usage examples.

Confidence Score: 3/5

Functional for the happy path, but the output document will contain a wrong URI scheme for every STARTTLS scan until the normalizer is made protocol-aware.

The --starttls argument is correctly validated, port-defaulted, and threaded through to testssl.sh. However, normalizeTargetFindings is never told about the protocol, so resource.uri is hard-coded to https:// for all targets — an SMTP scan on port 25 will emit uri: "https://mail.example.com:25/". Any downstream tool that trusts that field (CMDB ingestion, deduplication, display) will misclassify the resource.

plugins/connectors/testssl-inspector/scripts/scan.js — specifically normalizeTargetFindings and runTestssl

Important Files Changed

Filename Overview
plugins/connectors/testssl-inspector/scripts/scan.js Adds STARTTLS argument parsing, validation, default-port injection, and pass-through to testssl.sh. Two issues: resource.uri is hard-coded to https:// regardless of protocol (wrong for SMTP/IMAP/etc.), and the starttls parameter added to runTestssl is dead code.
plugins/connectors/testssl-inspector/commands/scan.md Documents the new --starttls=<proto> flag, default-port behavior, and adds STARTTLS usage examples. No issues found.
plugins/connectors/testssl-inspector/README.md Updates the Scope section to list supported STARTTLS protocols with their default ports. Accurate and consistent with the implementation.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["CLI argv"] -->|"--starttls=smtp"| B["parseArgs()"]
    B -->|"proto not in STARTTLS_PORTS"| C["fail EXIT.USAGE"]
    B -->|"valid proto"| D["args.starttls = proto"]
    D --> E["resolveRunner({ starttls })"]
    E -->|"useDocker"| F["runner.argv = (t,m) => docker + testsslArgs(t,m,starttls,outDir)"]
    E -->|"binary"| G["runner.argv = (t,m) => testsslArgs(t,m,starttls)"]
    D --> H["withDefaultStarttlsPort(target, starttls)"]
    H -->|"target has ':'"| I["preserve explicit port"]
    H -->|"no ':' in target"| J["append STARTTLS_PORTS[proto]"]
    I --> K["runTestssl(runner, finalTarget, mode, log)"]
    J --> K
    K --> L["runner.argv(target, mode)"]
    L --> M["testsslArgs() includes '--starttls proto'"]
    M --> N["testssl.sh invocation"]
    N --> O["normalizeTargetFindings()"]
    O -->|"⚠ always https://"| P["resource.uri = https://host:port/"]
Loading

Comments Outside Diff (1)

  1. plugins/connectors/testssl-inspector/scripts/scan.js, line 554-566 (link)

    P1 Incorrect https:// scheme in resource.uri for STARTTLS scans

    normalizeTargetFindings is not passed starttls, so resource.uri is hard-coded to https:// for every target. A scan of mail.example.com:25 with --starttls=smtp will emit uri: "https://mail.example.com:25/" — a semantically wrong URI that misrepresents the service type to any downstream consumer that parses this field (e.g., deduplication, CMDB ingestion, or display tooling).

    The fix requires threading starttls into normalizeTargetFindings and deriving the scheme from the protocol (smtp://, imap://, ldap://, etc.), or at minimum using a generic tls:// scheme for non-HTTPS endpoints.

    Fix in Claude Code Fix in Codex Fix in Cursor

Fix All in Claude Code Fix All in Codex Fix All in Cursor

Reviews (1): Last reviewed commit: "Add STARTTLS support to testssl-inspecto..." | Re-trigger Greptile

}

async function runTestssl(runner, target, mode, log) {
async function runTestssl(runner, target, mode, starttls, log) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 The starttls parameter added to runTestssl is never read inside the function body. The --starttls flag is already baked into the runner.argv closure built by resolveRunner, so the argument has no effect here. The dead parameter may mislead future maintainers into thinking they can call runTestssl with a different starttls value and get a different result.

Suggested change
async function runTestssl(runner, target, mode, starttls, log) {
async function runTestssl(runner, target, mode, log) {

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex Fix in Cursor

Comment on lines +35 to +46
const STARTTLS_PORTS = Object.freeze({
smtp: 25,
imap: 143,
pop3: 110,
ftp: 21,
ldap: 389,
postgres: 5432,
mysql: 3306,
smtps: 465,
});

const SUPPORTED_STARTTLS = Object.keys(STARTTLS_PORTS).join(', ');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Node script in connector plugin 📘 Rule violation ⌂ Architecture

The modified plugins/connectors/testssl-inspector/scripts/scan.js is a Node.js entrypoint located
under a non-allowed (non-persona) plugin directory. This violates the requirement that Node.js
scripts only exist under the allowed persona plugins, creating compliance and runtime-governance
risk.
Agent Prompt
## Issue description
`plugins/connectors/testssl-inspector/scripts/scan.js` is a Node.js runtime entrypoint, but it lives under `plugins/connectors/...`, which is not one of the allowed persona plugins.

## Issue Context
Compliance policy restricts Node.js scripts to persona plugins named exactly: `grc-engineer`, `grc-auditor`, `grc-internal`, or `grc-tprm`. This PR modifies a Node.js script in a connector plugin, which violates that restriction.

## Fix Focus Areas
- plugins/connectors/testssl-inspector/scripts/scan.js[35-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 238 to 256
const out = outDir || CACHE_DIR;
const jsonPath = path.join(out, `testssl-raw-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.json`);
const base = [
'--quiet', '--warnings', 'off', '--color', '0',
'--jsonfile-pretty', jsonPath,
];
if (mode === 'fast') base.push('--fast');
if (starttls) {
base.push('--starttls', starttls);
}
base.push(target);
base.__jsonPath = jsonPath;
return base;
}

async function runTestssl(runner, target, mode, log) {
async function runTestssl(runner, target, mode, starttls, log) {
const argv = runner.argv(target, mode);
const jsonPath = argv.__jsonPath;
log(`scanning ${target}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Docker json path mismatch 🐞 Bug ☼ Reliability

In Docker mode the JSON output path is generated as a container path (/tmp/scan-out/...), but
runTestssl() later reads that same path on the host filesystem, so --docker scans will fail when
trying to load the JSON results.
Agent Prompt
### Issue description
In `--docker` mode, `testsslArgs()` sets `argv.__jsonPath` to a container path (e.g. `/tmp/scan-out/...json`). After `docker run` completes, `runTestssl()` uses `fs.readFile(jsonPath)` on the host, which should instead read from `${CACHE_DIR}/...json` (the bind-mounted directory).

### Issue Context
Docker binds `${CACHE_DIR}` (host) to `/tmp/scan-out` (container). The JSON file is written inside the container to `/tmp/scan-out/<file>`, which appears on the host at `${CACHE_DIR}/<file>`.

### Fix Focus Areas
- plugins/connectors/testssl-inspector/scripts/scan.js[173-201]
- plugins/connectors/testssl-inspector/scripts/scan.js[237-263]

### Suggested approach
- Generate a filename once (e.g. `const fname = ...`), and set:
  - `containerJsonPath = path.posix.join('/tmp/scan-out', fname)` for the `--jsonfile-pretty` argument.
  - `hostJsonPath = path.join(CACHE_DIR, fname)` for `base.__jsonPath`.
- Alternatively, keep `--jsonfile-pretty` pointing at the container path but translate `argv.__jsonPath` to the host path in the docker runner (e.g., replace the `/tmp/scan-out/` prefix with `${CACHE_DIR}/` before reading).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@plugins/connectors/testssl-inspector/scripts/scan.js`:
- Around line 230-234: The withDefaultStarttlsPort function incorrectly detects
explicit ports by checking if target.includes(':'), which treats IPv6 addresses
as having explicit ports even when they don't (e.g., [2001:db8::1] has colons
but no port). Fix the port detection logic to properly handle IPv6 literals in
square brackets: if the target starts with '[', check whether there's a colon
after the closing bracket ']' to determine if a port is specified; otherwise,
check for the presence of a colon to determine if a port exists. This ensures
the default port is correctly appended only when no explicit port is provided.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 84983c7b-e419-4c9f-94bc-9b7adf3c4081

📥 Commits

Reviewing files that changed from the base of the PR and between 42cdc08 and 5db7073.

📒 Files selected for processing (3)
  • plugins/connectors/testssl-inspector/README.md
  • plugins/connectors/testssl-inspector/commands/scan.md
  • plugins/connectors/testssl-inspector/scripts/scan.js

Comment on lines +230 to +234
function withDefaultStarttlsPort(target, starttls) {
if (!starttls) return target;
if (target.includes(':')) return target;

return `${target}:${STARTTLS_PORTS[starttls]}`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix explicit-port detection for IPv6 targets

target.includes(':') treats IPv6 host literals as “has explicit port”, so --starttls=<proto> won’t append the default port for targets like [2001:db8::1]. That breaks the “append default port when port is omitted” behavior.

Suggested patch
 function withDefaultStarttlsPort(target, starttls) {
   if (!starttls) return target;
-  if (target.includes(':')) return target;
+  const hasExplicitPort = target.startsWith('[')
+    ? /^\[[^\]]+\]:\d+$/.test(target)   // bracketed IPv6 with :port
+    : /:\d+$/.test(target);             // hostname/IPv4 with :port
+  if (hasExplicitPort) return target;
 
   return `${target}:${STARTTLS_PORTS[starttls]}`;
 }
🤖 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 `@plugins/connectors/testssl-inspector/scripts/scan.js` around lines 230 - 234,
The withDefaultStarttlsPort function incorrectly detects explicit ports by
checking if target.includes(':'), which treats IPv6 addresses as having explicit
ports even when they don't (e.g., [2001:db8::1] has colons but no port). Fix the
port detection logic to properly handle IPv6 literals in square brackets: if the
target starts with '[', check whether there's a colon after the closing bracket
']' to determine if a port is specified; otherwise, check for the presence of a
colon to determine if a port exists. This ensures the default port is correctly
appended only when no explicit port is provided.

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.

Add STARTTLS protocol support to testssl-inspector

1 participant