diff --git a/nginx/default.conf b/nginx/default.conf index 6cb7b05..f391bb9 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -9,6 +9,21 @@ map $sent_http_content_type $addin_cache_control { ~*application/wasm "public, max-age=86400"; } +# Origin allowlist for CORS. The add-in's own assets are served same-origin +# inside the Office iframe, so most requests need no CORS at all; the entries +# below cover the Microsoft origins that legitimately fetch add-in assets +# cross-origin (Office.js CDN and the Outlook hosts). The request Origin is +# echoed back only when it is on the allowlist — any other origin gets an +# empty value, and nginx then omits the Access-Control-Allow-Origin header +# entirely, so arbitrary sites cannot read responses cross-origin. +map $http_origin $addin_cors_origin { + default ""; + "https://appsforoffice.microsoft.com" $http_origin; + "https://outlook.office.com" $http_origin; + "https://outlook.office365.com" $http_origin; + "https://outlook.live.com" $http_origin; +} + server { listen 80 default_server; server_name _; @@ -21,9 +36,13 @@ server { add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Cache-Control $addin_cache_control always; - # Permissive CORS so the Office runtime (and the manifest fetcher) can - # load assets across origins. - add_header Access-Control-Allow-Origin "*" always; + # Restrict CORS to the allowlisted Office/Outlook origins (see the + # $addin_cors_origin map above). For any other origin the value is empty + # and nginx skips the header, so only the trusted Microsoft origins can + # read add-in responses cross-origin. Vary: Origin keeps caches from + # serving one origin's CORS response to another. + add_header Access-Control-Allow-Origin $addin_cors_origin always; + add_header Vary Origin always; location = /health { access_log off;