롯데 e커머스 채용연계형 면접으로 보고와서 적는 리팩토링 글!
물론 떨어졌기에 큰 도움은 안되겠지만 내년에 면접 볼 분들을 위해 후기를 작성 할 생각이다.
5일차 포스팅에 문제에 대한 고민을 팀원들과 함께 의논을 해 본 결과..
ㅎㄱ 님: 노션은 드래그 앤 드랍과 엔터치면 새로운 블록 생성되는 기능 둘 다 있지 않나요..?
생각해보니 맞는 말이다. 그래서 둘 다 개발하는 걸로!
( 드래그 앤 드랍은 다음 포스팅에서 다룰 예정 입니다)
-> 사실 리팩토링하면서 계속 에디터를 고도화 하기 위해 공부하는데
contentEditable 속성에 문제점에 대한 글을 보게 되었다.
우선 공식적으로 정해진 표준이 아니기에 브라우저마다 동작이 다르다(일관성이 없다)는 문제점이 있었고, 또한 React에서 사용할 땐 input과 동작방식이 많은 차이점이 있다는 사실을 알게 되었다 .(아래 링크 참조)
https://www.bucketplace.com/post/2020-09-18-%EC%9B%90%ED%99%9C%ED%95%9C-%EC%BD%98%ED%85%90%EC%B8%A0-%EC%9E%91%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%97%90%EB%94%94%ED%84%B0-%EA%B0%9C%EB%B0%9C%EA%B8%B0/
dangerouslySetInnerHTML 란?
브라우저 DOM에서 innerHTML을 사용하기 위한 REACT의 대체 방법으로 이 태그를 통해 직접적으로 HTML을 삽입 할 수 있다.
XSS란 (Cross Site Script)
XSS 공격은 공격자에 의해 작성된 스크립트가 다른 사용자에게 전달되는 기법이다. 다른 사용자의 웹 브라우저에서 적절한 검증 없이 실행되기 때문에 사용자의 세션을 탈취하거나 , 웹 사이트 변조 또는 악의적인 사이트로 사용자를 이동시킬 수 있다.
<TextBlock
key={content.idx}
contentEditable="true"
suppressContentEditableWarning
onInput={handleChange}
onCompositionStart={handleCompositionStart}
onCompositionEnd={handleCompositionEnd}
ref={textRef}
dangerouslySetInnerHTML={{ __html: content.context }}
onContextMenu={handleContextMenu}
/>
당시에 위 코드를 통해 HTML 코드가 포함된 context를 그대로 보여주었다.
프로젝트 당시에도 가능하며 사용하지 않는게 좋은 태그인걸 알고 있었지만(이름부터 위험하다..) 프로젝트 마감 일정에 맞추기 위해 사용하였다.
react-contenteditable 링크 : https://www.npmjs.com/package/react-contenteditable
태그 커스텀이 필요하였기 때문에
Advenced example 예시 : https://codesandbox.io/s/l91xvkox9l
를 참조하였다.
해당 코드를 참조하면
<ContentEditable
className="editable"
tagName="pre"
html={this.state.html} // innerHTML of the editable div
disabled={!this.state.editable} // use true to disable edition
onChange={this.handleChange} // handle innerHTML change
onBlur={this.sanitize}
/>
html 속성에서 innerHTML 속성을 사용하는 것을 알 수 있다.
위 예시에서는 XSS에 취약한 innerHTML 속성의 문제점을 해결하기 위해 sanitize-html 라이브러리를 사용하였다.
sanitize 란?
sanitize(소독)은 html의 input 또는 textarea 또는 기타등등의 사용자 입력정보에
와 같은 문자열을 적을시, 웹브라우저에서 문자열이 txt가 아닌 script 기술로 받아들여서 생기는 문제를 방지하는 모듈이다.
사용자가 이를 악용하여 태그들을 삽입해서 악성 스크립트로 변질시켜 실행 시킬 수 있기 때문이다.
HTML Sanitization 할 수 있는 방법은 3가지가 있는데,
sanitize-html 라이브러리 사용하기
https://www.npmjs.com/package/sanitize-html
Sanitize-html란?
허용된 태그와 속성 외에 html 태그를 허용하지 않는다. 허용되지 않는 속성이 있다면 지워진다. 기본값으로 하면 디폴트로 허용된 태그들이 존재한다. 허용하는 태그와 허용하지 않는 태그를 따로 지정할 수 있다.
HTML Sanitizer API 사용하기
:https://ui.toast.com/weekly-pick/ko_2021124
DOM Purify 라이브러리 사용하기
https://github.com/cure53/DOMPurify
DOMPurify란?
DOM 레벨에서 HTML을 sanitize 해주고 XSS 공격을 막아준다. jsdom 을 사용하면 node 와 같은 서버 레벨에서도 사용 가능하다. DOMPurify는 화이트리스트 접근 방식을 취하는데 특정한 태그와 속성, 프로토콜만 허용한다.
등의 방법이 있었다...
: 라이브러리를 사용하면 모르고 사용하는 느낌이 싫어 프로젝트에서 거의 사용하지 않았었는데,
리팩토링 이전에 contentEditable 속성을 사용하면서 사용했을때의 문제점과 에러를 고치는 과정을 직접 해봤기에 이번엔 라이브러리를 도입하여 사용하기로 하였다.
: 마찬가지로 위에 조사한 내용 이외에 작동 원리를 조사하여 프로젝트에 맞는 라이브러리 or api를 도입 할 예정이다.
프로젝트 당시에 XSS 공격 문제 때문에 고민을 많이 했었는데, 그때는 기간 내에 작동하는 프로젝트를 만드는 것이 우선순위여서 특정 태그를 파싱하여 사용하지 못하도록 임시 조취만 취했는데 이번엔 제대로 XSS 문제를 방지 할 수 있을 것이란 기대가 된다!
완성한 후에 테스트 해서 XSS 공격이 방지가 되는지 테스트 해서 포스팅을 작성하는것을 목표로 하고 있다.