diff --git a/docs/install/audit.md b/docs/install/audit.md new file mode 100644 index 0000000000..a3b615b7b5 --- /dev/null +++ b/docs/install/audit.md @@ -0,0 +1,37 @@ +`bun pm audit` checks your installed packages for known security vulnerabilities. + +Run the command in a project with a `bun.lock` file: + +```bash +$ bun pm audit +``` + +Bun sends the list of installed packages and versions to NPM, and prints a report of any vulnerabilities that were found. Packages installed from registries other than the default registry are skipped. + +If no vulnerabilities are found, the command prints: + +``` +No vulnerabilities found +``` + +When vulnerabilities are detected, each affected package is listed along with the severity, a short description and a link to the advisory. At the end of the report Bun prints a summary and hints for updating: + +``` +3 vulnerabilities (1 high, 2 moderate) +To update all dependencies to the latest compatible versions: + bun update +To update all dependencies to the latest versions (including breaking changes): + bun update --latest +``` + +### `--json` + +Use the `--json` flag to print the raw JSON response from the registry instead of the formatted report: + +```bash +$ bun pm audit --json +``` + +### Exit code + +`bun pm audit` will exit with code `0` if no vulnerabilities are found and `1` if the report lists any vulnerabilities. This will still happen even if `--json` is passed. diff --git a/docs/nav.ts b/docs/nav.ts index 5cebfd11f6..8f4c112b32 100644 --- a/docs/nav.ts +++ b/docs/nav.ts @@ -207,6 +207,9 @@ export default { description: "Patch dependencies in your project to fix bugs or add features without vendoring the entire package.", }), + page("install/audit", "Audit dependencies", { + description: "Check installed packages for vulnerabilities.", + }), page("install/npmrc", ".npmrc support", { description: "Bun supports loading some configuration options from .npmrc", }), diff --git a/src/cli/audit_command.zig b/src/cli/audit_command.zig index 87fc8d90e8..0ee26b2502 100644 --- a/src/cli/audit_command.zig +++ b/src/cli/audit_command.zig @@ -98,6 +98,26 @@ pub const AuditCommand = struct { if (json_output) { Output.writer().writeAll(response_text) catch {}; Output.writer().writeByte('\n') catch {}; + + if (response_text.len > 0) { + const source = logger.Source.initPathString("audit-response.json", response_text); + var log = logger.Log.init(ctx.allocator); + defer log.deinit(); + + const expr = @import("../json_parser.zig").parse(&source, &log, ctx.allocator, true) catch { + Output.prettyErrorln("error: audit request failed to parse json. Is the registry down?", .{}); + return 1; // If we can't parse then safe to assume a similar failure + }; + + // If the response is an empty object, no vulnerabilities + if (expr.data == .e_object and expr.data.e_object.properties.len == 0) { + return 0; + } + + // If there's any content in the response, there are vulnerabilities + return 1; + } + return 0; } else if (response_text.len > 0) { const exit_code = try printEnhancedAuditReport(ctx.allocator, response_text, pm, &dependency_tree); diff --git a/test/cli/install/__snapshots__/bun-audit.test.ts.snap b/test/cli/install/__snapshots__/bun-audit.test.ts.snap index 40cb335d30..154c97cfe1 100644 --- a/test/cli/install/__snapshots__/bun-audit.test.ts.snap +++ b/test/cli/install/__snapshots__/bun-audit.test.ts.snap @@ -80,7 +80,7 @@ To update all dependencies to the latest versions (including breaking changes): exports[`\`bun pm audit\` should print valid JSON and exit 0 when --json is passed and there are no vulnerabilities: bun-audit-expect-valid-json-stdout-report-no-vulnerabilities 1`] = `{}`; -exports[`\`bun pm audit\` should print valid JSON and exit 0 when --json is passed and there are vulnerabilities: bun-audit-expect-valid-json-stdout-report-vulnerabilities 1`] = ` +exports[`\`bun pm audit\` should print valid JSON and exit 1 when --json is passed and there are vulnerabilities: bun-audit-expect-valid-json-stdout-report-vulnerabilities 1`] = ` { "base64-url": [ { diff --git a/test/cli/install/bun-audit.test.ts b/test/cli/install/bun-audit.test.ts index 5cce28e51e..037a3370f1 100644 --- a/test/cli/install/bun-audit.test.ts +++ b/test/cli/install/bun-audit.test.ts @@ -164,8 +164,8 @@ describe("`bun pm audit`", () => { }, }); - doAuditTest("should print valid JSON and exit 0 when --json is passed and there are vulnerabilities", { - exitCode: 0, + doAuditTest("should print valid JSON and exit 1 when --json is passed and there are vulnerabilities", { + exitCode: 1, files: fixture("express@3"), args: ["--json"], fn: async ({ stdout }) => {