Skip to content

Commit

Permalink
fix: appending on existing pre-release
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-ippolito committed Mar 25, 2024
1 parent 095c9dc commit cd2b5b8
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 30 deletions.
20 changes: 0 additions & 20 deletions lib/github/templates/security-pos-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,3 @@ following issues.
%REPORTS%
---

# Summary

The Node.js project will release new versions of the %AFFECTED_VERSIONS%
releases lines on or shortly after, %RELEASE_DATE% in order to address:

%VULNERABILITIES%

## Impact

%IMPACT%

## Release timing

Releases will be available on, or shortly after, %RELEASE_DATE%.

## Contact and future updates

The current Node.js security policy can be found at <https://nodejs.org/en/security/>. Please follow the process outlined in <https://github.com/nodejs/node/blob/master/SECURITY.md> if you wish to report a vulnerability in Node.js.

Subscribe to the low-volume announcement-only nodejs-sec mailing list at <https://groups.google.com/forum/#!forum/nodejs-sec> to stay up to date on security vulnerabilities and security-related releases of Node.js and the projects maintained in the nodejs GitHub organization.
2 changes: 1 addition & 1 deletion lib/prepare_security.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class SecurityReleaseSteward {
const req = new Request(credentials);
const release = new PrepareSecurityRelease(req);
const releaseDate = await release.promptReleaseDate(cli);
validateDate(releaseDate);
if (releaseDate !== 'TBD') validateDate(releaseDate);
const createVulnerabilitiesJSON = await release.promptVulnerabilitiesJSON(cli);

let securityReleasePRUrl;
Expand Down
52 changes: 43 additions & 9 deletions lib/security_blog.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,39 @@ export default class SecurityBlog {
affectedVersions: this.getAffectedVersions(content),
vulnerabilities: this.getVulnerabilities(content),
slug: this.getSlug(releaseDate),
impact: this.getImpact(content),
openSSLUpdate: await this.promptOpenSSLUpdate(cli),
author: await this.promptAuthor(cli),
reports: content.reports,
dependencyUpdates: await this.promptDependencyUpdates(cli)
};
const month = releaseDate.toLocaleString('en-US', { month: 'long' }).toLowerCase();
const year = releaseDate.getFullYear();
const fileName = `${month}-${year}-security-releases.md`;
const posRelease = await this.buildPosRelease(template, data);
const file = path.join(process.cwd(), fileName);
fs.writeFileSync(file, posRelease);
cli.ok(`Pos-release announcement file created at ${file}`);

const pathPreRelease = await this.promptExistingPreRelease(cli);
// read the existing pre-release announcement
let preReleaseContent = fs.readFileSync(pathPreRelease, 'utf-8');
// cut the part before summary
const preSummary = preReleaseContent.indexOf('# Summary');
if (preSummary !== -1) {
preReleaseContent = preReleaseContent.substring(preSummary);
}

const updatedContent = posRelease + preReleaseContent;

fs.writeFileSync(pathPreRelease, updatedContent);
cli.ok(`Pos-release announcement file updated at ${pathPreRelease}`);
}

async promptExistingPreRelease(cli) {
const pathPreRelease = await cli.prompt(
'Please provide the path of the existing pre-release announcement:', {
questionType: 'input',
defaultAnswer: ''
});

if (!pathPreRelease || !fs.existsSync(path.resolve(pathPreRelease))) {
return this.promptExistingPreRelease(cli);
}
return pathPreRelease;
}

promptDependencyUpdates(cli) {
Expand Down Expand Up @@ -170,12 +190,21 @@ export default class SecurityBlog {
for (const report of reports) {
let cveId = report.cve_ids.join(', ');
if (!cveId) {
// TODO(@marco-ippolito): fetch the CVE ID from hackerone
cveId = await this.cli.prompt(`What is the CVE ID for vulnerability https://hackerone.com/reports/${report.id} ${report.title}?`, {
questionType: 'input',
defaultAnswer: 'TBD'
});
// TODO(@marco-ippolito): save the cve_id in the vulnerabilities JSON
report.cve_ids = [cveId];
}
template += `\n## ${report.title} (${cveId}) - (${report.severity.rating})\n\n`;
if (!report.summary) {
// TODO(@marco-ippolito): fetch the summary
// from hackerone and update the vulnerabilities JSON
this.cli.warn(`Summary is missing for vulnerability:\
${report.link}. Please add it manually.`);
}
template += `${report.summary}\n\n`;
const releaseLines = report.affectedVersions.join(', ');
template += `Impact:\n\n- This vulnerability affects all users\
Expand All @@ -202,8 +231,8 @@ and thank you ${contributor} for fixing it.\n`;

getOpenSSLUpdateTemplate(openSSLUpdate) {
if (!openSSLUpdate) return '';
return '## OpenSSL Security updates\n\n' +
'This security release includes OpenSSL security updates';
return '\n## OpenSSL Security updates\n\n' +
'This security release includes OpenSSL security updates\n';
}

getSlug(releaseDate) {
Expand Down Expand Up @@ -246,6 +275,11 @@ and thank you ${contributor} for fixing it.\n`;
for (const [key, value] of Object.entries(impact)) {
const groupedByRating = Object.values(_.groupBy(value, 'severity.rating'))
.map(severity => {
if (!severity[0]?.severity?.rating || severity[0]?.severity?.rating === 'TBD') {
this.cli.error(`Invalid severity rating for vulnerability ${severity[0].link}`);
// TODO(@marco-ippolito): ask to fetch the severity rating from hackerone
process.exit(1);
}
const firstSeverityRating = severity[0].severity.rating.toLocaleLowerCase();
return `${severity.length} ${firstSeverityRating} severity issues`;
}).join(', ');
Expand Down

0 comments on commit cd2b5b8

Please sign in to comment.