mirror of
https://github.com/coder/code-server.git
synced 2026-07-17 22:25:26 +02:00
Fix automatic CSP hash update
The problem was that whenever the hashe needed an update, the current patch would create a conflict which cannot be easily auto-resolved. Instead, put the hashes in a separate patch that is deleted and regenerated each time, avoiding the conflicts. Also the web worker iframe hash was not being updated.
This commit is contained in:
@@ -4,7 +4,7 @@ set -Eeuo pipefail
|
|||||||
|
|
||||||
function unapply_patches() {
|
function unapply_patches() {
|
||||||
local -i exit_code=0
|
local -i exit_code=0
|
||||||
quiet quilt pop -af || exit_code=$?
|
quiet quilt pop -af 2>&1 || exit_code=$?
|
||||||
case $exit_code in
|
case $exit_code in
|
||||||
# Sucessfully unapplied.
|
# Sucessfully unapplied.
|
||||||
0) ;;
|
0) ;;
|
||||||
@@ -15,6 +15,19 @@ function unapply_patches() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function apply_patches() {
|
||||||
|
local -i exit_code=0
|
||||||
|
quiet quilt push -a 2>&1 || exit_code=$?
|
||||||
|
case $exit_code in
|
||||||
|
# Sucessfully applied.
|
||||||
|
0) ;;
|
||||||
|
# No more patches to apply.
|
||||||
|
2) ;;
|
||||||
|
# Some error.
|
||||||
|
*) return $exit_code ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
function update_vscode() {
|
function update_vscode() {
|
||||||
pushd lib/vscode
|
pushd lib/vscode
|
||||||
if ! git checkout 2>&1 "$target_vscode_version" ; then
|
if ! git checkout 2>&1 "$target_vscode_version" ; then
|
||||||
@@ -28,8 +41,8 @@ function update_vscode() {
|
|||||||
|
|
||||||
function refresh_patches() {
|
function refresh_patches() {
|
||||||
local -i exit_code=0
|
local -i exit_code=0
|
||||||
while quiet quilt push ; ! (( exit_code=$? )) ; do
|
while quiet quilt push 2>&1 ; ! (( exit_code=$? )) ; do
|
||||||
quilt refresh
|
quilt refresh 2>&1
|
||||||
done
|
done
|
||||||
case $exit_code in
|
case $exit_code in
|
||||||
# No more patches to apply.
|
# No more patches to apply.
|
||||||
@@ -56,50 +69,41 @@ function get-webview-script-hash() {
|
|||||||
local html
|
local html
|
||||||
html=$(<"$1")
|
html=$(<"$1")
|
||||||
local start_tag='<script async type="module">'
|
local start_tag='<script async type="module">'
|
||||||
|
if [[ $file == */webWorkerExtensionHostIframe.html ]] ; then
|
||||||
|
start_tag='<script>'
|
||||||
|
fi
|
||||||
local end_tag="</script>"
|
local end_tag="</script>"
|
||||||
html=${html##*"$start_tag"}
|
html=${html##*"$start_tag"}
|
||||||
html=${html%%"$end_tag"*}
|
html=${html%%"$end_tag"*}
|
||||||
echo -n "$html" | openssl sha256 -binary | openssl base64
|
echo -n "$html" | openssl sha256 -binary | openssl base64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delete_csp() {
|
||||||
|
quilt delete csp-hashes.diff
|
||||||
|
}
|
||||||
|
|
||||||
function update_csp() {
|
function update_csp() {
|
||||||
local current
|
apply_patches
|
||||||
current=$(quilt top 2>/dev/null || echo "")
|
|
||||||
local patch_action=""
|
local files=(
|
||||||
echo "Currently at ${current:-base}"
|
./lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
||||||
if [[ $current != */webview.diff ]] ; then
|
./lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||||
echo "Moving to patches/webview.diff..."
|
)
|
||||||
local -i exit_code=0
|
|
||||||
if quilt applied 2>/dev/null | grep --quiet webview.diff ; then
|
quilt new csp-hashes.diff
|
||||||
quiet quilt pop webview || exit_code=$?
|
|
||||||
patch_action=pop
|
local file
|
||||||
else
|
for file in "${files[@]}" ; do
|
||||||
quiet quilt push webview || exit_code=$?
|
quilt add "$file"
|
||||||
patch_action=push
|
|
||||||
fi
|
local hash
|
||||||
case $exit_code in
|
hash=$(get-webview-script-hash "$file")
|
||||||
# Successfully moved.
|
echo "Calculated hash as $hash"
|
||||||
0) ;;
|
# Use octothorpe as a delimiter since the hash may contain a slash.
|
||||||
# Some error.
|
sed -i.bak "s#'sha256-[^']\+'#'sha256-$hash'#" "$file"
|
||||||
*) return $exit_code ;;
|
done
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
local file=lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
|
||||||
local hash
|
|
||||||
hash=$(get-webview-script-hash "$file")
|
|
||||||
echo "Calculated hash as $hash"
|
|
||||||
# Use octothorpe as a delimiter since the hash may contain a slash.
|
|
||||||
sed -i.bak "s#script-src 'sha256-[^']\+'#script-src 'sha256-$hash'#" "$file"
|
|
||||||
quilt refresh
|
quilt refresh
|
||||||
|
|
||||||
if [[ $patch_action != "" ]] ; then
|
|
||||||
echo "Moving back to ${current:-base}..."
|
|
||||||
case $patch_action in
|
|
||||||
pop) quiet quilt push "$current" ;;
|
|
||||||
push) quiet quilt pop "${current:--a}" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_changelog() {
|
function add_changelog() {
|
||||||
@@ -120,6 +124,9 @@ function main() {
|
|||||||
|
|
||||||
declare -a steps
|
declare -a steps
|
||||||
|
|
||||||
|
# Hashes are always regenerated to avoid having to resolve conflicts..
|
||||||
|
steps+=("Revert CSP hashes" "delete_csp")
|
||||||
|
|
||||||
# If version is not set, assume we are already at the target version and the
|
# If version is not set, assume we are already at the target version and the
|
||||||
# user is just trying to resolve conflics.
|
# user is just trying to resolve conflics.
|
||||||
local target_vscode_version
|
local target_vscode_version
|
||||||
@@ -141,7 +148,7 @@ function main() {
|
|||||||
|
|
||||||
steps+=(
|
steps+=(
|
||||||
"Update Node version" "update_node"
|
"Update Node version" "update_node"
|
||||||
"Update CSP webview hash" "update_csp"
|
"Regenerate CSP hashes" "update_csp"
|
||||||
"Add changelog note" "add_changelog"
|
"Add changelog note" "add_changelog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
10
ci/lib.sh
10
ci/lib.sh
@@ -85,18 +85,20 @@ run-steps() {
|
|||||||
while (( $# )) ; do
|
while (( $# )) ; do
|
||||||
local name=$1 ; shift
|
local name=$1 ; shift
|
||||||
local fn=$1 ; shift
|
local fn=$1 ; shift
|
||||||
|
echo "$name..."
|
||||||
# Only run if an earlier step has not failed.
|
# Only run if an earlier step has not failed.
|
||||||
|
# For all failed steps, write out an empty checkbox.
|
||||||
if [[ $failed == 0 ]] ; then
|
if [[ $failed == 0 ]] ; then
|
||||||
echo "$name..."
|
|
||||||
if $fn | indent ; then
|
if $fn | indent ; then
|
||||||
echo "- [X] $name" >> .cache/checklist
|
echo "- [X] $name" >> .cache/checklist
|
||||||
else
|
else
|
||||||
((failed++))
|
((failed++))
|
||||||
|
echo "- [-] $name" >> .cache/checklist
|
||||||
|
echo "Failed" | indent
|
||||||
fi
|
fi
|
||||||
fi
|
else
|
||||||
# For all failed steps, write out an empty checkbox.
|
|
||||||
if [[ $failed != 0 ]] ; then
|
|
||||||
echo "- [ ] $name" >> .cache/checklist
|
echo "- [ ] $name" >> .cache/checklist
|
||||||
|
echo "Skipped" | indent
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if [[ $failed != 0 ]] ; then
|
if [[ $failed != 0 ]] ; then
|
||||||
|
|||||||
26
patches/csp-hashes.diff
Normal file
26
patches/csp-hashes.diff
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
||||||
|
@@ -5,7 +5,7 @@
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
|
||||||
|
<meta http-equiv="Content-Security-Policy"
|
||||||
|
- content="default-src 'none'; script-src 'sha256-nXjtuhBilO++r8hfxl5VjEScSmdm07wDAk6jw228DgM=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||||
|
+ content="default-src 'none'; script-src 'sha256-A6/szVNdTzyi4hDa+9OLbzS8tSd2iUV4CqimLNWex2Y=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||||
|
|
||||||
|
<!-- Disable pinch zooming -->
|
||||||
|
<meta name="viewport"
|
||||||
|
Index: code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="
|
||||||
|
default-src 'none';
|
||||||
|
child-src 'self' data: blob:;
|
||||||
|
- script-src 'self' 'unsafe-eval' 'sha256-cl8ijlOzEe+0GRCQNJQu2k6nUQ0fAYNYIuuKEm72JDs=' https: http://localhost:* blob:;
|
||||||
|
+ script-src 'self' 'unsafe-eval' 'sha256-yhZXuB8LS6t73dvNg6rtLX8y4PHLnqRm5+6DdOGkOcw=' https: http://localhost:* blob:;
|
||||||
|
connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
@@ -24,3 +24,4 @@ trusted-domains.diff
|
|||||||
signature-verification.diff
|
signature-verification.diff
|
||||||
copilot.diff
|
copilot.diff
|
||||||
app-name.diff
|
app-name.diff
|
||||||
|
csp-hashes.diff
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ Serve webviews from the same origin
|
|||||||
Normally webviews are served from vscode-webview.net but we would rather them be
|
Normally webviews are served from vscode-webview.net but we would rather them be
|
||||||
self-hosted.
|
self-hosted.
|
||||||
|
|
||||||
When doing this CSP will block resources (for example when viewing images) so
|
|
||||||
add 'self' to the CSP to fix that.
|
|
||||||
|
|
||||||
Additionally the service worker defaults to handling *all* requests made to the
|
Additionally the service worker defaults to handling *all* requests made to the
|
||||||
current host but when self-hosting the webview this will end up including the
|
current host but when self-hosting the webview this will end up including the
|
||||||
webview HTML itself which means these requests will fail since the communication
|
webview HTML itself which means these requests will fail since the communication
|
||||||
@@ -20,16 +17,6 @@ webview host is separate by default but we serve on the same host).
|
|||||||
|
|
||||||
To test, open a few types of webviews (images, markdown, extension details, etc).
|
To test, open a few types of webviews (images, markdown, extension details, etc).
|
||||||
|
|
||||||
Make sure to update the hash. To do so:
|
|
||||||
1. run code-server
|
|
||||||
2. open any webview (i.e. preview Markdown)
|
|
||||||
3. see error in console and copy hash
|
|
||||||
|
|
||||||
That will test the hash change in pre/index.html
|
|
||||||
|
|
||||||
Double-check the console to make sure there are no console errors for the webWorkerExtensionHostIframe
|
|
||||||
which also requires a hash change.
|
|
||||||
|
|
||||||
parentOriginHash changes
|
parentOriginHash changes
|
||||||
|
|
||||||
This fixes webviews from not working properly due to a change upstream.
|
This fixes webviews from not working properly due to a change upstream.
|
||||||
@@ -66,15 +53,6 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
|
|||||||
===================================================================
|
===================================================================
|
||||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
||||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
|
||||||
@@ -5,7 +5,7 @@
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
|
|
||||||
<meta http-equiv="Content-Security-Policy"
|
|
||||||
- content="default-src 'none'; script-src 'sha256-nXjtuhBilO++r8hfxl5VjEScSmdm07wDAk6jw228DgM=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
|
||||||
+ content="default-src 'none'; script-src 'sha256-A6/szVNdTzyi4hDa+9OLbzS8tSd2iUV4CqimLNWex2Y=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
|
||||||
|
|
||||||
<!-- Disable pinch zooming -->
|
|
||||||
<meta name="viewport"
|
|
||||||
@@ -253,7 +253,7 @@
|
@@ -253,7 +253,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,15 +79,6 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWor
|
|||||||
===================================================================
|
===================================================================
|
||||||
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||||
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
|
||||||
@@ -4,7 +4,7 @@
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="
|
|
||||||
default-src 'none';
|
|
||||||
child-src 'self' data: blob:;
|
|
||||||
- script-src 'self' 'unsafe-eval' 'sha256-cl8ijlOzEe+0GRCQNJQu2k6nUQ0fAYNYIuuKEm72JDs=' https: http://localhost:* blob:;
|
|
||||||
+ script-src 'self' 'unsafe-eval' 'sha256-yhZXuB8LS6t73dvNg6rtLX8y4PHLnqRm5+6DdOGkOcw=' https: http://localhost:* blob:;
|
|
||||||
connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
@@ -25,6 +25,13 @@
|
@@ -25,6 +25,13 @@
|
||||||
// validation not requested
|
// validation not requested
|
||||||
return start();
|
return start();
|
||||||
|
|||||||
Reference in New Issue
Block a user