updating deny-packages config option to deny exact version or wildcard

This commit is contained in:
Brandon Teng
2024-04-04 13:25:54 -05:00
parent 0e665bf3ac
commit 411e5ec44f
3 changed files with 157 additions and 121 deletions
+51 -112
View File
@@ -1,100 +1,11 @@
import {expect, jest, test} from '@jest/globals' import {expect, jest, test} from '@jest/globals'
import {Change, Changes} from '../src/schemas' import {Change, Changes} from '../src/schemas'
import {
let getDeniedChanges: Function createMavenTestChange,
createPipTestChange,
const npmChange: Change = { createRubyTestChange,
manifest: 'package.json', createTestChange
change_type: 'added', } from './fixtures/create-test-change'
ecosystem: 'npm',
name: 'Reeuhq',
version: '1.0.2',
package_url: 'pkg:npm/[email protected]',
license: 'MIT',
source_repository_url: 'github.com/some-repo',
scope: 'runtime',
vulnerabilities: [
{
severity: 'critical',
advisory_ghsa_id: 'first-random_string',
advisory_summary: 'very dangerous',
advisory_url: 'github.com/future-funk'
}
]
}
const rubyChange: Change = {
change_type: 'added',
manifest: 'Gemfile.lock',
ecosystem: 'rubygems',
name: 'actionsomething',
version: '3.2.0',
package_url: 'pkg:gem/[email protected]',
license: 'BSD',
source_repository_url: 'github.com/some-repo',
scope: 'runtime',
vulnerabilities: [
{
severity: 'moderate',
advisory_ghsa_id: 'second-random_string',
advisory_summary: 'not so dangerous',
advisory_url: 'github.com/future-funk'
},
{
severity: 'low',
advisory_ghsa_id: 'third-random_string',
advisory_summary: 'dont page me',
advisory_url: 'github.com/future-funk'
}
]
}
const pipChange: Change = {
change_type: 'added',
manifest: 'requirements.txt',
ecosystem: 'pip',
name: 'package-1',
version: '1.1.1',
package_url: 'pkg:pypi/[email protected]',
license: 'MIT',
source_repository_url: 'github.com/some-repo',
scope: 'runtime',
vulnerabilities: [
{
severity: 'moderate',
advisory_ghsa_id: 'second-random_string',
advisory_summary: 'not so dangerous',
advisory_url: 'github.com/future-funk'
},
{
severity: 'low',
advisory_ghsa_id: 'third-random_string',
advisory_summary: 'dont page me',
advisory_url: 'github.com/future-funk'
}
]
}
const mvnChange: Change = {
change_type: 'added',
manifest: 'pom.xml',
ecosystem: 'maven',
name: 'org.apache.logging.log4j:log4j-core',
version: '2.15.0',
package_url: 'pkg:maven/org.apache.logging.log4j/[email protected]',
license: 'Apache-2.0',
source_repository_url:
'https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core',
scope: 'unknown',
vulnerabilities: [
{
severity: 'critical',
advisory_ghsa_id: 'second-random_string',
advisory_summary: 'not so dangerous',
advisory_url: 'github.com/future-funk'
}
]
}
jest.mock('@actions/core') jest.mock('@actions/core')
@@ -108,6 +19,12 @@ const mockOctokit = {
} }
} }
let getDeniedChanges: Function
let npmChange: Change
let rubyChange: Change
let pipChange: Change
let mvnChange: Change
jest.mock('octokit', () => { jest.mock('octokit', () => {
return { return {
// eslint-disable-next-line @typescript-eslint/no-extraneous-class // eslint-disable-next-line @typescript-eslint/no-extraneous-class
@@ -128,13 +45,18 @@ beforeEach(async () => {
}) })
// eslint-disable-next-line @typescript-eslint/no-require-imports // eslint-disable-next-line @typescript-eslint/no-require-imports
;({getDeniedChanges} = require('../src/deny')) ;({getDeniedChanges} = require('../src/deny'))
npmChange = createTestChange()
rubyChange = createRubyTestChange()
pipChange = createPipTestChange()
mvnChange = createMavenTestChange()
}) })
test('it adds packages in the deny packages list', async () => { test('denies packages from the deny packages list', async () => {
const changes: Changes = [npmChange, rubyChange] const changes: Changes = [npmChange, rubyChange]
const deniedChanges = await getDeniedChanges( const deniedChanges = await getDeniedChanges(
changes, changes,
['pkg:gem/actionsomething'], ['pkg:gem/actionsomething@3.2.0'],
[] []
) )
@@ -142,7 +64,35 @@ test('it adds packages in the deny packages list', async () => {
expect(deniedChanges.length).toEqual(1) expect(deniedChanges.length).toEqual(1)
}) })
test('it adds packages in the deny group list', async () => { test('denies packages only for the specified version from deny packages list', async () => {
const packageWithDifferentVersion = 'pkg:npm/[email protected]'
const changes: Changes = [npmChange]
const deniedChanges = await getDeniedChanges(
changes,
[packageWithDifferentVersion],
[]
)
expect(deniedChanges.length).toEqual(0)
})
test('if no specified version from deny packages list, it will treat package as wildcard and deny all versions', async () => {
const changes: Changes = [
createTestChange({name: 'lodash', version: '1.2.3'}),
createTestChange({name: 'lodash', version: '4.5.6'}),
createTestChange({name: 'lodash', version: '7.8.9'})
]
const denyAllLodashVersions = 'pkg:npm/lodash'
const deniedChanges = await getDeniedChanges(
changes,
[denyAllLodashVersions],
[]
)
expect(deniedChanges.length).toEqual(3)
})
test('denies packages from the deny group list', async () => {
const changes: Changes = [mvnChange, rubyChange] const changes: Changes = [mvnChange, rubyChange]
const deniedChanges = await getDeniedChanges( const deniedChanges = await getDeniedChanges(
changes, changes,
@@ -154,23 +104,12 @@ test('it adds packages in the deny group list', async () => {
expect(deniedChanges.length).toEqual(1) expect(deniedChanges.length).toEqual(1)
}) })
test('it adds packages outside of the deny lists', async () => { test('allows packages not defined in the deny packages and groups list', async () => {
const changes: Changes = [npmChange, pipChange] const changes: Changes = [npmChange, pipChange]
const deniedChanges = await getDeniedChanges( const deniedChanges = await getDeniedChanges(
changes, changes,
['pkg:gem/actionsomething'], ['pkg:gem/[email protected]'],
['pkg:maven:org.apache.logging.log4j'] ['pkg:maven:org.apache.logging.not-in-list']
)
expect(deniedChanges.length).toEqual(0)
})
test('it adds packages with versions', async () => {
const changes: Changes = [npmChange]
const deniedChanges = await getDeniedChanges(
changes,
['pkg:npm/[email protected]'],
['pkg:maven:org.apache.logging.log4j']
) )
expect(deniedChanges.length).toEqual(0) expect(deniedChanges.length).toEqual(0)
+96 -3
View File
@@ -1,7 +1,7 @@
import {Change} from '../../src/schemas' import {Change} from '../../src/schemas'
import {createTestVulnerability} from './create-test-vulnerability' import {createTestVulnerability} from './create-test-vulnerability'
const defaultChange: Change = { const defaultNpmChange: Change = {
change_type: 'added', change_type: 'added',
manifest: 'package.json', manifest: 'package.json',
ecosystem: 'npm', ecosystem: 'npm',
@@ -28,9 +28,102 @@ const defaultChange: Change = {
] ]
} }
const defaultRubyChange: Change = {
change_type: 'added',
manifest: 'Gemfile.lock',
ecosystem: 'rubygems',
name: 'actionsomething',
version: '3.2.0',
package_url: 'pkg:gem/[email protected]',
license: 'BSD',
source_repository_url: 'github.com/some-repo',
scope: 'runtime',
vulnerabilities: [
{
severity: 'moderate',
advisory_ghsa_id: 'second-random_string',
advisory_summary: 'not so dangerous',
advisory_url: 'github.com/future-funk'
},
{
severity: 'low',
advisory_ghsa_id: 'third-random_string',
advisory_summary: 'dont page me',
advisory_url: 'github.com/future-funk'
}
]
}
const defaultPipChange: Change = {
change_type: 'added',
manifest: 'requirements.txt',
ecosystem: 'pip',
name: 'package-1',
version: '1.1.1',
package_url: 'pkg:pypi/[email protected]',
license: 'MIT',
source_repository_url: 'github.com/some-repo',
scope: 'runtime',
vulnerabilities: [
{
severity: 'moderate',
advisory_ghsa_id: 'second-random_string',
advisory_summary: 'not so dangerous',
advisory_url: 'github.com/future-funk'
},
{
severity: 'low',
advisory_ghsa_id: 'third-random_string',
advisory_summary: 'dont page me',
advisory_url: 'github.com/future-funk'
}
]
}
const defaultMavenChange: Change = {
change_type: 'added',
manifest: 'pom.xml',
ecosystem: 'maven',
name: 'org.apache.logging.log4j:log4j-core',
version: '2.15.0',
package_url: 'pkg:maven/org.apache.logging.log4j/[email protected]',
license: 'Apache-2.0',
source_repository_url:
'https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core',
scope: 'unknown',
vulnerabilities: [
{
severity: 'critical',
advisory_ghsa_id: 'second-random_string',
advisory_summary: 'not so dangerous',
advisory_url: 'github.com/future-funk'
}
]
}
const createTestChange = (overwrites: Partial<Change> = {}): Change => ({ const createTestChange = (overwrites: Partial<Change> = {}): Change => ({
...defaultChange, ...defaultNpmChange,
...overwrites ...overwrites
}) })
export {createTestChange} const createRubyTestChange = (overwrites: Partial<Change> = {}): Change => ({
...defaultRubyChange,
...overwrites
})
const createPipTestChange = (overwrites: Partial<Change> = {}): Change => ({
...defaultPipChange,
...overwrites
})
const createMavenTestChange = (overwrites: Partial<Change> = {}): Change => ({
...defaultMavenChange,
...overwrites
})
export {
createTestChange,
createRubyTestChange,
createPipTestChange,
createMavenTestChange
}
+10 -6
View File
@@ -16,12 +16,16 @@ export async function getDeniedChanges(
if (deniedPackages) { if (deniedPackages) {
for (const denied of deniedPackages) { for (const denied of deniedPackages) {
const [dpName, dpVersion] = denied.toLowerCase().split('@') const [dpName, dpVersion] = denied.toLowerCase().split('@')
if (name === dpName && version !== dpVersion) { if (dpVersion) {
continue if (name === dpName && version === dpVersion) {
} changesDenied.push(change)
if (name === dpName && version === dpVersion) { failed = true
changesDenied.push(change) }
failed = true } else {
if (name === dpName) {
changesDenied.push(change)
failed = true
}
} }
} }
} }