@@ -19,7 +19,7 @@ const npmChange: Change = {
1919 vulnerabilities : [
2020 {
2121 severity : 'critical' ,
22- advisory_ghsa_id : 'first-random_string ' ,
22+ advisory_ghsa_id : 'vulnerable-ghsa-id ' ,
2323 advisory_summary : 'very dangerous' ,
2424 advisory_url : 'github.com/future-funk'
2525 }
@@ -39,13 +39,13 @@ const rubyChange: Change = {
3939 vulnerabilities : [
4040 {
4141 severity : 'moderate' ,
42- advisory_ghsa_id : 'second-random_string ' ,
42+ advisory_ghsa_id : 'moderate-ghsa-id ' ,
4343 advisory_summary : 'not so dangerous' ,
4444 advisory_url : 'github.com/future-funk'
4545 } ,
4646 {
4747 severity : 'low' ,
48- advisory_ghsa_id : 'third-random_string ' ,
48+ advisory_ghsa_id : 'low-ghsa-id ' ,
4949 advisory_summary : 'dont page me' ,
5050 advisory_url : 'github.com/future-funk'
5151 }
@@ -65,6 +65,64 @@ const noVulnNpmChange: Change = {
6565 vulnerabilities : [ ]
6666}
6767
68+ const lodashChange : Change = {
69+ change_type : 'added' ,
70+ manifest : 'package.json' ,
71+ ecosystem : 'npm' ,
72+ name : 'lodash' ,
73+ version : '4.17.0' ,
74+ package_url :
'pkg:npm/[email protected] ' , 75+ license : 'MIT' ,
76+ source_repository_url : 'https://github.com/lodash/lodash' ,
77+ scope : 'runtime' ,
78+ vulnerabilities : [
79+ {
80+ severity : 'critical' ,
81+ advisory_ghsa_id : 'GHSA-jf85-cpcp-j695' ,
82+ advisory_summary : 'Prototype Pollution in lodash' ,
83+ advisory_url : 'https://github.com/advisories/GHSA-jf85-cpcp-j695'
84+ } ,
85+ {
86+ severity : 'high' ,
87+ advisory_ghsa_id : 'GHSA-4xc9-xhrj-v574' ,
88+ advisory_summary : 'Prototype Pollution in lodash' ,
89+ advisory_url : 'https://github.com/advisories/GHSA-4xc9-xhrj-v574'
90+ } ,
91+ {
92+ severity : 'high' ,
93+ advisory_ghsa_id : 'GHSA-35jh-r3h4-6jhm' ,
94+ advisory_summary : 'Command Injection in lodash' ,
95+ advisory_url : 'https://github.com/advisories/GHSA-35jh-r3h4-6jhm'
96+ } ,
97+ {
98+ severity : 'high' ,
99+ advisory_ghsa_id : 'GHSA-p6mc-m468-83gw' ,
100+ advisory_summary : 'Prototype Pollution in lodash' ,
101+ advisory_url : 'https://github.com/advisories/GHSA-p6mc-m468-83gw'
102+ } ,
103+ {
104+ severity : 'moderate' ,
105+ advisory_ghsa_id : 'GHSA-x5rq-j2xg-h7qm' ,
106+ advisory_summary :
107+ 'Regular Expression Denial of Service (ReDoS) in lodash' ,
108+ advisory_url : 'https://github.com/advisories/GHSA-x5rq-j2xg-h7qm'
109+ } ,
110+ {
111+ severity : 'moderate' ,
112+ advisory_ghsa_id : 'GHSA-29mw-wpgm-hmr9' ,
113+ advisory_summary :
114+ 'Regular Expression Denial of Service (ReDoS) in lodash' ,
115+ advisory_url : 'https://github.com/advisories/GHSA-29mw-wpgm-hmr9'
116+ } ,
117+ {
118+ severity : 'low' ,
119+ advisory_ghsa_id : 'GHSA-fvqr-27wr-82fm' ,
120+ advisory_summary : 'Prototype Pollution in lodash' ,
121+ advisory_url : 'https://github.com/advisories/GHSA-fvqr-27wr-82fm'
122+ }
123+ ]
124+ }
125+
68126test ( 'it properly filters changes by severity' , async ( ) => {
69127 const changes = [ npmChange , rubyChange ]
70128 let result = filterChangesBySeverity ( 'high' , changes )
@@ -99,25 +157,61 @@ test('it properly handles undefined advisory IDs', async () => {
99157test ( 'it properly filters changes with allowed vulnerabilities' , async ( ) => {
100158 const changes = [ npmChange , rubyChange , noVulnNpmChange ]
101159
102- let result = filterAllowedAdvisories ( [ 'notrealGHSAID' ] , changes )
103- expect ( result ) . toEqual ( [ npmChange , rubyChange , noVulnNpmChange ] )
160+ const fakeGHSAChanges = filterAllowedAdvisories ( [ 'notrealGHSAID' ] , changes )
161+ expect ( fakeGHSAChanges ) . toEqual ( [ npmChange , rubyChange , noVulnNpmChange ] )
162+ } )
163+
164+ test ( 'it properly filters only allowed vulnerabilities' , async ( ) => {
165+ const changes = [ npmChange , rubyChange , noVulnNpmChange ]
166+ const oldVulns = [
167+ ...npmChange . vulnerabilities ,
168+ ...rubyChange . vulnerabilities ,
169+ ...noVulnNpmChange . vulnerabilities
170+ ]
104171
105- result = filterAllowedAdvisories ( [ 'first-random_string' ] , changes )
106- expect ( result ) . toEqual ( [ rubyChange , noVulnNpmChange ] )
172+ const vulnerable = filterAllowedAdvisories ( [ 'vulnerable-ghsa-id' ] , changes )
107173
108- result = filterAllowedAdvisories (
109- [ 'second-random_string' , 'third-random_string' ] ,
110- changes
174+ const newVulns = vulnerable . map ( change => change . vulnerabilities ) . flat ( )
175+
176+ expect ( newVulns . length ) . toEqual ( oldVulns . length - 1 )
177+ expect ( newVulns ) . not . toContainEqual (
178+ expect . objectContaining ( { advisory_ghsa_id : 'vulnerable-ghsa-id' } )
111179 )
112- expect ( result ) . toEqual ( [ npmChange , noVulnNpmChange ] )
180+ } )
113181
114- result = filterAllowedAdvisories (
115- [ 'first-random_string' , 'second-random_string' , 'third-random_string' ] ,
182+ test ( 'does not drop dependencies when filtering by GHSA' , async ( ) => {
183+ const changes = [ npmChange , rubyChange , noVulnNpmChange ]
184+ const result = filterAllowedAdvisories (
185+ [ 'moderate-ghsa-id' , 'low-ghsa-id' , 'GHSA-jf85-cpcp-j695' ] ,
116186 changes
117187 )
118- expect ( result ) . toEqual ( [ noVulnNpmChange ] )
119188
120- // if we have a change with multiple vulnerabilities but only one is allowed, we still should not filter out that change
121- result = filterAllowedAdvisories ( [ 'second-random_string' ] , changes )
122- expect ( result ) . toEqual ( [ npmChange , rubyChange , noVulnNpmChange ] )
189+ expect ( result . map ( change => change . name ) ) . toEqual (
190+ changes . map ( change => change . name )
191+ )
192+ } )
193+
194+ test ( 'it properly filters multiple GHSAs' , async ( ) => {
195+ const allowedGHSAs = [ 'vulnerable-ghsa-id' , 'moderate-ghsa-id' , 'low-ghsa-id' ]
196+ const changes = [ npmChange , rubyChange , noVulnNpmChange ]
197+ const oldVulns = changes . map ( change => change . vulnerabilities ) . flat ( )
198+
199+ const result = filterAllowedAdvisories ( allowedGHSAs , changes )
200+
201+ const newVulns = result . map ( change => change . vulnerabilities ) . flat ( )
202+
203+ expect ( newVulns . length ) . toEqual ( oldVulns . length - 3 )
204+ } )
205+
206+ test ( 'it properly filters multiple GHSAs' , async ( ) => {
207+ const lodash = filterAllowedAdvisories (
208+ [ 'GHSA-jf85-cpcp-j695' ] ,
209+ [ lodashChange ]
210+ ) [ 0 ]
211+ // the filter should have removed a single GHSA from the list
212+ const expected = lodashChange . vulnerabilities . filter (
213+ vuln => vuln . advisory_ghsa_id !== 'GHSA-jf85-cpcp-j695'
214+ )
215+ expect ( expected . length ) . toEqual ( lodashChange . vulnerabilities . length - 1 )
216+ expect ( lodash . vulnerabilities ) . toEqual ( expected )
123217} )
0 commit comments