@@ -27,6 +27,7 @@ async function render(panel: vscode.WebviewPanel, rootPath: string): Promise<voi
2727
2828 // used for CSP
2929 const nonces : string [ ] = [ ]
30+ const hashes : string [ ] = [ ]
3031
3132 // generate vscode-resource build path uri
3233 const createUri = ( _filePath : string ) : any => {
@@ -50,7 +51,12 @@ async function render(panel: vscode.WebviewPanel, rootPath: string): Promise<voi
5051 // support additional CSP exemptions when CodeRoad is embedded
5152 if ( CONTENT_SECURITY_POLICY_EXEMPTIONS && CONTENT_SECURITY_POLICY_EXEMPTIONS . length ) {
5253 for ( const exemption of CONTENT_SECURITY_POLICY_EXEMPTIONS . split ( ' ' ) ) {
53- nonces . push ( exemption )
54+ // sha hashes should not be prefixed with 'nonce-'
55+ if ( exemption . match ( / ^ s h a / ) ) {
56+ hashes . push ( exemption )
57+ } else {
58+ nonces . push ( exemption )
59+ }
5460 }
5561 }
5662
@@ -71,17 +77,24 @@ async function render(panel: vscode.WebviewPanel, rootPath: string): Promise<voi
7177 }
7278
7379 // set CSP (content security policy) to grant permission to local files
80+ // while blocking unexpected malicious network requests
7481 const cspMeta : HTMLMetaElement = document . createElement ( 'meta' )
7582 cspMeta . httpEquiv = 'Content-Security-Policy'
83+
84+ const wrapInQuotes = ( str : string ) => `'${ str } '`
85+ const nonceString = nonces . map ( ( nonce : string ) => wrapInQuotes ( `nonce-${ nonce } ` ) ) . join ( ' ' )
86+ const hashString = hashes . map ( wrapInQuotes ) . join ( ' ' )
87+
7688 cspMeta . content =
7789 [
7890 `default-src 'self'` ,
91+ `manifest-src ${ hashString } 'self'` ,
7992 `connect-src https: http:` ,
8093 // @ts -ignore
8194 `font-src ${ panel . webview . cspSource } http: https: data:` ,
8295 // @ts -ignore
8396 `img-src ${ panel . webview . cspSource } https:` ,
84- `script-src ${ nonces . map ( ( nonce ) => `'nonce- ${ nonce } '` ) . join ( ' ' ) } data:` ,
97+ `script-src ${ nonceString } ${ hashString } data:` ,
8598 // @ts -ignore
8699 `style-src ${ panel . webview . cspSource } https: 'self' 'unsafe-inline'` ,
87100 ] . join ( '; ' ) + ';'
@@ -92,7 +105,7 @@ async function render(panel: vscode.WebviewPanel, rootPath: string): Promise<voi
92105
93106 // set view
94107 panel . webview . html = html
95- } catch ( error ) {
108+ } catch ( error : any ) {
96109 onError ( error )
97110 console . error ( error )
98111 }
0 commit comments