Skip to content

Feature/xray 144147 onboard yarn v4#778

Open
gauriy-tech wants to merge 9 commits into
jfrog:devfrom
gauriy-tech:feature/XRAY-144147-onboard-yarn-v4
Open

Feature/xray 144147 onboard yarn v4#778
gauriy-tech wants to merge 9 commits into
jfrog:devfrom
gauriy-tech:feature/XRAY-144147-onboard-yarn-v4

Conversation

@gauriy-tech

@gauriy-tech gauriy-tech commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
  • The pull request is targeting the dev branch.
  • The code has been validated to compile successfully by running go vet ./....
  • The code has been formatted properly using go fmt ./....
  • All static analysis checks passed.
  • All tests have passed. If this feature is not already covered by the tests, new tests have been added.
  • Updated the Contributing page / ReadMe page / CI Workflow files if needed.
  • All changes are detailed at the description. if not already covered at JFrog Documentation, new documentation have been added.

What

Onboards Yarn V4 (Berry, native .yarnrc.yml mode) to jf curation-audit (jf ca),
and unifies Yarn V3 + V4 curation on a metadata-only lockfile resolution path.

Why / Design

jf ca must build a complete yarn.lock to enumerate the dependency graph, without
downloading tarballs (curation blocks blocked tarballs with a 403, which aborts a normal
install before the lockfile is written).
Approaches considered:

  • yarn install --mode=update-lockfile (previous V3 behavior): rejected — it still
    fetches uncached tarballs to compute checksums, so a curation 403 on a blocked uncached
    package aborts before yarn.lock is written.
  • Hosted plugin via yarn plugin import <url>: rejected — adds a runtime network
    dependency, breaks air-gapped CI.
  • .yarnrc.yml flags (enableNetwork: false, etc.): rejected — doesn't produce a
    complete lockfile for uncached packages.
  • Chosen: embedded resolution-only plugin (jfrog-yarn-resolve-lockfile.cjs, //go:embed).
    It calls project.resolveEverything() + project.persistLockfile() — resolving the full
    graph from registry metadata only (no tarball fetch), so blocked packages never abort
    the lockfile. The plugin is written into the per-run temp dir, never the customer's project.
    V3 behavior change (intentional): V3 curation previously used --mode=update-lockfile;
    it now uses the same embedded plugin as V4. V3 had the identical tarball-fetch abort problem,
    so this gives V3 strictly better behavior and keeps V3/V4 on one code path.

Highlights

  • Yarn V4 native mode: registry + auth read from .yarnrc.yml (no jf yarn-config step).
  • Non-invasive: all resolution happens in a temp copy; the only touch to the original project
    is bumping yarn.lock mtime so the next run can skip re-resolution.
  • Full workspace coverage: attachWorkspaceMembersToRoot audits every workspace member's
    dependencies from the root, matching npm/pnpm.
  • --run-native is a no-op for Yarn V4 (always native) with a deferred warning.
  • V1 is rejected up front with an actionable message; V2 falls back to direct-dependency probing.

Tests

  • TestRegisterYarnPluginInYarnrc, TestAttachWorkspaceMembersToRoot (yarn package)
  • TestPromoteYarnWorkspaceMember incl. the $HOME-stop case (curation package)


V4 operates in native mode: registry URL and auth token come from
.yarnrc.yml (local or ~/.yarnrc.yml written by yarn config set --home)
instead of requiring jf yarn-config / yarn.yaml.

Key changes:

yarn.go
- Remove V4 rejection from verifyYarnVersionSupportedForCuration and
  configureYarnResolutionServerAndRunInstall (only V1 is now rejected).
- resolveCurationLockfileDir: copy project to temp dir before running
  install (mirrors pnpm), so the customer's checkout is never modified.
- For V4 curation: yarnCurationRegistry() rewrites api/npm/ →
  api/curation/audit/, then runYarnConfigSet sets a global npmAuthToken
  in the temp .yarnrc.yml so the rewritten URL authenticates correctly
  (the original token is scoped to api/npm/ and does not match the
  curation endpoint).
- GetNativeYarnV4RegistryConfig: reads npmRegistryServer via
  yarn config get; reads npmAuthToken via direct YAML parsing of
  .yarnrc.yml and ~/.yarnrc.yml (yarn config get is unreliable for
  nested keys).
- runYarnCommandQuiet: capture stdout+stderr on failure and emit as
  Debug log so failed-install diagnosis is visible.

curationaudit.go
- setRepoFromYarnrcForYarnV4: calls SetDepsRepo(repoName) in addition
  to setPackageManagerConfig. Both are required — PackageManagerConfig
  drives auth; SetDepsRepo populates params.DependenciesRepository so
  the curation endpoint URL is constructed in
  configureYarnResolutionServerAndRunInstall (was always "" before,
  causing the V4 branch to be skipped and the install to hit api/npm/
  instead of api/curation/audit/).
- resolveNpmYarnTech: detect V4 projects that have .yarnrc.yml (created
  by yarn set version 4) without a pre-existing yarn.lock, and projects
  using a global ~/.yarnrc.yml (--home setup); guard with
  package-lock.json absence to avoid npm misidentification.
- validateRunNativeForTech: accept --run-native for Yarn as a no-op
  (V4 is always native; flag has no effect but should not error).
- SetRepo: detect V4 via version check and route to
  setRepoFromYarnrcForYarnV4; make version-detection failures explicit
  errors instead of silent fallbacks.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from ef1823e to e29283f Compare June 18, 2026 10:49
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from ab03730 to d07e8b3 Compare June 19, 2026 06:13
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from d07e8b3 to d615404 Compare June 19, 2026 07:07
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from d615404 to 9fd40e0 Compare June 19, 2026 11:53
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from 9fd40e0 to 8981284 Compare June 19, 2026 18:08
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from 8981284 to 79d1ae5 Compare June 19, 2026 18:45
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from 79d1ae5 to d9e1352 Compare June 19, 2026 19:31
…param refactor

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread commands/curation/curationaudit.go Outdated
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from 10b8a8e to a904623 Compare June 25, 2026 04:15
@gauriy-tech gauriy-tech added the safe to test Approve running integration tests on a pull request label Jun 25, 2026
@github-actions github-actions Bot removed the safe to test Approve running integration tests on a pull request label Jun 25, 2026
@gauriy-tech gauriy-tech added the safe to test Approve running integration tests on a pull request label Jun 25, 2026
@github-actions github-actions Bot removed the safe to test Approve running integration tests on a pull request label Jun 25, 2026
@gauriy-tech

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@gauriy-tech gauriy-tech added the safe to test Approve running integration tests on a pull request label Jun 29, 2026
@github-actions github-actions Bot removed the safe to test Approve running integration tests on a pull request label Jun 29, 2026
@attiasas attiasas requested a review from a team June 29, 2026 07:11
@attiasas attiasas added improvement Automatically generated release notes safe to test Approve running integration tests on a pull request labels Jun 29, 2026
@github-actions github-actions Bot removed the safe to test Approve running integration tests on a pull request label Jun 29, 2026

@attiasas attiasas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice work!, check out my comments

In addition, please add integration tests at: curation_test.go

Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go
Comment thread commands/curation/curationaudit.go
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go
@gauriy-tech gauriy-tech added the safe to test Approve running integration tests on a pull request label Jun 29, 2026
@github-actions github-actions Bot removed the safe to test Approve running integration tests on a pull request label Jun 29, 2026
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-144147-onboard-yarn-v4 branch from a8f884d to 298fe3e Compare June 29, 2026 10:09
@gauriy-tech gauriy-tech added the safe to test Approve running integration tests on a pull request label Jun 29, 2026
@github-actions github-actions Bot removed the safe to test Approve running integration tests on a pull request label Jun 29, 2026
@github-actions

Copy link
Copy Markdown

🚨 Frogbot scanned this pull request and found the below:

📗 Scan Summary

  • Frogbot scanned for vulnerabilities and found 1 issues
Scan Category Status Security Issues
Software Composition Analysis ✅ Done Not Found
Contextual Analysis ✅ Done -
Static Application Security Testing (SAST) ✅ Done
1 Issues Found 1 High
Secrets ✅ Done -
Infrastructure as Code (IaC) ✅ Done Not Found

Comment thread curation_test.go
}
// npm packument lookup (resolve-only plugin); tarball GETs contain "/-/".
if body := yarnPackument(r); body != "" {
_, err := w.Write([]byte(body))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Static Application Security Testing (SAST) Vulnerability

Severity Finding
high
High
Untrusted input is included in web page content
Full description

Vulnerability Details

Rule ID: go-xss

Overview

Cross-Site Scripting (XSS) is a vulnerability that allows attackers to inject
malicious scripts into web pages viewed by other users. These scripts can steal
sensitive information, hijack user sessions, deface websites, or redirect users
to malicious sites.

Vulnerable example

func displayMessage(w http.ResponseWriter, r *http.Request) {
    message := r.URL.Query().Get("message")
    fmt.Fprintf(w, "<h1>%s</h1>", message)
}

In this example, the displayMessage function retrieves a message from the
query parameters and directly embeds it into an HTML response without any
escaping. This makes it vulnerable to XSS attacks as an attacker could craft
a malicious message containing JavaScript code.

Remediation

To mitigate XSS vulnerabilities, always sanitize and encode user input before
embedding it into HTML responses:

func displayMessage(w http.ResponseWriter, r *http.Request) {
    message := r.URL.Query().Get("message")
    tpl.Execute(w, html.EscapeString(message))
}

In the remediation, we've introduced the html/template package to properly
escape and sanitize the message before embedding it into the HTML response.
We use html.EscapeString to mark the message as safe HTML content, ensuring it's
not escaped by the template engine.

Code Flows
Vulnerable data flow analysis result

↘️ r.Host (at curation_test.go line 274)

↘️ "http://" + r.Host (at curation_test.go line 274)

↘️ "http://" + r.Host + "/api/npm/npms/" (at curation_test.go line 274)

↘️ base (at curation_test.go line 277)

↘️ fmt.Sprintf({"name":"xml","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.1":{"name":"xml","version":"1.0.1","dist":{"shasum":"97e0d0e9603c6ffd00fbf5419b3f48a6f4e0c7d9","tarball":"%sxml/-/xml-1.0.1.tgz"}}}}, base) (at curation_test.go line 277)

↘️ yarnPackument(r) (at curation_test.go line 256)

↘️ body (at curation_test.go line 257)




Comment on lines +1248 to +1251
Dependencies map[string]string `json:"dependencies"`
DevDependencies map[string]string `json:"devDependencies"`
OptionalDependencies map[string]string `json:"optionalDependencies"`
PeerDependencies map[string]string `json:"peerDependencies"`

@attiasas attiasas Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

omitempty is missing?

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

Labels

improvement Automatically generated release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants