forked from colin/resume
2
0
Fork 0
lucky-ddg/docker/resume/update-csp-hashes.sh

164 lines
5.9 KiB
Bash
Executable File

#!/bin/bash
# =====================================================================
# update-csp-hashes.sh - Update Content Security Policy hashes
# =====================================================================
# This script updates the CSP hashes for:
# 1. All JavaScript and CSS files
# 2. All inline style attributes in HTML files
# 3. Adds CSP meta tags to HTML files
# After running this script, restart the server using:
# ./caddy.sh
# =====================================================================
set -e
echo "Updating CSP hashes for all JavaScript, CSS files, and inline styles..."
# Directory containing the files
BASE_DIR="$(pwd)"
# Check if we're in a Docker environment
if [ -f "/etc/caddy/Caddyfile" ]; then
CADDYFILE="/etc/caddy/Caddyfile"
else
CADDYFILE="$BASE_DIR/Caddyfile"
fi
TEMP_INLINE_HASHES_FILE=$(mktemp)
# Arrays to store hashes
SCRIPT_HASHES=()
STYLE_HASHES=()
# Calculate hash for a file
calculate_hash() {
local file=$1
sha256sum "$file" | awk '{print $1}' | xxd -r -p | base64
}
# Calculate hash for inline style
calculate_inline_hash() {
local style_content=$1
echo -n "$style_content" | sha256sum | awk '{print $1}' | xxd -r -p | base64
}
# Process JavaScript files
echo "Processing JavaScript files..."
for js_file in $(find "$BASE_DIR" -name "*.js" -type f); do
echo "Processing $js_file"
file_name=$(basename "$js_file")
hash=$(calculate_hash "$js_file")
SCRIPT_HASHES+=("'sha256-$hash'")
# Update HTML files that reference this JS file
for html_file in $(find "$BASE_DIR" -name "*.html" -type f); do
if grep -q "$file_name" "$html_file"; then
echo "Updating $file_name in $html_file"
# Create a temporary file for the replacement
tmp_file=$(mktemp)
# For files with existing integrity attribute
if grep -q "$file_name.*integrity" "$html_file"; then
# Use awk for safer text processing
awk -v fname="$file_name" -v newhash="$hash" '
{
if ($0 ~ fname && $0 ~ /integrity/) {
gsub(/integrity="sha256-[^"]*"/, "integrity=\"sha256-" newhash "\"");
}
print;
}' "$html_file" > "$tmp_file"
else
# Add integrity attribute if it doesn't exist
awk -v fname="$file_name" -v newhash="$hash" '
{
if ($0 ~ fname && $0 ~ /src/ && !($0 ~ /integrity/)) {
gsub(/src="[^"]*"/, "&" " integrity=\"sha256-" newhash "\"");
}
print;
}' "$html_file" > "$tmp_file"
fi
# Replace original file with modified content
mv "$tmp_file" "$html_file"
fi
done
done
# Process CSS files
echo "Processing CSS files..."
for css_file in $(find "$BASE_DIR" -name "*.css" -type f); do
echo "Processing $css_file"
file_name=$(basename "$css_file")
hash=$(calculate_hash "$css_file")
STYLE_HASHES+=("'sha256-$hash'")
# Update HTML files that reference this CSS file
for html_file in $(find "$BASE_DIR" -name "*.html" -type f); do
if grep -q "$file_name" "$html_file"; then
echo "Updating $file_name in $html_file"
# Create a temporary file for the replacement
tmp_file=$(mktemp)
# For files with existing integrity attribute
if grep -q "$file_name.*integrity" "$html_file"; then
# Use awk for safer text processing
awk -v fname="$file_name" -v newhash="$hash" '
{
if ($0 ~ fname && $0 ~ /integrity/) {
gsub(/integrity="sha256-[^"]*"/, "integrity=\"sha256-" newhash "\"");
}
print;
}' "$html_file" > "$tmp_file"
else
# Add integrity attribute if it doesn't exist
awk -v fname="$file_name" -v newhash="$hash" '
{
if ($0 ~ fname && $0 ~ /href/ && !($0 ~ /integrity/)) {
gsub(/href="[^"]*"/, "&" " integrity=\"sha256-" newhash "\"");
}
print;
}' "$html_file" > "$tmp_file"
fi
# Replace original file with modified content
mv "$tmp_file" "$html_file"
fi
done
done
# Find and process inline styles - using a more thorough approach
echo "Processing HTML files for inline styles..."
find "$BASE_DIR" -name "*.html" -type f | while read -r html_file; do
echo "Processing $html_file for inline styles..."
# Use a more comprehensive grep pattern to catch all inline styles
# This includes both style="..." and style = "..." patterns
grep -o 'style\s*=\s*"[^"]*"' "$html_file" | sed 's/style\s*=\s*"\(.*\)"/\1/' | while read -r style_content; do
if [ -n "$style_content" ]; then
hash=$(calculate_inline_hash "$style_content")
echo "Found inline style: '$style_content'"
echo "Calculated hash: sha256-$hash"
echo "'sha256-$hash'" >> "$TEMP_INLINE_HASHES_FILE"
fi
done
done
# Sort and remove duplicates from inline style hashes
if [ -f "$TEMP_INLINE_HASHES_FILE" ]; then
sort -u "$TEMP_INLINE_HASHES_FILE" > "${TEMP_INLINE_HASHES_FILE}.sorted"
mv "${TEMP_INLINE_HASHES_FILE}.sorted" "$TEMP_INLINE_HASHES_FILE"
# Add inline style hashes to the STYLE_HASHES array
while read -r hash; do
STYLE_HASHES+=("$hash")
done < "$TEMP_INLINE_HASHES_FILE"
# Clean up
rm -f "$TEMP_INLINE_HASHES_FILE"
fi
# Combine all hashes for CSP
echo "Skipping CSP header updates (disabled)"
echo "CSP hashes updated successfully!"
echo "To apply changes, restart the server using: ./caddy.sh"