Skip to content

Commit

Permalink
Adds a warning when the hardened mode is enabled (#5969)
Browse files Browse the repository at this point in the history
**What's the problem this PR addresses?**

It's currently difficult to spot that the hardened mode is enabled;
people upgrading to Yarn 4 will think that the resolution is slower due
to a bug, without noticing that the slowdown is caused by the extra
check on the remote registry.

**How did you fix it?**

This diff adds a warning prior to the install when the hardened mode is
enabled.

I'd also like to be smarter in a subsequent diff and skip the hardened
mode when the user is the repository admin, but that will be for a
separate PR.

**Checklist**
<!--- Don't worry if you miss something, chores are automatically
tested. -->
<!--- This checklist exists to help you remember doing the chores when
you submit a PR. -->
<!--- Put an `x` in all the boxes that apply. -->
- [x] I have read the [Contributing
Guide](https://yarnpkg.com/advanced/contributing).

<!-- See
https://yarnpkg.com/advanced/contributing#preparing-your-pr-to-be-released
for more details. -->
<!-- Check with `yarn version check` and fix with `yarn version check
-i` -->
- [x] I have set the packages that need to be released for my changes to
be effective.

<!-- The "Testing chores" workflow validates that your PR follows our
guidelines. -->
<!-- If it doesn't pass, click on it to see details as to what your PR
might be missing. -->
- [x] I will check that all automated PR checks pass before the PR gets
reviewed.
  • Loading branch information
arcanis authored Nov 13, 2023
1 parent 872df6d commit de2e5aa
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 17 deletions.
10 changes: 10 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
34 changes: 34 additions & 0 deletions .yarn/versions/84eaca3b.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
releases:
"@yarnpkg/cli": patch
"@yarnpkg/core": patch
"@yarnpkg/plugin-essentials": patch

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-exec"
- "@yarnpkg/plugin-file"
- "@yarnpkg/plugin-git"
- "@yarnpkg/plugin-github"
- "@yarnpkg/plugin-http"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-link"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/doctor"
- "@yarnpkg/extensions"
- "@yarnpkg/nm"
- "@yarnpkg/pnpify"
- "@yarnpkg/sdks"
6 changes: 5 additions & 1 deletion packages/docusaurus/docs/features/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ You can exclude your `devDependencies` (and their transitive dependencies) from

## Hardened mode

The hardened mode can be set (or disabled) using either the `enableHardenedMode` setting, or by defining `YARN_ENABLE_HARDENED_MODE` in your environment variables, but in most cases you won't even have to think about it - the hardened mode is enabled by default when Yarn detects it runs in a pull request from a public GitHub repository.
The hardened mode can be set (or disabled) using either the `enableHardenedMode` setting or by defining `YARN_ENABLE_HARDENED_MODE=1|0` in your environment variables, but in most cases you won't even have to think about it - the hardened mode is enabled by default when Yarn detects it runs in a pull request from a public GitHub repository.

Under this mode, Yarn will automatically enable the `--check-resolutions` and `--refresh-lockfile` flags when running `yarn install`, which should protect you against most attacks caused by [lockfile poisoning](https://snyk.io/blog/why-npm-lockfiles-can-be-a-security-blindspot-for-injecting-malicious-modules/), at the cost of a little bit of install speed.

:::warning
The hardened mode makes installs significantly slower as Yarn has to query the registry to make sure the information contained in the lockfile are accurate. If your CI pipeline runs multiple jobs, we recommend disabling the hardened mode in all but one of them so as to limit the performance impact.
:::
13 changes: 13 additions & 0 deletions packages/plugin-essentials/sources/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,19 @@ export default class YarnCommand extends BaseCommand {

const enableHardenedMode = configuration.get(`enableHardenedMode`);

if (enableHardenedMode && typeof configuration.sources.get(`enableHardenedMode`) === `undefined`) {
await StreamReport.start({
configuration,
json: this.json,
stdout: this.context.stdout,
includeFooter: false,
}, async report => {
report.reportWarning(MessageName.UNNAMED, `Yarn detected that the current workflow is executed from a public pull request. For safety the hardened mode has been enabled.`);
report.reportWarning(MessageName.UNNAMED, `It will prevent malicious lockfile manipulations, in exchange for a slower install time. You can opt-out if necessary; check our ${formatUtils.applyHyperlink(configuration, `documentation`, `https://yarnpkg.com/features/security#hardened-mode`)} for more details.`);
report.reportSeparator();
});
}

if (this.refreshLockfile ?? enableHardenedMode)
project.lockfileNeedsRefresh = true;

Expand Down
1 change: 1 addition & 0 deletions packages/yarnpkg-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"tunnel": "^0.0.6"
},
"devDependencies": {
"@octokit/webhooks-types": "^7.3.1",
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^11.0.1",
Expand Down
39 changes: 23 additions & 16 deletions packages/yarnpkg-core/sources/Configuration.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {WebhookEvent} from '@octokit/webhooks-types';
import {Filename, PortablePath, npath, ppath, xfs} from '@yarnpkg/fslib';
import {parseSyml, stringifySyml} from '@yarnpkg/parsers';
import camelcase from 'camelcase';
Expand Down Expand Up @@ -31,16 +32,25 @@ import * as structUtils
import {IdentHash, Package, Descriptor, PackageExtension, PackageExtensionType, PackageExtensionStatus, Locator} from './types';

const isPublicRepository = (function () {
if (GITHUB_ACTIONS && process.env.GITHUB_EVENT_PATH) {
const githubEventPath = npath.toPortablePath(process.env.GITHUB_EVENT_PATH);
try {
return !(xfs.readJsonSync(githubEventPath).repository?.private ?? true);
} catch (err) {
return false;
}
if (!GITHUB_ACTIONS || !process.env.GITHUB_EVENT_PATH)
return false;

const githubEventPath = npath.toPortablePath(process.env.GITHUB_EVENT_PATH);

let data: WebhookEvent;
try {
data = xfs.readJsonSync(githubEventPath) as WebhookEvent;
} catch {
return false;
}

return false;
if (!(`repository` in data) || !data.repository)
return false;

if (data.repository.private ?? true)
return false;

return true;
})();

export const LEGACY_PLUGINS = new Set([
Expand Down Expand Up @@ -872,15 +882,13 @@ function getDefaultValue(configuration: Configuration, definition: SettingsDefin
result.set(propKey, getDefaultValue(configuration, propDefinition));

return result;
} break;

}
case SettingsType.MAP: {
if (definition.isArray && !ignoreArrays)
return [];

return new Map<string, any>();
} break;

}
case SettingsType.ABSOLUTE_PATH: {
if (definition.default === null)
return null;
Expand All @@ -904,11 +912,10 @@ function getDefaultValue(configuration: Configuration, definition: SettingsDefin
return ppath.resolve(configuration.projectCwd, definition.default);
}
}
} break;

}
default: {
return definition.default;
} break;
}
}
}

Expand Down Expand Up @@ -1906,7 +1913,7 @@ export class Configuration {

default: {
miscUtils.assertNever(extension);
} break;
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3424,6 +3424,13 @@ __metadata:
languageName: node
linkType: hard

"@octokit/webhooks-types@npm:^7.3.1":
version: 7.3.1
resolution: "@octokit/webhooks-types@npm:7.3.1"
checksum: c4da1e1eb94a90c2e79e158f6e6d935aa099340f7cccac3449feca4cd4e2b5b5b04bbb8414310791d421b3451cd5b0685f498f1bcec6af85d2c14803dae2e1b8
languageName: node
linkType: hard

"@polka/url@npm:^1.0.0-next.20":
version: 1.0.0-next.21
resolution: "@polka/url@npm:1.0.0-next.21"
Expand Down Expand Up @@ -5038,6 +5045,7 @@ __metadata:
resolution: "@yarnpkg/core@workspace:packages/yarnpkg-core"
dependencies:
"@arcanis/slice-ansi": "npm:^1.1.1"
"@octokit/webhooks-types": "npm:^7.3.1"
"@rollup/plugin-commonjs": "npm:^21.0.1"
"@rollup/plugin-json": "npm:^6.0.0"
"@rollup/plugin-node-resolve": "npm:^11.0.1"
Expand Down

0 comments on commit de2e5aa

Please sign in to comment.