-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Subresource Integrity (SRI) on Highlight.js styles and scripts #440
Add Subresource Integrity (SRI) on Highlight.js styles and scripts #440
Conversation
@@ -0,0 +1,36 @@ | |||
// from https://github.com/cdnjs/SRIs/blob/master/highlight.js/9.18.3.json | |||
import * as sri from './highlightjs-sri-9.18.3.json' | |||
const {Opal} = require('asciidoctor-opal-runtime') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Asciidoctor.js does not provide an API to extend a class, that's why we are using Opal directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am so glad you are here to help 😺
Thanks for this opportunity. I'll take a look at it this afternoon and hope to learn something. On the face of it without disabling preview security highlight.js is still not running, so I must investigate. |
There are two problems with the existing code AFAIU: The integrity of the So we need to include the integrity definition in the following: <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js" integrity="sha512-tHQeqtcNWlZtEh8As/4MmZ5qpy0wj04svWFK7MIzLmUVIzaHXS8eod9OmHxyBL1UET5Rchvw7Ih4ZDv5JojZww==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> In the CSP definition here: asciidoctor-vscode/src/features/previewContentProvider.ts Lines 196 to 198 in 05e2413
So that we end up with something like: <meta http-equiv="Content-Security-Policy"
content="default-src 'none'; img-src https://*.vscode-webview.net https: data:; media-src https://*.vscode-webview.net https: data:;
script-src 'nonce-163141872707272' 'sha512-tHQeqtcNWlZtEh8As/4MmZ5qpy0wj04svWFK7MIzLmUVIzaHXS8eod9OmHxyBL1UET5Rchvw7Ih4ZDv5JojZww==';
style-src https://*.vscode-webview.net 'unsafe-inline' https: data:; font-src https://*.vscode-webview.net https: data:;
"> That will then allow <script>
if (!hljs.initHighlighting.called) {
hljs.initHighlighting.called = true
;[].slice.call(document.querySelectorAll("pre.highlight > code")).forEach(function (el) { hljs.highlightBlock(el) })
}
</script>` This script needs to have a nonce included in it. The easiest solution would be to move this code into the return value of asciidoctor-vscode/src/features/previewContentProvider.ts Lines 73 to 92 in 05e2413
Something like: return `<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
${csp}
<meta id="vscode-asciidoc-preview-data"
data-settings="${JSON.stringify(initialData).replace(/"/g, '"')}"
data-strings="${JSON.stringify(previewStrings).replace(/"/g, '"')}"
data-state="${JSON.stringify(state || {}).replace(/"/g, '"')}">
<script src="${this.extensionScriptPath('pre.js')}" nonce="${nonce}"></script>
${this.getStyles(sourceUri, nonce, config, state)}
<base href="${asciidocDocument.uri.with({ scheme: 'vscode-resource' }).toString(true)}">
</head>
<body class="${bodyClassesVal} vscode-body ${config.scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${config.wordWrap ? 'wordWrap' : ''} ${config.markEditorSelection ? 'showEditorSelection' : ''}">
${body}
<div class="code-line" data-line="${asciidocDocument.lineCount}"></div>
<script async src="${this.extensionScriptPath('index.js')}" nonce="${nonce}" charset="UTF-8"></script>
<script nonce="${nonce}">
if (!hljs.initHighlighting.called) {
hljs.initHighlighting.called = true
;[].slice.call(document.querySelectorAll("pre.highlight > code")).forEach(function (el) { hljs.highlightBlock(el) })
}
</script>
</body>
</html>`;
} When I have locally hacked this, I find that this works correctly. But we should probably avoid calling Hack here: Now that I've written all this I realise I should probably have scoped this more tightly against specific lines of code. I'll put a little comment in a few places. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for helping out here. I think I understand why this isn't quite working yet. I have made many comments and am happy to help out in any way.
} | ||
return `<script src="${baseUrl}/highlight.min.js" integrity="${sri['highlight.min.js']}" crossorigin="anonymous" referrerpolicy="no-referrer"></script> | ||
${languageScripts} | ||
<script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not work at all 😉 because it will not be run due to CSP which is quite funny 😜
languageScripts = doc.$attr('highlightjs-languages').split(',').map((lang) => { | ||
const key = `languages/${lang.trim()}.min.js` | ||
const integrityValue = sri[key] | ||
return `<script src="${baseUrl}/${key}" ${integrityValue ? `integrity="${integrityValue}" ` : ''}crossorigin="anonymous" referrerpolicy="no-referrer"></script>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The integrity of this script also needs to be included in the <meta>
tag of the document, see
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https: data:; media-src vscode-resource: https: data:; script-src 'nonce-${nonce}'; style-src vscode-resource: 'unsafe-inline' https: data:; font-src vscode-resource: https: data:;">`; |
The integrity needs to be included as a separate quoted value (in the same form as in the script) adjacent to the nonce.
@@ -0,0 +1,36 @@ | |||
// from https://github.com/cdnjs/SRIs/blob/master/highlight.js/9.18.3.json | |||
import * as sri from './highlightjs-sri-9.18.3.json' | |||
const {Opal} = require('asciidoctor-opal-runtime') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am so glad you are here to help 😺
@joaompinto You were too eager to merge 😉 By the way, how do you re-enable security? I wasn't able to test since I already disabled security on VS Code 😞 |
If you open the command palette (on my system Ctrl+Shift P) and write some
keywords, e.g. 'AsciiDoc security' you should see the extension security
options.
Typically you must force a preview refresh by writing some more text before
the preview updates to see the outcome.
Also in the command palette you can open the web developer tools and
inspect the console.
Thanks!
…On Sun, 12 Sep 2021, 21:12 Guillaume Grossetie, ***@***.***> wrote:
@joaompinto <https://github.com/joaompinto> You were too eager to merge 😉
As mentioned by @danyill <https://github.com/danyill>, my changes are not
enough, I will open a new pull request to address your comments.
By the way, how do you re-enable security? I wasn't able to test since I
already disabled security on VS Code 😞
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#440 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFEXXY4LJFGYQTJDNYFCG3UBRVHLANCNFSM5D25VQRQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Thanks for the tip 👍 I just noticed that it won't work when using the |
Sorry, was trying to help :P |
No worries, I have push permission on the main branch so I can merge pull request when it's ready 😉 |
Register a syntax highlighter based on Highlight.js that adds
integrity
,crossorigin
andreferrerpolicy
on<link>
and<script>
elements (as suggested in: asciidoctor/asciidoctor#3728 (comment))In theory, users won't need to disable security policies when enabling syntax highlighting (with Highlight.js).