Skip to content

Commit 2549772

Browse files
security(nginx): replace wildcard CORS with Office origin allowlist
Replace `Access-Control-Allow-Origin: *` in nginx/default.conf with a map-based allowlist that echoes the request Origin back only for the trusted Microsoft origins (Office.js CDN + Outlook hosts). Any other origin gets an empty value, so nginx omits the header entirely and arbitrary sites can no longer read add-in responses cross-origin. Also add `Vary: Origin` so caches don't serve one origin's CORS response to another. Refs GHSA-m957-9cxh-72q7, closes #115 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent d413cf5 commit 2549772

1 file changed

Lines changed: 22 additions & 3 deletions

File tree

nginx/default.conf

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@ map $sent_http_content_type $addin_cache_control {
99
~*application/wasm "public, max-age=86400";
1010
}
1111

12+
# Origin allowlist for CORS. The add-in's own assets are served same-origin
13+
# inside the Office iframe, so most requests need no CORS at all; the entries
14+
# below cover the Microsoft origins that legitimately fetch add-in assets
15+
# cross-origin (Office.js CDN and the Outlook hosts). The request Origin is
16+
# echoed back only when it is on the allowlist — any other origin gets an
17+
# empty value, and nginx then omits the Access-Control-Allow-Origin header
18+
# entirely, so arbitrary sites cannot read responses cross-origin.
19+
map $http_origin $addin_cors_origin {
20+
default "";
21+
"https://appsforoffice.microsoft.com" $http_origin;
22+
"https://outlook.office.com" $http_origin;
23+
"https://outlook.office365.com" $http_origin;
24+
"https://outlook.live.com" $http_origin;
25+
}
26+
1227
server {
1328
listen 80 default_server;
1429
server_name _;
@@ -21,9 +36,13 @@ server {
2136
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
2237
add_header Cache-Control $addin_cache_control always;
2338

24-
# Permissive CORS so the Office runtime (and the manifest fetcher) can
25-
# load assets across origins.
26-
add_header Access-Control-Allow-Origin "*" always;
39+
# Restrict CORS to the allowlisted Office/Outlook origins (see the
40+
# $addin_cors_origin map above). For any other origin the value is empty
41+
# and nginx skips the header, so only the trusted Microsoft origins can
42+
# read add-in responses cross-origin. Vary: Origin keeps caches from
43+
# serving one origin's CORS response to another.
44+
add_header Access-Control-Allow-Origin $addin_cors_origin always;
45+
add_header Vary Origin always;
2746

2847
location = /health {
2948
access_log off;

0 commit comments

Comments
 (0)