@small-tech/vite-plugin-sri
Advanced tools
+17
| # Changelog | ||
| All notable changes to this project will be documented in this file. | ||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
| ## [1.0.1] - 2021-03-31 | ||
| Smaller package. | ||
| ### Improved | ||
| - Remove unnecessary files from npm package. | ||
| ## [1.0.0] - 2021-03-31 | ||
| Initial release. |
+2
-1
| { | ||
| "name": "@small-tech/vite-plugin-sri", | ||
| "version": "1.0.0", | ||
| "version": "1.0.1", | ||
| "description": "A Vite plugin that adds subresource integrity hashes to your index.html file at build time.", | ||
@@ -19,2 +19,3 @@ "type": "module", | ||
| }, | ||
| "files": [], | ||
| "keywords": [ | ||
@@ -21,0 +22,0 @@ "Vite", |
| <!DOCTYPE html> | ||
| <html lang='en'> | ||
| <head> | ||
| <meta charset='UTF-8' /> | ||
| <link rel='icon' type='image/svg+xml' href='favicon.svg' /> | ||
| <link rel='stylesheet' type='text/css' href='/assets/style.css' /> | ||
| <link rel='stylesheet' type='text/css' href='https://ar.al/style.css' /> | ||
| <meta name='viewport' content='width=device-width, initial-scale=1.0' /> | ||
| <script> | ||
| console.log('An inline script, which should be ignored and cause no errors.') | ||
| </script> | ||
| <style> | ||
| /* Ditto for inline CSS. */ | ||
| #app { | ||
| background-color: slategrey; | ||
| } | ||
| </style> | ||
| <title>Vite App</title> | ||
| </head> | ||
| <body> | ||
| <div id='app'></div> | ||
| <script type='module' src='/main.js'></script> | ||
| <script type='module' src='https://ar.al/chat.js'></script> | ||
| </body> | ||
| </html> |
| import './style.css' | ||
| document.querySelector('#app').innerHTML = ` | ||
| <h1>Hello Vite!</h1> | ||
| <a href="https://vitejs.dev/guide/features.html" target="_blank">Documentation</a> | ||
| ` |
| import fs from 'fs' | ||
| import path from 'path' | ||
| import test from 'tape' | ||
| import { fileURLToPath } from 'url' | ||
| import fetch from 'node-fetch' | ||
| import { createHash } from 'crypto' | ||
| import sri from '../index.js' | ||
| const __dirname = fileURLToPath(new URL('.', import.meta.url)) | ||
| test('basic functionality', async (t) => { | ||
| // Setup | ||
| const fixtures = path.join(__dirname, 'fixtures') | ||
| const indexHTML = fs.readFileSync(path.join(fixtures, 'index.html')) | ||
| const localJS = fs.readFileSync(path.join(fixtures, 'main.js')) | ||
| const localCSS = fs.readFileSync(path.join(fixtures, 'assets', 'style.css')) | ||
| const remoteJS = await (await fetch('https://ar.al/chat.js')).buffer() | ||
| const remoteCSS = await (await fetch('https://ar.al/style.css')).buffer() | ||
| const localJSHash = createHash('sha384').update(localJS).digest().toString('base64') | ||
| const localCSSHash = createHash('sha384').update(localCSS).digest().toString('base64') | ||
| const remoteJSHash = createHash('sha384').update(remoteJS).digest().toString('base64') | ||
| const remoteCSSHash = createHash('sha384').update(remoteCSS).digest().toString('base64') | ||
| const expectedLocalCSSLinkTag = `<link rel="stylesheet" type="text/css" href="/assets/style.css" integrity="sha384-${localCSSHash}">` | ||
| const expectedRemoteCSSLinkTag = `<link rel="stylesheet" type="text/css" href="https://ar.al/style.css" integrity="sha384-${remoteCSSHash}">` | ||
| const expectedLocalJSScriptTag = `<script type="module" src="/main.js" integrity="sha384-${localJSHash}"></script>` | ||
| const expectedRemoteJSScriptTag = `<script type="module" src="https://ar.al/chat.js" integrity="sha384-${remoteJSHash}"></script>` | ||
| const context = { | ||
| bundle: { | ||
| 'assets/style.css': { source: localCSS }, | ||
| 'main.js': { code: localJS } | ||
| } | ||
| } | ||
| const plugin = sri() | ||
| t.strictEquals(plugin.name, 'vite-plugin-sri', 'Plugin name is as expected.') | ||
| t.strictEquals(plugin.apply, 'build', 'Plugin applies to build tasks only.') | ||
| t.strictEquals(plugin.enforce, 'post', 'Plugin is enforced to run during post stage.') | ||
| const html = await plugin.transformIndexHtml(indexHTML, context) | ||
| t.true(html.includes(expectedLocalCSSLinkTag), 'Transformed HTML includes expected local CSS link tag.') | ||
| t.true(html.includes(expectedRemoteCSSLinkTag), 'Transformed HTML includes expected remote CSS link tag.') | ||
| t.true(html.includes(expectedLocalJSScriptTag), 'Transformed HTML includes expected local JS link tag.') | ||
| t.true(html.includes(expectedRemoteJSScriptTag), 'Transformed HTML includes expected remote JS link tag.') | ||
| }) |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
0
-100%2
-60%6068
-33.73%5
-37.5%60
-42.86%