@@ -132,6 +132,51 @@ const getCspStats = (sdk: SDK): Promise<Record<string, unknown>> => {
132132 }
133133} ;
134134
135+ // Helper function to extract host and path from analysis
136+ const extractHostAndPath = ( analysis : CspAnalysisResult ) => {
137+ const firstPolicy = analysis . policies [ 0 ] ;
138+
139+ if ( firstPolicy ?. url !== undefined && firstPolicy . url . trim ( ) !== "" ) {
140+ try {
141+ let urlToparse = firstPolicy . url ;
142+ if (
143+ ! urlToparse . startsWith ( "http://" ) &&
144+ ! urlToparse . startsWith ( "https://" )
145+ ) {
146+ urlToparse = "https://" + urlToparse ;
147+ }
148+
149+ const url = new URL ( urlToparse ) ;
150+ return {
151+ host : url . hostname ,
152+ path : url . pathname || "/" ,
153+ } ;
154+ } catch ( error ) {
155+ const parts = firstPolicy . url ?. split ( "/" ) ?? [ ] ;
156+ if ( parts . length > 0 ) {
157+ const firstPart = parts [ 0 ] ;
158+ let hostPart = "N/A" ;
159+ if (
160+ firstPart !== null &&
161+ firstPart !== undefined &&
162+ firstPart . trim ( ) !== ""
163+ ) {
164+ hostPart = firstPart ;
165+ }
166+ return {
167+ host : hostPart ,
168+ path : "/" ,
169+ } ;
170+ }
171+ }
172+ }
173+
174+ return {
175+ host : "N/A" ,
176+ path : "N/A" ,
177+ } ;
178+ } ;
179+
135180const exportCspFindings = async (
136181 sdk : SDK ,
137182 format : "json" | "csv" = "json" ,
@@ -140,11 +185,24 @@ const exportCspFindings = async (
140185 const allVulnerabilities = analyses . flatMap ( ( a ) => a . vulnerabilities ) ;
141186
142187 if ( format === "json" ) {
188+ const enrichedFindings = allVulnerabilities . map ( ( vuln ) => {
189+ const analysis = analyses . find ( ( a ) => a . requestId === vuln . requestId ) ;
190+ const hostPath = analysis
191+ ? extractHostAndPath ( analysis )
192+ : { host : "N/A" , path : "N/A" } ;
193+ return {
194+ ...vuln ,
195+ host : hostPath . host ,
196+ path : hostPath . path ,
197+ analyzedAt : analysis ?. analyzedAt ?. toISOString ( ) ?? null ,
198+ } ;
199+ } ) ;
200+
143201 return JSON . stringify (
144202 {
145203 exportedAt : new Date ( ) . toISOString ( ) ,
146204 totalFindings : allVulnerabilities . length ,
147- findings : allVulnerabilities ,
205+ findings : enrichedFindings ,
148206 } ,
149207 null ,
150208 2 ,
@@ -157,17 +215,29 @@ const exportCspFindings = async (
157215 "Directive" ,
158216 "Value" ,
159217 "Description" ,
218+ "Host" ,
219+ "Path" ,
220+ "Analyzed At" ,
160221 "Request ID" ,
161222 ] ;
162- const rows = allVulnerabilities . map ( ( vuln ) => [
163- vuln . id ,
164- vuln . type ,
165- vuln . severity ,
166- vuln . directive ,
167- vuln . value ,
168- vuln . description . replace ( / [ " , ] / g, "" ) ,
169- vuln . requestId ,
170- ] ) ;
223+ const rows = allVulnerabilities . map ( ( vuln ) => {
224+ const analysis = analyses . find ( ( a ) => a . requestId === vuln . requestId ) ;
225+ const hostPath = analysis
226+ ? extractHostAndPath ( analysis )
227+ : { host : "N/A" , path : "N/A" } ;
228+ return [
229+ vuln . id ,
230+ vuln . type ,
231+ vuln . severity ,
232+ vuln . directive ,
233+ vuln . value ,
234+ vuln . description . replace ( / [ " , ] / g, "" ) ,
235+ hostPath . host ,
236+ hostPath . path ,
237+ analysis ?. analyzedAt ?. toISOString ( ) ?? "N/A" ,
238+ vuln . requestId ,
239+ ] ;
240+ } ) ;
171241
172242 return [ headers , ...rows ] . map ( ( row ) => row . join ( "," ) ) . join ( "\n" ) ;
173243 }
0 commit comments