픽셀스트리밍 트러블슈팅
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.UseHTTPS 가 true 일 때만 활성화되고 있다.
•
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에서 추가한 내용을 제거해도 아래 속성 추가만으로 해당 오류를 해결 할 수 있었다.
Related Posts
Search