diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 61f18bc855..0477dc558a 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -51,6 +51,7 @@ services: user: 1000:1000 environment: MESH_HOST: ${MESH_HOST} + APP_HOST: ${APP_HOST} MESH_USER: ${MESH_USER} MESH_PASS: ${MESH_PASS} MONGODB_USER: ${MONGODB_USER} diff --git a/ansible/roles/trmm_dev/templates/mesh.cfg.j2 b/ansible/roles/trmm_dev/templates/mesh.cfg.j2 index b9a20090d3..4569fa6478 100644 --- a/ansible/roles/trmm_dev/templates/mesh.cfg.j2 +++ b/ansible/roles/trmm_dev/templates/mesh.cfg.j2 @@ -7,7 +7,7 @@ "AliasPort": 443, "RedirPort": 800, "AllowLoginToken": true, - "AllowFraming": true, + "allowedFramingOrigins": ["https://{{ rmm }}", "http://{{ rmm }}:8080", "https://{{ rmm }}:8080"], "AgentPing": 35, "AllowHighQualityDesktop": true, "TlsOffload": "127.0.0.1", diff --git a/docker/containers/tactical-meshcentral/entrypoint.sh b/docker/containers/tactical-meshcentral/entrypoint.sh index cbb99e243d..69e93da2e3 100644 --- a/docker/containers/tactical-meshcentral/entrypoint.sh +++ b/docker/containers/tactical-meshcentral/entrypoint.sh @@ -21,6 +21,12 @@ set -e : "${SMTP_PASS:=mesh-smtp-pass}" : "${SMTP_TLS:=false}" +if [ -n "${APP_HOST}" ]; then + ALLOWED_FRAMING_ORIGINS='["https://'"${APP_HOST}"'"]' +else + ALLOWED_FRAMING_ORIGINS='[]' +fi + if [ ! -f "/home/node/app/meshcentral-data/config.json" ] || [[ "${MESH_PERSISTENT_CONFIG}" -eq 0 ]]; then encoded_uri=$(node -p "encodeURI('mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@${MONGODB_HOST}:${MONGODB_PORT}')") @@ -39,7 +45,7 @@ if [ ! -f "/home/node/app/meshcentral-data/config.json" ] || [[ "${MESH_PERSISTE "agentAliasPort": 443, "aliasPort": 443, "allowLoginToken": true, - "allowFraming": true, + "allowedFramingOrigins": ${ALLOWED_FRAMING_ORIGINS}, "agentPing": 35, "allowHighQualityDesktop": true, "agentCoreDump": false, diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index dcbd290044..c207d7caa0 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -105,6 +105,7 @@ services: restart: always environment: MESH_HOST: ${MESH_HOST} + APP_HOST: ${APP_HOST} MESH_USER: ${MESH_USER} MESH_PASS: ${MESH_PASS} MONGODB_USER: ${MONGODB_USER} diff --git a/install.sh b/install.sh index 83c714747e..6cf09541dd 100644 --- a/install.sh +++ b/install.sh @@ -448,7 +448,7 @@ meshcfg="$( "aliasPort": 443, "redirPort": 800, "allowLoginToken": true, - "allowFraming": true, + "allowedFramingOrigins": ["https://${frontenddomain}"], "agentPing": 35, "allowHighQualityDesktop": true, "tlsOffload": "127.0.0.1", diff --git a/update.sh b/update.sh index b154bc89f4..9183e3f0c4 100644 --- a/update.sh +++ b/update.sh @@ -663,6 +663,7 @@ if ! which jq >/dev/null; then fi if which jq >/dev/null; then + mesh_config_changed=false if ! jq -e "$check_jq_filter" "$mesh_cfg" >/dev/null; then echo "Disabling mesh compression" # backup to homedir first @@ -671,11 +672,33 @@ if which jq >/dev/null; then if jq "$apply_jq_filter" "$mesh_cfg" >"$mesh_tmp"; then if [ -s "$mesh_tmp" ]; then mv "$mesh_tmp" "$mesh_cfg" - sudo systemctl restart meshcentral + mesh_config_changed=true fi fi rm -f "$mesh_tmp" fi + + # Migrate allowFraming to allowedFramingOrigins for clickjacking protection + if [ -f "$mesh_cfg" ] && [ -n "$FRONTEND" ]; then + has_allow_framing=$(jq -r '.settings | to_entries | map(.key | ascii_downcase) | index("allowframing") // "none"' "$mesh_cfg" 2>/dev/null) + has_allowed_origins=$(jq -r '.settings | to_entries | map(.key | ascii_downcase) | index("allowedframingorigins") // "none"' "$mesh_cfg" 2>/dev/null) + if [[ "$has_allow_framing" != "none" ]] && [[ "$has_allowed_origins" == "none" ]]; then + echo "Migrating MeshCentral config: replacing allowFraming with allowedFramingOrigins for clickjacking protection" + cp "$mesh_cfg" ~/meshcfg-framing-$(date "+%Y%m%dT%H%M%S").bak + mesh_tmp=$(mktemp) + if jq --arg frontend "$FRONTEND" '.settings |= ((to_entries | map(select((.key | ascii_downcase) != "allowframing")) | from_entries) + {"allowedFramingOrigins": ["https://\($frontend)"]})' "$mesh_cfg" >"$mesh_tmp" 2>/dev/null && [ -s "$mesh_tmp" ]; then + mv "$mesh_tmp" "$mesh_cfg" + mesh_config_changed=true + else + printf >&2 "${YELLOW}Warning: Could not migrate allowFraming to allowedFramingOrigins. Backup saved to ~/meshcfg-framing-*.bak${NC}\n" + rm -f "$mesh_tmp" + fi + fi + fi + + if [[ "$mesh_config_changed" == "true" ]]; then + sudo systemctl restart meshcentral + fi fi for i in nats nats-api rmm daphne celery celerybeat nginx; do