Blog

Refused to display in a frame because it set 'X-Frame-Options' to 'sameorigin'.

Category
Author
citeFred
citeFred
PinOnMain
1 more property
픽셀스트리밍 트러블슈팅
Table of Content

문제 인식

HTTPS 배포를 통해 모든 서버들은 SSL을 통해 HTTPS 요청/응답을 받는 구조로 변경되고 있음
이 중 PixelStreaming을 하는 웹시그널링서버(WebRTC/Stun-Turn Server)가 동일한 도메인 인증서를 사용하면서 프론트엔드 서비스 내에 iFrame으로 PixelStreaming 화면을 임베딩 하는 부분의 오류가 발생
동일 오리진에 따른 문제
chrome-error://chromewebdata/:1 Refused to display 'https://metaverseacademy.site:8443/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

해결 방안 탐색

해결 시도
보안을 위하여 다른 사이트에서 로드할 때 허용 범위가 지정되어 있다.
호출하는 사이트(A 프로젝트)는 호출 당하는 사이트(B 프로젝트)에서 막은거라 할 수 있는 일은 없다.
호출 당하는 사이트(B 프로젝트)에서 X-Frame-Options 설정을 해준다.
DENY: 시도하는 사이트에 관계없이 페이지를 프레임에 표시 X
SAMEORIGIN: 페이지는 모든 조상 프레임이 페이지 자체와 동일한 출처인 경우에만 표시
호출당하는 입장인 B 프로젝트에서 응답 헤더에 X-Frame-Options를 세팅해서 보내주어야 한다.
httpResponse.setHeader("X-Frame-Options", "allow-from A프로젝트 IP주소:포트번호");
httpResponse.setHeader("X-Frame-Options", "allow-from http://localhost:8080");
Java
복사

해결 시도와 결과

호출 당하는 입장인 Pixel Streaming의 서버에서 헤더 추가 설정 필요
아래는 SignalingWebServer의 cirrus.js의 부분이다.
해당 서버 프로젝트는 helmet은 HTTP 헤더를 설정하여 앱을 일반적인 웹 취약점으로부터 보호하는 데 도움이 되는 Express.js 미들웨어를 사용하고 있는 것으로 파악되었다.
if (config.UseHTTPS) { app.use(helmet()); app.use(hsts({ maxAge: 15552000 // 180 days in seconds })); //Setup http -> https redirect console.log('Redirecting http->https'); app.use(function (req, res, next) { if (!req.secure) { if (req.get('Host')) { var hostAddressParts = req.get('Host').split(':'); var hostAddress = hostAddressParts[0]; if (httpsPort != 443) { hostAddress = `${hostAddress}:${httpsPort}`; } return res.redirect(['https://', hostAddress, req.originalUrl].join('')); } else { console.error(`unable to get host name from header. Requestor ${req.ip}, url path: '${req.originalUrl}', available headers ${JSON.stringify(req.headers)}`); return res.status(400).send('Bad Request'); } } next(); }); }
JavaScript
복사
실제로 파라미터로 UseHttps boolean을 받는 것으로 보아 HTTPS 사용 시에만 helmet 적용: helmet 미들웨어는 config.UseHTTPStrue 일 때만 활성화되고 있다.
helmet 설정 변경으로 helmet() 호출 시에 frameguard 옵션을 명시적으로 설정하여 X-Frame-Options 헤더의 동작을 변경하고자 한다.
1.
첫번째로 해당 부분이 실질적으로 위 문제를 발생시키는지 확인하기 위하여 frameguard 옵션 자체를 비활성화 해본다.
if (config.UseHTTPS) { app.use(helmet({ frameguard: false // frameguard 미들웨어 비활성화 })); app.use(hsts({ maxAge: 15552000 // 180 days in seconds }));
JavaScript
복사
이를 통해 해당 helmet 미들웨어가 해당 부분을 제어하고 있는 것으로 파악되었다.
2.
이 상태로는 보안상 취약점을 발생 시킬 수 있으므로 명시적으로 해당 도메인에 대한 출처 허용으로 스코프를 좁히고자 한다.
if (config.UseHTTPS) { app.use(helmet({ frameguard: false // frameguard 미들웨어 비활성화 })); app.use((req, res, next) => { res.setHeader( "Content-Security-Policy", `frame-ancestors 'self' https://metaverseacademy.site:443 https://www.metaverseacademy.site:443;` ); next(); }); app.use(hsts({ maxAge: 15552000 // 180 days in seconds })); ...
JavaScript
복사
이렇게 헤더를 추가 설정해준다. 이후 모바일로도 문제 없이 실행되는 모습
추가적인 문제
위 헤더 설정 변경 이후 다음과 같은 오류가 발생하고있다.
player.js:1 [Violation] Permissions policy violation: xr-spatial-tracking is not allowed in this document. isSessionSupported @ player.js:1 get rootElement @ player.js:1 createButtons @ player.js:1 ti @ player.js:1 document.body.onload @ player.js:1Understand this error player.js:1 Uncaught (in promise) SecurityError: Failed to execute 'isSessionSupported' on 'XRSystem': Access to the feature "xr" is disallowed by permissions policy. at Et.isSessionSupported (player.js:1:141730) at get rootElement (player.js:1:205667) at ti.createButtons (player.js:1:237093) at new ti (player.js:1:235631) at document.body.onload (player.js:1:256060)
JavaScript
복사
이 오류는 웹 페이지 (player.html) 내에서 WebXR API의 xr-spatial-tracking 기능에 접근하려고 시도했지만, 브라우저의 권한 정책에 의해 허용되지 않았음을 나타낸다.
WebXR 기능을 사용할 계획이 있을 수도 있기 때문에 해당 부분을 해결해보고자 한다. 이 또한 cirrus.js 부분에서 헤더에 xr 허용을 추가하도록 한다.
app.use((req, res, next) => { res.setHeader( "Content-Security-Policy", `frame-ancestors 'self' https://metaverseacademy.site:443 https://www.metaverseacademy.site:443;` ); res.setHeader( "Permissions-Policy", "xr-spatial-tracking=(self)" // 현재 출처에서 xr-spatial-tracking 허용 ); next(); }); ...
JavaScript
복사
헤더를 설정했음에도 여전히 해당 오류가 나타나는 것으로 보아 프론트엔드의 문제일 가능성이 있다.
프론트엔드의 iframe 태그에 다음과 같은 속성을 추가해준다.
<iframe [src]="iframeUrl" width="100%" height="660px" style="border: none;" title="Exhibition" allow="xr-spatial-tracking"> </iframe>
JavaScript
복사
해당 방법으로 해결이 되었으며 위 cirrus.js에서 추가한 내용을 제거해도 아래 속성 추가만으로 해당 오류를 해결 할 수 있었다.
Search
 | Main Page | Category |  Tags | About Me | Contact | Portfolio